From 3554b33f37f6a313c78b85a0e3c699ca80ae2976 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 21 May 2024 10:35:02 +0200 Subject: [PATCH 01/73] Cleanup unused F1AP message transmission and system information files --- CMakeLists.txt | 3 -- .../f1ap_cu_warning_message_transmission.c | 31 ------------------- .../f1ap_cu_warning_message_transmission.h | 31 ------------------- openair2/F1AP/f1ap_du_system_information.c | 31 ------------------- openair2/F1AP/f1ap_du_system_information.h | 31 ------------------- .../f1ap_du_warning_message_transmission.c | 31 ------------------- .../f1ap_du_warning_message_transmission.h | 31 ------------------- 7 files changed, 189 deletions(-) delete mode 100644 openair2/F1AP/f1ap_cu_warning_message_transmission.c delete mode 100644 openair2/F1AP/f1ap_cu_warning_message_transmission.h delete mode 100644 openair2/F1AP/f1ap_du_system_information.c delete mode 100644 openair2/F1AP/f1ap_du_system_information.h delete mode 100644 openair2/F1AP/f1ap_du_warning_message_transmission.c delete mode 100644 openair2/F1AP/f1ap_du_warning_message_transmission.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 627b87593d..034bc89fc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -435,14 +435,11 @@ add_library(f1ap ${F1AP_DIR}/f1ap_cu_rrc_message_transfer.c ${F1AP_DIR}/f1ap_cu_task.c ${F1AP_DIR}/f1ap_cu_ue_context_management.c - ${F1AP_DIR}/f1ap_cu_warning_message_transmission.c ${F1AP_DIR}/f1ap_du_interface_management.c ${F1AP_DIR}/f1ap_du_paging.c ${F1AP_DIR}/f1ap_du_rrc_message_transfer.c - ${F1AP_DIR}/f1ap_du_system_information.c ${F1AP_DIR}/f1ap_du_task.c ${F1AP_DIR}/f1ap_du_ue_context_management.c - ${F1AP_DIR}/f1ap_du_warning_message_transmission.c ${F1AP_DIR}/f1ap_encoder.c ${F1AP_DIR}/f1ap_handlers.c ${F1AP_DIR}/f1ap_itti_messaging.c) diff --git a/openair2/F1AP/f1ap_cu_warning_message_transmission.c b/openair2/F1AP/f1ap_cu_warning_message_transmission.c deleted file mode 100644 index 725bb4e1af..0000000000 --- a/openair2/F1AP/f1ap_cu_warning_message_transmission.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - */ - -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU - * \author EURECOM/NTUST - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr - * \note - * \warning - */ diff --git a/openair2/F1AP/f1ap_cu_warning_message_transmission.h b/openair2/F1AP/f1ap_cu_warning_message_transmission.h deleted file mode 100644 index b6bbedba2f..0000000000 --- a/openair2/F1AP/f1ap_cu_warning_message_transmission.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - */ - -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU - * \author EURECOM/NTUST - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr - * \note - * \warning - */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_system_information.c b/openair2/F1AP/f1ap_du_system_information.c deleted file mode 100644 index 725bb4e1af..0000000000 --- a/openair2/F1AP/f1ap_du_system_information.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - */ - -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU - * \author EURECOM/NTUST - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr - * \note - * \warning - */ diff --git a/openair2/F1AP/f1ap_du_system_information.h b/openair2/F1AP/f1ap_du_system_information.h deleted file mode 100644 index b6bbedba2f..0000000000 --- a/openair2/F1AP/f1ap_du_system_information.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - */ - -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU - * \author EURECOM/NTUST - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr - * \note - * \warning - */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_warning_message_transmission.c b/openair2/F1AP/f1ap_du_warning_message_transmission.c deleted file mode 100644 index 725bb4e1af..0000000000 --- a/openair2/F1AP/f1ap_du_warning_message_transmission.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - */ - -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU - * \author EURECOM/NTUST - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr - * \note - * \warning - */ diff --git a/openair2/F1AP/f1ap_du_warning_message_transmission.h b/openair2/F1AP/f1ap_du_warning_message_transmission.h deleted file mode 100644 index b6bbedba2f..0000000000 --- a/openair2/F1AP/f1ap_du_warning_message_transmission.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - */ - -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU - * \author EURECOM/NTUST - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr - * \note - * \warning - */ \ No newline at end of file From deb63888d9ba0b9de8820a785efe4f04be9199c7 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 27 May 2024 18:06:08 +0200 Subject: [PATCH 02/73] Cleanup of long-time unused F1AP interface management functions --- openair2/F1AP/f1ap_cu_interface_management.c | 50 +------------------ openair2/F1AP/f1ap_cu_interface_management.h | 26 ---------- openair2/F1AP/f1ap_du_interface_management.c | 51 -------------------- openair2/F1AP/f1ap_du_interface_management.h | 28 ----------- openair2/F1AP/f1ap_handlers.c | 4 +- 5 files changed, 3 insertions(+), 156 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 2e73172e2b..075d3c5671 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -35,36 +35,14 @@ #include "f1ap_itti_messaging.h" #include "f1ap_cu_interface_management.h" -int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); -} - -int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); + AssertFatal(1 == 0, "Not implemented yet\n"); } int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack) { - AssertFatal(1==0,"Not implemented yet\n"); -} - -/* - Error Indication -*/ -int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - -int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication) { - AssertFatal(1==0,"Not implemented yet\n"); + AssertFatal(1 == 0, "Not implemented yet\n"); } static uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) @@ -790,12 +768,6 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso return 0; } -int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, - f1ap_gnb_du_configuration_update_failure_t *GNBDUConfigurationUpdateFailure) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE( sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge) @@ -931,11 +903,6 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_confi return 0; } -int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, @@ -944,16 +911,3 @@ int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, LOG_I(F1AP,"Cell Configuration ok (assoc_id %d)\n",assoc_id); return(0); } - -int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, - sctp_assoc_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(0, "Not implemented yet\n"); -} - -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 11a45868e1..9d0bf4a391 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.h +++ b/openair2/F1AP/f1ap_cu_interface_management.h @@ -36,17 +36,9 @@ /* * Reset */ -int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset); int CU_handle_RESET_ACKNOWLEDGE(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(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack); -/* - * 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(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication); - /* * F1 Setup */ @@ -61,9 +53,6 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t * */ 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(sctp_assoc_t assoc_id, - f1ap_gnb_du_configuration_update_failure_t *GNBDUConfigurationUpdateFailure); - int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE( sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge); @@ -72,25 +61,10 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE( * 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, - F1AP_F1AP_PDU_t *pdu); int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -/* - * gNB-DU Resource Coordination - */ -int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, - sctp_assoc_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu); - -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_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index f560754bf3..673d37b637 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -160,30 +160,6 @@ int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack return 0; } -int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - -int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - -/* - Error Indication -*/ - -int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - -int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_cell_info_t *c) { /* 4.1.1 served cell Information */ @@ -744,19 +720,6 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du return 0; } -int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - -int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, - sctp_assoc_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) -{ - AssertFatal(1==0,"Not implemented yet\n"); -} - int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { LOG_D(F1AP, "DU_handle_gNB_CU_CONFIGURATION_UPDATE\n"); @@ -956,17 +919,3 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE( f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } - -int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id, - F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) -{ - AssertFatal(0, "Not implemented yet\n"); -} - -int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, - sctp_assoc_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) -{ - 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 f8d7eafb02..0cbf6adae2 100644 --- a/openair2/F1AP/f1ap_du_interface_management.h +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -38,14 +38,6 @@ */ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack); -int DU_send_RESET(sctp_assoc_t assoc_id, const 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(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 @@ -61,13 +53,6 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3 */ int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd); -int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); - -int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, - sctp_assoc_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu); - /* * gNB-CU Configuration Update */ @@ -79,17 +64,4 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge); - - -/* - * gNB-DU Resource Coordination - */ -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, - sctp_assoc_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu); - #endif /* F1AP_DU_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index bfaa9959dc..544e763c49 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -49,9 +49,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = { {CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */ {0, 0, 0}, /* ErrorIndication */ {CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */ - {DU_handle_gNB_CU_CONFIGURATION_UPDATE, - CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, - CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE}, /* gNBCUConfigurationUpdate */ + {DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, 0}, /* gNBCUConfigurationUpdate */ {DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0}, /* UEContextSetup */ {DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0}, /* UEContextRelease */ {DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0}, /* UEContextModification */ From bacf713299d5025bc46398301c48bb257718e624 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Apr 2024 16:35:00 +0200 Subject: [PATCH 03/73] Use char * for DU/CU IP address The previously used net_ip_address_t type is limited to some bytes, but the CU name might be longer. Use char * to allow longer DNS names. Also, this type separates IPv4/v6, which is not necessary, as it is now handled by the same C API (getaddrinfo()), since !2635. Co-authored-by: Guido Casati --- openair2/COMMON/f1ap_messages_types.h | 6 ++---- openair2/F1AP/f1ap_du_task.c | 17 ++++++++++++++--- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 12 ++++-------- openair3/SCTP/sctp_eNB_task.c | 2 +- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 3b6082e221..dc444366ea 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -83,11 +83,9 @@ #define F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET 65536 -typedef net_ip_address_t f1ap_net_ip_address_t; - typedef struct f1ap_net_config_t { - f1ap_net_ip_address_t CU_f1_ip_address; - f1ap_net_ip_address_t DU_f1c_ip_address; + char *CU_f1_ip_address; + char *DU_f1c_ip_address; char *DU_f1u_ip_address; uint16_t CUport; uint16_t DUport; diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index ff188e52df..02e23c0281 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -44,7 +44,7 @@ static instance_t du_create_gtpu_instance_to_cu(const f1ap_net_config_t *nc) { openAddr_t tmp = {0}; strncpy(tmp.originHost, nc->DU_f1u_ip_address, sizeof(tmp.originHost) - 1); - strncpy(tmp.destinationHost, nc->CU_f1_ip_address.ipv4_address, sizeof(tmp.destinationHost) - 1); + strncpy(tmp.destinationHost, nc->CU_f1_ip_address, sizeof(tmp.destinationHost) - 1); sprintf(tmp.originService, "%d", nc->DUport); sprintf(tmp.destinationService, "%d", nc->CUport); return gtpv1Init(tmp); @@ -63,9 +63,20 @@ void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *n sctp_new_association_req_p->in_streams = 2; //du_inst->sctp_in_streams; sctp_new_association_req_p->out_streams = 2; //du_inst->sctp_out_streams; // remote - memcpy(&sctp_new_association_req_p->remote_address, &nc->CU_f1_ip_address, sizeof(nc->CU_f1_ip_address)); + sctp_new_association_req_p->remote_address.ipv4 = 1; + strncpy(sctp_new_association_req_p->remote_address.ipv4_address, + nc->CU_f1_ip_address, + sizeof(sctp_new_association_req_p->remote_address.ipv4_address) - 1); // local - memcpy(&sctp_new_association_req_p->local_address, &nc->DU_f1c_ip_address, sizeof(nc->DU_f1c_ip_address)); + sctp_new_association_req_p->local_address.ipv4 = 1; + strncpy(sctp_new_association_req_p->local_address.ipv4_address, + nc->DU_f1c_ip_address, + sizeof(sctp_new_association_req_p->local_address.ipv4_address) - 1); + LOG_D(F1AP, + "Local IPv4 Address: %s, Remote IPv4 Address: %s\n", + sctp_new_association_req_p->local_address.ipv4_address, + sctp_new_association_req_p->remote_address.ipv4_address); + // du_f1ap_register_to_sctp itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 742f85c390..3fe7fcf91a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -33,20 +33,16 @@ static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const { f1ap_net_config_t nc = {0}; - nc.CU_f1_ip_address.ipv6 = 0; - nc.CU_f1_ip_address.ipv4 = 1; - strcpy(nc.CU_f1_ip_address.ipv4_address, f1_params->remote_addr); + nc.CU_f1_ip_address= strdup(f1_params->remote_addr); nc.CUport = f1_params->remote_portd; - nc.DU_f1c_ip_address.ipv6 = 0; - nc.DU_f1c_ip_address.ipv4 = 1; - strcpy(nc.DU_f1c_ip_address.ipv4_address, f1_params->my_addr); + nc.DU_f1c_ip_address = strdup(f1_params->my_addr); nc.DU_f1u_ip_address = strdup(f1u_ip_addr); nc.DUport = f1_params->my_portd; LOG_I(F1AP, "F1-C DU IPaddr %s, connect to F1-C CU %s, binding GTP to %s\n", - nc.DU_f1c_ip_address.ipv4_address, - nc.CU_f1_ip_address.ipv4_address, + nc.DU_f1c_ip_address, + nc.CU_f1_ip_address, nc.DU_f1u_ip_address); // sctp_in_streams/sctp_out_streams are given by SCTP layer diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index a6d3a11a39..530b3ea6b0 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -394,7 +394,7 @@ static void sctp_handle_new_association_req(const instance_t instance, struct addrinfo *serv; int status = getaddrinfo(local, NULL, &hints, &serv); - AssertFatal(status == 0, "getaddrinfo() failed: %s\n", gai_strerror(status)); + AssertFatal(status == 0, "getaddrinfo(%s) failed: %s\n", local, gai_strerror(status)); int sd; struct addrinfo *p = NULL; From c9da5aabff084fa77e3e6d9737d00bebe99a54c2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Apr 2024 16:43:25 +0200 Subject: [PATCH 04/73] Use primitive type for TEID teid_t is defined in platfrom_types.h, which defines a bunch of 4G-specific things. In an attempt to decouple from 4G types, do not use it. --- openair2/COMMON/f1ap_messages_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index dc444366ea..d8c832e6e5 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -344,7 +344,7 @@ typedef struct f1ap_ul_rrc_message_s { typedef struct f1ap_up_tnl_s { in_addr_t tl_address; // currently only IPv4 supported - teid_t teid; + uint32_t teid; uint16_t port; } f1ap_up_tnl_t; From 4b5ea6dcf8528e3eaf58ec774a3a81910655a01b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Apr 2024 16:56:55 +0200 Subject: [PATCH 05/73] Fix header inclusion: NGAP message types depends on S1AP --- openair2/COMMON/f1ap_messages_types.h | 1 - openair2/COMMON/ngap_messages_types.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index d8c832e6e5..e71c0eab64 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -24,7 +24,6 @@ #include #include -#include "s1ap_messages_types.h" #include "ngap_messages_types.h" //-------------------------------------------------------------------------------------------// diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 861f5e6d2c..99d9d1dc0c 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -33,6 +33,7 @@ #include "common/platform_types.h" #include "common/ngran_types.h" #include "LTE_asn_constant.h" +#include "s1ap_messages_types.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. From da6b1a4be4cb941b3eb39c4584383be79d22a06c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 28 Aug 2024 17:48:20 +0200 Subject: [PATCH 06/73] Fixes to SI message struct item in CU messages * num_SI is the size of the list of gNB-CU System Information messages * the new struct member is an array, sized after the maximum nb of SIB types, which contains the SI container, the container length and the SIB type --- openair2/COMMON/f1ap_messages_types.h | 16 +++++-- openair2/F1AP/f1ap_cu_interface_management.c | 44 ++++++++++++-------- openair2/F1AP/f1ap_du_interface_management.c | 29 +++++++------ 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index e71c0eab64..c3cc837f4c 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -81,6 +81,8 @@ #define F1AP_MAX_NO_UE_ID 1024 #define F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET 65536 +/* 9.3.1.42 of 3GPP TS 38.473 - gNB-CU System Information */ +#define F1AP_MAX_NO_SIB_TYPES 32 typedef struct f1ap_net_config_t { char *CU_f1_ip_address; @@ -176,6 +178,14 @@ typedef struct f1ap_du_register_req_t { f1ap_net_config_t net_config; } f1ap_du_register_req_t; +typedef struct f1ap_sib_msg_t { + /// RRC container with system information owned by gNB-CU + uint8_t *SI_container; + int SI_container_length; + /// SIB block type, e.g. 2 for sibType2 + int SI_type; +} f1ap_sib_msg_t; + typedef struct served_cells_to_activate_s { f1ap_plmn_t plmn; // NR Global Cell Id @@ -184,10 +194,8 @@ typedef struct served_cells_to_activate_s { uint16_t nrpci; /// num SI messages per DU cell uint8_t num_SI; - /// SI message containers (up to 21 messages per cell) - uint8_t *SI_container[21]; - int SI_container_length[21]; - int SI_type[21]; + /// gNB-CU System Information message (up to 32 messages per cell) + f1ap_sib_msg_t SI_msg[F1AP_MAX_NO_SIB_TYPES]; } served_cells_to_activate_t; typedef struct f1ap_setup_resp_s { diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 075d3c5671..afd2775863 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -322,14 +322,22 @@ int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_set // for (int sIBtype=2;sIBtype<33;sIBtype++) { //21 ? 33 ? for (int sIBtype=2; sIBtype<21; sIBtype++) { - if (f1ap_setup_resp->cells_to_activate[i].SI_container[sIBtype]!=NULL) { - AssertFatal(sIBtype < 6 || sIBtype == 9, "Illegal SI type %d\n",sIBtype); - asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); - sib_item->sIBtype = sIBtype; - OCTET_STRING_fromBuf(&sib_item->sIBmessage, - (const char *)f1ap_setup_resp->cells_to_activate[i].SI_container[sIBtype], - f1ap_setup_resp->cells_to_activate[i].SI_container_length[sIBtype]); - LOG_D(F1AP, "f1ap_setup_resp->SI_container_length[%d][%d] = %d \n", i,sIBtype,f1ap_setup_resp->cells_to_activate[i].SI_container_length[sIBtype]); + for (int n = 0; n < f1ap_setup_resp->cells_to_activate[i].num_SI; n++) { + if (f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container != NULL) { + if (f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_type > 6 + && f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_type != 9) { + asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); + sib_item->sIBtype = f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_type; + OCTET_STRING_fromBuf(&sib_item->sIBmessage, + (const char *)f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container, + f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container_length); + LOG_D(F1AP, + "f1ap_setup_resp->cells_to_activate[%d].SI_msg[%d].SI_container_length = %d \n", + i, + n, + f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container_length); + } + } } } } @@ -875,16 +883,18 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_confi //printf("\n"); // for (int sIBtype=2;sIBtype<33;sIBtype++) { //21 ? 33 ? - for (int sIBtype=2; sIBtype<21; sIBtype++) { - if (f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container[sIBtype]!=NULL) { - AssertFatal(sIBtype < 6 || sIBtype == 9, "Illegal SI type %d\n",sIBtype); + for (int j = 0; j < sizeofArray(f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_msg); j++) { + f1ap_sib_msg_t *SI_msg = &f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_msg[j]; + if (SI_msg->SI_container != NULL) { asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); - sib_item->sIBtype = sIBtype; - OCTET_STRING_fromBuf(&sib_item->sIBmessage, - (const char *)f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container[sIBtype], - f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container_length[sIBtype]); - LOG_D(F1AP, "f1ap_setup_resp->SI_container_length[%d][%d] = %d \n", i,sIBtype, - f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_container_length[sIBtype]); + sib_item->sIBtype = SI_msg->SI_type; + AssertFatal(sib_item->sIBtype < 6 || sib_item->sIBtype == 9, "Illegal SI type %ld\n", sib_item->sIBtype); + OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container, SI_msg->SI_container_length); + LOG_D(F1AP, + "f1ap_gnb_cu_configuration_update->SI_container_length[%d][sIBtype %ld] = %d \n", + i, + sib_item->sIBtype, + SI_msg->SI_container_length); } } } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 673d37b637..56cb9d0e7b 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -525,15 +525,15 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint resp.cells_to_activate[i].plmn.mnc, resp.cells_to_activate[i].nr_cellid, resp.cells_to_activate[i].num_SI); - - for (int si = 0; si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; si++) { - F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si]; - size_t size = sib_item->sIBmessage.size; - resp.cells_to_activate[i].SI_container_length[si] = size; - LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, size); - resp.cells_to_activate[i].SI_container[si] = malloc(resp.cells_to_activate[i].SI_container_length[si]); - memcpy(resp.cells_to_activate[i].SI_container[si], sib_item->sIBmessage.buf, size); - resp.cells_to_activate[i].SI_type[si]=sib_item->sIBtype; + for (int s = 0; s < resp.cells_to_activate[i].num_SI; s++) { + F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[s]; + f1ap_sib_msg_t *SI_msg = &resp.cells_to_activate[i].SI_msg[s]; + SI_msg->SI_container = calloc(sib_item->sIBmessage.size, sizeof(uint8_t)); + AssertFatal(SI_msg->SI_container != NULL, "out of memory\n"); + memcpy(SI_msg->SI_container, sib_item->sIBmessage.buf, sib_item->sIBmessage.size); + SI_msg->SI_container_length = sib_item->sIBmessage.size; + SI_msg->SI_type = sib_item->sIBtype; + LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, sib_item->sIBmessage.size); } break; @@ -816,13 +816,12 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso for (int si = 0; si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; si++) { F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si]; size_t size = sib_item->sIBmessage.size; - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container_length[si] = size; + f1ap_sib_msg_t *SI_msg = &F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].SI_msg[si]; + SI_msg->SI_container_length = size; LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, size); - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container[si] = malloc(F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container_length[si]); - memcpy((void *)F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_container[si], - (void *)sib_item->sIBmessage.buf, - size); - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].SI_type[si]=sib_item->sIBtype; + SI_msg->SI_container = malloc(SI_msg->SI_container_length); + memcpy((void *)SI_msg->SI_container, (void *)sib_item->sIBmessage.buf, size); + SI_msg->SI_type = sib_item->sIBtype; } break; From ea28b9bb5bb50568c57e9d2b0d6781460c2a8f16 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Apr 2024 17:32:56 +0200 Subject: [PATCH 07/73] F1AP: RLC mode: introduce separate type The currently used type does not cover all possibilities. While we don't encode&decode them, it might still be good to be able to express it, so introduce the new type. Co-authored-by: Guido Casati --- openair2/COMMON/f1ap_messages_types.h | 3 ++- openair2/F1AP/f1ap_cu_ue_context_management.c | 18 ++++++++----- openair2/F1AP/f1ap_du_ue_context_management.c | 26 ++++++++++++------- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- openair2/RRC/NR/rrc_gNB.c | 2 +- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index c3cc837f4c..5752cd0660 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -406,6 +406,7 @@ typedef struct f1ap_drb_information_s { uint8_t flows_to_be_setup_length; } f1ap_drb_information_t; +typedef enum f1ap_rlc_mode_t { F1AP_RLC_MODE_AM, F1AP_RLC_MODE_UM_BIDIR, F1AP_RLC_UM_UNI_UL, F1AP_RLC_UM_UNI_DL } f1ap_rlc_mode_t; typedef struct f1ap_drb_to_be_setup_s { long drb_id; f1ap_up_tnl_t up_ul_tnl[2]; @@ -413,7 +414,7 @@ typedef struct f1ap_drb_to_be_setup_s { f1ap_up_tnl_t up_dl_tnl[2]; uint8_t up_dl_tnl_length; f1ap_drb_information_t drb_info; - rlc_mode_t rlc_mode; + f1ap_rlc_mode_t rlc_mode; nssai_t nssai; } f1ap_drb_to_be_setup_t; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 8451fb7062..7e8e26564a 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -483,12 +483,15 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu /* 12.1.4 rLCMode */ /* TODO use rlc_mode from f1ap_drb_to_be_setup */ switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { - case RLC_MODE_AM: + case F1AP_RLC_MODE_AM: drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am; break; - - default: + case F1AP_RLC_MODE_UM_BIDIR: drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; + break; + default: + AssertFatal(false, "modes other than AM/UM-Bidir not supported\n"); + break; } /* OPTIONAL */ @@ -1218,12 +1221,15 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte /* 12.1.4 rLCMode */ /* TODO use rlc_mode from f1ap_drb_to_be_setup */ switch (f1ap_ue_context_modification_req->drbs_to_be_setup[i].rlc_mode) { - case RLC_MODE_AM: + case F1AP_RLC_MODE_AM: drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_am; break; - - default: + case F1AP_RLC_MODE_UM_BIDIR: drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; + break; + default: + AssertFatal(false, "modes other than AM/UM-Bidir not supported\n"); + break; } /* OPTIONAL */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 6d9771f1f4..fb3d640855 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -209,11 +209,14 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i switch (drbs_tobesetup_item_p->rLCMode) { case F1AP_RLCMode_rlc_am: - drb_p->rlc_mode = RLC_MODE_AM; + drb_p->rlc_mode = F1AP_RLC_MODE_AM; + break; + case F1AP_RLCMode_rlc_um_bidirectional: + drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR; break; - default: - drb_p->rlc_mode = RLC_MODE_TM; + LOG_W(F1AP, "unsupported RLC Mode %ld received: setting UM bidir\n", drbs_tobesetup_item_p->rLCMode); + drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR; break; } @@ -930,13 +933,16 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport; switch (drbs_tobesetupmod_item_p->rLCMode) { - case F1AP_RLCMode_rlc_am: - drb_p->rlc_mode = RLC_MODE_AM; - break; - - default: - drb_p->rlc_mode = RLC_MODE_TM; - break; + case F1AP_RLCMode_rlc_am: + drb_p->rlc_mode = F1AP_RLC_MODE_AM; + break; + case F1AP_RLCMode_rlc_um_bidirectional: + drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR; + break; + default: + LOG_W(F1AP, "unsupported RLC Mode %ld received: setting UM bidir\n", drbs_tobesetupmod_item_p->rLCMode); + drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR; + break; } if (drbs_tobesetupmod_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index bb84a4793c..52d978309a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -244,7 +244,7 @@ static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb) { - const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am; + const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == F1AP_RLC_MODE_AM ? NR_RLC_Config_PR_am : NR_RLC_Config_PR_um_Bi_Directional; long priority = 13; // hardcoded for the moment return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority); } diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2c5e45f428..1b75028013 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2189,7 +2189,7 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc, const DRB_nGRAN_setup_t *drb_config = &pduSession[p].DRBnGRanList[i]; f1ap_drb_to_be_setup_t *drb = &drbs[nb_drb]; drb->drb_id = pduSession[p].DRBnGRanList[i].id; - drb->rlc_mode = rrc->configuration.um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; + drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM; drb->up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tlAddress; drb->up_ul_tnl[0].port = rrc->eth_params_s.my_portd; drb->up_ul_tnl[0].teid = drb_config->UpParamList[0].teId; From ba208c0fc23e3bb9cc667b27dcffefb76feec88d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Apr 2024 17:08:19 +0200 Subject: [PATCH 08/73] Group 5G platform types for common 5G-specific types Co-authored-by: Guido Casati --- common/5g_platform_types.h | 34 +++++++++++++++++++ common/ngran_types.h | 1 - openair2/COMMON/e1ap_messages_types.h | 2 +- openair2/COMMON/f1ap_messages_types.h | 4 +-- openair2/COMMON/ngap_messages_types.h | 9 ++--- openair2/E1AP/e1ap.c | 6 ++-- openair2/F1AP/f1ap_cu_ue_context_management.c | 4 +-- openair2/F1AP/f1ap_du_ue_context_management.c | 8 ++--- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 4 +-- openair2/RRC/NR/rrc_gNB.c | 6 ++-- openair2/RRC/NR/rrc_gNB_NGAP.c | 10 +++--- 11 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 common/5g_platform_types.h diff --git a/common/5g_platform_types.h b/common/5g_platform_types.h new file mode 100644 index 0000000000..05fc2be28d --- /dev/null +++ b/common/5g_platform_types.h @@ -0,0 +1,34 @@ +/* + * 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 FIVEG_PLATFORM_TYPES_H__ +#define FIVEG_PLATFORM_TYPES_H__ + +#include + +typedef struct nssai_s { + uint8_t sst; + uint32_t sd; +} nssai_t; + +typedef enum { NON_DYNAMIC, DYNAMIC } fiveQI_t; + +#endif diff --git a/common/ngran_types.h b/common/ngran_types.h index 37a6ea9177..ac5af71f23 100644 --- a/common/ngran_types.h +++ b/common/ngran_types.h @@ -55,5 +55,4 @@ typedef enum { CPtype = 0, UPtype } E1_t; #define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA) #define GTPV1_U_PORT_NUMBER (2152) -typedef enum { non_dynamic, dynamic } fiveQI_type_t; #endif diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index cc48a6f9e9..f2fd64252c 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -163,7 +163,7 @@ typedef struct qos_characteristics_s { } packet_error_rate; } dynamic; }; - fiveQI_type_t qos_type; + fiveQI_t qos_type; } qos_characteristics_t; typedef struct ngran_allocation_retention_priority_s { diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 5752cd0660..7c46b5fef8 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -24,7 +24,7 @@ #include #include -#include "ngap_messages_types.h" +#include "common/5g_platform_types.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. @@ -381,7 +381,7 @@ typedef struct f1ap_qos_characteristics_s { } packet_error_rate; } dynamic; }; - fiveQI_type_t qos_type; + fiveQI_t qos_type; } f1ap_qos_characteristics_t; typedef struct f1ap_ngran_allocation_retention_priority_s { diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 99d9d1dc0c..0f1555cfdf 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -31,7 +31,7 @@ #define NGAP_MESSAGES_TYPES_H_ #include "common/platform_constants.h" #include "common/platform_types.h" -#include "common/ngran_types.h" +#include "common/5g_platform_types.h" #include "LTE_asn_constant.h" #include "s1ap_messages_types.h" //-------------------------------------------------------------------------------------------// @@ -197,16 +197,11 @@ typedef enum ngap_rrc_establishment_cause_e { NGAP_RRC_CAUSE_LAST } ngap_rrc_establishment_cause_t; -typedef struct nssai_s { - uint8_t sst; - uint32_t sd; -} nssai_t; - typedef struct pdusession_level_qos_parameter_s { uint8_t qfi; uint64_t fiveQI; uint64_t qos_priority; - fiveQI_type_t fiveQI_type; + fiveQI_t fiveQI_type; ngap_allocation_retention_priority_t allocation_retention_priority; } pdusession_level_qos_parameter_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index fda507ef4e..df359c9234 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -686,7 +686,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear ieC6_1_1_1->qoS_Flow_Identifier = k->qfi; /* QoS Characteristics */ qos_characteristics_t *qos_char_in = &k->qos_params.qos_characteristics; - if (qos_char_in->qos_type == non_dynamic) { // non Dynamic 5QI + if (qos_char_in->qos_type == NON_DYNAMIC) { // non Dynamic 5QI ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI; asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI); non_Dynamic_5QI->fiveQI = qos_char_in->non_dynamic.fiveqi; @@ -1002,12 +1002,12 @@ static void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1a qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics; if (qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { - qos_char->qos_type = non_dynamic; + qos_char->qos_type = NON_DYNAMIC; qos_char->non_dynamic.fiveqi = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI; } else { E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI; - qos_char->qos_type = dynamic; + qos_char->qos_type = DYNAMIC; qos_char->dynamic.qos_priority_level = dynamic5QI->qoSPriorityLevel; qos_char->dynamic.packet_delay_budget = dynamic5QI->packetDelayBudget; qos_char->dynamic.packet_error_rate.per_scalar = dynamic5QI->packetErrorRate.pER_Scalar; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 7e8e26564a..78e0ba02e9 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -44,7 +44,7 @@ static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t int type = drb_qos_in->qos_characteristics.qos_type; const f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics; - if (type == non_dynamic) { + if (type == NON_DYNAMIC) { asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.non_Dynamic_5QI, tmp); @@ -130,7 +130,7 @@ static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapp const f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics; int type = flow_qos_params_in->qos_characteristics.qos_type; - if (type == non_dynamic) { + if (type == NON_DYNAMIC) { QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; asn1cCalloc(QosParams->choice.non_Dynamic_5QI, tmp); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index fb3d640855..529c478ac2 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -45,13 +45,13 @@ static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1 const F1AP_QoS_Characteristics_t *dRB_QoS_Char = &asn1_qos->qoS_Characteristics; if (dRB_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { - drb_qos_char->qos_type = non_dynamic; + drb_qos_char->qos_type = NON_DYNAMIC; drb_qos_char->non_dynamic.fiveqi = dRB_QoS_Char->choice.non_Dynamic_5QI->fiveQI; drb_qos_char->non_dynamic.qos_priority_level = (dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL) ? *dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel : -1; } else { - drb_qos_char->qos_type = dynamic; + drb_qos_char->qos_type = DYNAMIC; drb_qos_char->dynamic.fiveqi = (dRB_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *dRB_QoS_Char->choice.dynamic_5QI->fiveQI : -1; drb_qos_char->dynamic.qos_priority_level = dRB_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel; @@ -84,13 +84,13 @@ static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_f const F1AP_QoS_Characteristics_t *Flow_QoS_Char = &Flow_QoS->qoS_Characteristics; if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { - flow_qos_char->qos_type = non_dynamic; + flow_qos_char->qos_type = NON_DYNAMIC; flow_qos_char->non_dynamic.fiveqi = Flow_QoS_Char->choice.non_Dynamic_5QI->fiveQI; flow_qos_char->non_dynamic.qos_priority_level = (Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL) ? *Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel : -1; } else { - flow_qos_char->qos_type = dynamic; + flow_qos_char->qos_type = DYNAMIC; flow_qos_char->dynamic.fiveqi = (Flow_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *Flow_QoS_Char->choice.dynamic_5QI->fiveQI : -1; flow_qos_char->dynamic.qos_priority_level = Flow_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 52d978309a..ff73b8b646 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -262,11 +262,11 @@ static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char { NR_QoS_config_t qos_c = {0}; switch (qos_char->qos_type) { - case dynamic: + case DYNAMIC: qos_c.priority = qos_char->dynamic.qos_priority_level; qos_c.fiveQI = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0; break; - case non_dynamic: + case NON_DYNAMIC: qos_c.fiveQI = qos_char->non_dynamic.fiveqi; qos_c.priority = get_non_dynamic_priority(qos_char->non_dynamic.fiveqi); break; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1b75028013..ffd22e6a7d 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2161,12 +2161,12 @@ static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, static f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param) { f1ap_qos_characteristics_t qos_char = {0}; - if (qos_param->fiveQI_type == dynamic) { - qos_char.qos_type = dynamic; + if (qos_param->fiveQI_type == DYNAMIC) { + qos_char.qos_type = DYNAMIC; qos_char.dynamic.fiveqi = qos_param->fiveQI; qos_char.dynamic.qos_priority_level = qos_param->qos_priority; } else { - qos_char.qos_type = non_dynamic; + qos_char.qos_type = NON_DYNAMIC; qos_char.non_dynamic.fiveqi = qos_param->fiveQI; qos_char.non_dynamic.qos_priority_level = qos_param->qos_priority; } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 1ef1f8c808..6ffb8ad88e 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -248,11 +248,11 @@ static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session) AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx); if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n"); - session->qos[qosIdx].fiveQI_type = non_dynamic; + session->qos[qosIdx].fiveQI_type = NON_DYNAMIC; session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; } else { AssertFatal(qosChar->choice.dynamic5QI, "Dynamic 5QI is NULL\n"); - session->qos[qosIdx].fiveQI_type = dynamic; + session->qos[qosIdx].fiveQI_type = DYNAMIC; session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI); } @@ -412,7 +412,7 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics; qos_flow->qfi = qos_session->qfi; qos_char->qos_type = qos_session->fiveQI_type; - if (qos_char->qos_type == dynamic) { + if (qos_char->qos_type == DYNAMIC) { qos_char->dynamic.fiveqi = qos_session->fiveQI; qos_char->dynamic.qos_priority_level = qos_session->qos_priority; } else { @@ -861,11 +861,11 @@ static void fill_qos2(NGAP_QosFlowAddOrModifyRequestList_t *qos, pdusession_t *s AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx); if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n"); - session->qos[qosIdx].fiveQI_type = non_dynamic; + session->qos[qosIdx].fiveQI_type = NON_DYNAMIC; session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; } else { AssertFatal(qosChar->choice.dynamic5QI, "Dynamic 5QI is NULL\n"); - session->qos[qosIdx].fiveQI_type = dynamic; + session->qos[qosIdx].fiveQI_type = DYNAMIC; session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI); } From ab27d02e1c63b9e7a00ad4ef1a0d95f806dc4d55 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Apr 2024 19:16:49 +0200 Subject: [PATCH 09/73] Add new F1AP msg enc&dec library Add a new target f1ap_lib that groups F1AP ASN.1 encoding&decoding for messages defined f1ap_messages_types.h. The objective is to, for each F1AP message, - add encoder&decoder (similar to what already exists, but without mandatory message sending afterwards) - eq_X() function that checks two messages for equality (to be used mostly in tests) - cp_X() function that deep-copies a message, e.g., to be used when sending ITTI messages, instead of manual copying done currently - free_X() function that frees the memory associated to a memory, to avoid memory leaks. Each message will be tested, notably that encoding&decoding as well as copying yield identical messages. The actual message encoding & decoding, tests, and their use will be done in the forthcoming commits. --- openair2/F1AP/CMakeLists.txt | 3 ++ openair2/F1AP/lib/CMakeLists.txt | 8 ++++ openair2/F1AP/lib/f1ap_lib_common.c | 41 ++++++++++++++++++++ openair2/F1AP/lib/f1ap_lib_common.h | 54 +++++++++++++++++++++++++++ openair2/F1AP/lib/f1ap_lib_extern.h | 25 +++++++++++++ openair2/F1AP/lib/f1ap_lib_includes.h | 27 ++++++++++++++ openair2/F1AP/tests/CMakeLists.txt | 6 +++ openair2/F1AP/tests/f1ap_lib_test.c | 47 +++++++++++++++++++++++ 8 files changed, 211 insertions(+) create mode 100644 openair2/F1AP/lib/CMakeLists.txt create mode 100644 openair2/F1AP/lib/f1ap_lib_common.c create mode 100644 openair2/F1AP/lib/f1ap_lib_common.h create mode 100644 openair2/F1AP/lib/f1ap_lib_extern.h create mode 100644 openair2/F1AP/lib/f1ap_lib_includes.h create mode 100644 openair2/F1AP/tests/CMakeLists.txt create mode 100644 openair2/F1AP/tests/f1ap_lib_test.c diff --git a/openair2/F1AP/CMakeLists.txt b/openair2/F1AP/CMakeLists.txt index e6490b96b0..78bc9435a2 100644 --- a/openair2/F1AP/CMakeLists.txt +++ b/openair2/F1AP/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(lib) add_subdirectory(MESSAGES) if(ENABLE_TESTS) @@ -5,4 +6,6 @@ if(ENABLE_TESTS) target_link_libraries(f1ap_ids_test UTIL HASHTABLE minimal_lib) add_dependencies(tests f1ap_ids_test) add_test(NAME F1AP_ID_test COMMAND f1ap_ids_test) + + add_subdirectory(tests) endif() diff --git a/openair2/F1AP/lib/CMakeLists.txt b/openair2/F1AP/lib/CMakeLists.txt new file mode 100644 index 0000000000..6ad2e38aaf --- /dev/null +++ b/openair2/F1AP/lib/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(f1ap_lib OBJECT + f1ap_lib_common.c +) +target_link_libraries(f1ap_lib PRIVATE asn1_f1ap) +target_include_directories(f1ap_lib PUBLIC + ${CMAKE_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/openair2/F1AP/lib/f1ap_lib_common.c b/openair2/F1AP/lib/f1ap_lib_common.c new file mode 100644 index 0000000000..09c1b83b42 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_lib_common.c @@ -0,0 +1,41 @@ +/* + * 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 "f1ap_lib_common.h" +#include "f1ap_messages_types.h" + +#include "OCTET_STRING.h" + +#include "common/utils/assertions.h" +#include "common/utils/utils.h" + +bool eq_f1ap_plmn(const f1ap_plmn_t *a, const f1ap_plmn_t *b) +{ + return a->mcc == b->mcc && a->mnc == b->mnc && a->mnc_digit_length == b->mnc_digit_length; +} + +uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) +{ + uint8_t *buf = calloc_or_fail(os->size, sizeof(*buf)); + memcpy(buf, os->buf, os->size); + *len = os->size; + return buf; +} diff --git a/openair2/F1AP/lib/f1ap_lib_common.h b/openair2/F1AP/lib/f1ap_lib_common.h new file mode 100644 index 0000000000..fa1b6246d0 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_lib_common.h @@ -0,0 +1,54 @@ +/* + * 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 F1AP_LIB_COMMON_H_ +#define F1AP_LIB_COMMON_H_ + +#include +#include +#include + +/* macro to look up IE. If mandatory and not found, macro will print + * descriptive debug message to stderr and force exit in calling function */ +#define F1AP_LIB_FIND_IE(IE_TYPE, ie, container, IE_ID, mandatory) \ + do { \ + ie = NULL; \ + for (IE_TYPE **ptr = container->protocolIEs.list.array; \ + ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if ((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (mandatory && ie == NULL) { \ + fprintf(stderr, "%s(): could not find element " #IE_ID " with type " #IE_TYPE "\n", __func__); \ + return false; \ + } \ + } while (0) + +struct f1ap_plmn_t; +bool eq_f1ap_plmn(const struct f1ap_plmn_t *a, const struct f1ap_plmn_t *b); + +struct OCTET_STRING; +uint8_t *cp_octet_string(const struct OCTET_STRING *os, int *len); + +#endif /* F1AP_LIB_COMMON_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_extern.h b/openair2/F1AP/lib/f1ap_lib_extern.h new file mode 100644 index 0000000000..88cc11d3b1 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_lib_extern.h @@ -0,0 +1,25 @@ +/* + * 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 F1AP_LIB_EXTERN_H_ +#define F1AP_LIB_EXTERN_H_ + +#endif /* F1AP_LIB_EXTERN_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_includes.h b/openair2/F1AP/lib/f1ap_lib_includes.h new file mode 100644 index 0000000000..d68189d277 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_lib_includes.h @@ -0,0 +1,27 @@ +/* + * 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 F1AP_LIB_INCLUDES_H_ +#define F1AP_LIB_INCLUDES_H_ + +#include "F1AP_F1AP-PDU.h" + +#endif /* F1AP_LIB_INCLUDES_H_ */ diff --git a/openair2/F1AP/tests/CMakeLists.txt b/openair2/F1AP/tests/CMakeLists.txt new file mode 100644 index 0000000000..a73334051a --- /dev/null +++ b/openair2/F1AP/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(f1ap_lib_test f1ap_lib_test.c) +add_dependencies(tests f1ap_lib_test) +add_test(NAME f1ap_lib_test COMMAND f1ap_lib_test) +target_link_libraries(f1ap_lib_test PRIVATE f1ap_lib) +target_link_libraries(f1ap_lib_test PRIVATE asn1_f1ap) +target_include_directories(f1ap_lib_test PRIVATE ${CMAKE_SOURCE_DIR}) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c new file mode 100644 index 0000000000..39f69b5beb --- /dev/null +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -0,0 +1,47 @@ +#include +#include +#include + +#include "common/utils/assertions.h" + +#include "f1ap_messages_types.h" +#include "F1AP_F1AP-PDU.h" + +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + printf("detected error at %s:%d:%s: %s\n", file, line, function, s); + abort(); +} + +static F1AP_F1AP_PDU_t *f1ap_encode_decode(const F1AP_F1AP_PDU_t *enc_pdu) +{ + //xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, enc_pdu); + + DevAssert(enc_pdu != NULL); + char errbuf[1024]; + size_t errlen = sizeof(errbuf); + int ret = asn_check_constraints(&asn_DEF_F1AP_F1AP_PDU, enc_pdu, errbuf, &errlen); + AssertFatal(ret == 0, "asn_check_constraints() failed: %s\n", errbuf); + + uint8_t msgbuf[16384]; + asn_enc_rval_t enc = aper_encode_to_buffer(&asn_DEF_F1AP_F1AP_PDU, NULL, enc_pdu, msgbuf, sizeof(msgbuf)); + AssertFatal(enc.encoded > 0, "aper_encode_to_buffer() failed\n"); + + F1AP_F1AP_PDU_t *dec_pdu = NULL; + asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; + asn_dec_rval_t dec = aper_decode(&st, &asn_DEF_F1AP_F1AP_PDU, (void **)&dec_pdu, msgbuf, enc.encoded, 0, 0); + AssertFatal(dec.code == RC_OK, "aper_decode() failed\n"); + + //xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, dec_pdu); + return dec_pdu; +} + +static void f1ap_msg_free(F1AP_F1AP_PDU_t *pdu) +{ + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); +} + +int main() +{ + return 0; +} From 11df3c743f2c106150ac19a39b71891cfa0bf07f Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 29 May 2024 12:25:51 +0200 Subject: [PATCH 10/73] Introduce new macros to improve debugging capabilities in F1AP library * _F1_EQ_CHECK_GENERIC can be used to check the equality of two different members of F1AP structs and return `false` if the condition is not met. When the condition fails, the macros will print a debug message to the standard error stream, including the function name, line number, and the provided format string and arguments. --- openair2/F1AP/lib/f1ap_lib_common.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_lib_common.h b/openair2/F1AP/lib/f1ap_lib_common.h index fa1b6246d0..97e4f7eac4 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.h +++ b/openair2/F1AP/lib/f1ap_lib_common.h @@ -26,6 +26,28 @@ #include #include +#ifdef ENABLE_TESTS + #define PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__) +#else + #define PRINT_ERROR(...) // Do nothing +#endif + +#define _F1_EQ_CHECK_GENERIC(condition, fmt, ...) \ + do { \ + if (!(condition)) { \ + PRINT_ERROR("F1 Equality Check failure: %s:%d: Condition '%s' failed: " fmt " != " fmt "\n", \ + __FILE__, \ + __LINE__, \ + #condition, \ + ##__VA_ARGS__); \ + return false; \ + } \ + } while (0) + +#define _F1_EQ_CHECK_LONG(A, B) _F1_EQ_CHECK_GENERIC(A == B, "%ld", A, B); +#define _F1_EQ_CHECK_INT(A, B) _F1_EQ_CHECK_GENERIC(A == B, "%d", A, B); +#define _F1_EQ_CHECK_STR(A, B) _F1_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B); + /* macro to look up IE. If mandatory and not found, macro will print * descriptive debug message to stderr and force exit in calling function */ #define F1AP_LIB_FIND_IE(IE_TYPE, ie, container, IE_ID, mandatory) \ From 648ed19544caaa0840a770b32b6f0f3a1d25fc64 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 25 Sep 2024 17:18:21 +0200 Subject: [PATCH 11/73] Use _F1_EQ_CHECK_INT in eq_f1ap_plmn --- openair2/F1AP/lib/f1ap_lib_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/F1AP/lib/f1ap_lib_common.c b/openair2/F1AP/lib/f1ap_lib_common.c index 09c1b83b42..a7d47c990f 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.c +++ b/openair2/F1AP/lib/f1ap_lib_common.c @@ -29,7 +29,10 @@ bool eq_f1ap_plmn(const f1ap_plmn_t *a, const f1ap_plmn_t *b) { - return a->mcc == b->mcc && a->mnc == b->mnc && a->mnc_digit_length == b->mnc_digit_length; + _F1_EQ_CHECK_INT(a->mcc, b->mcc); + _F1_EQ_CHECK_INT(a->mnc, b->mnc); + _F1_EQ_CHECK_INT(a->mnc_digit_length, b->mnc_digit_length); + return true; } uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) From ca6eb7bd101c8bf39d2bff6f99d57eec81ad9823 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 30 Apr 2024 10:15:13 +0200 Subject: [PATCH 12/73] Add message enc&dec for F1AP Initial UL RRC msg, and test Co-authored-by: Guido Casati --- openair2/COMMON/f1ap_messages_types.h | 1 + openair2/F1AP/lib/CMakeLists.txt | 1 + openair2/F1AP/lib/f1ap_lib_extern.h | 2 + openair2/F1AP/lib/f1ap_lib_includes.h | 4 + openair2/F1AP/lib/f1ap_rrc_message_transfer.c | 199 ++++++++++++++++++ openair2/F1AP/lib/f1ap_rrc_message_transfer.h | 36 ++++ openair2/F1AP/tests/f1ap_lib_test.c | 42 ++++ 7 files changed, 285 insertions(+) create mode 100644 openair2/F1AP/lib/f1ap_rrc_message_transfer.c create mode 100644 openair2/F1AP/lib/f1ap_rrc_message_transfer.h diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 7c46b5fef8..f34b1dfea7 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -339,6 +339,7 @@ typedef struct f1ap_initial_ul_rrc_message_s { int rrc_container_length; uint8_t *du2cu_rrc_container; int du2cu_rrc_container_length; + uint8_t transaction_id; } f1ap_initial_ul_rrc_message_t; typedef struct f1ap_ul_rrc_message_s { diff --git a/openair2/F1AP/lib/CMakeLists.txt b/openair2/F1AP/lib/CMakeLists.txt index 6ad2e38aaf..7e08cb18b1 100644 --- a/openair2/F1AP/lib/CMakeLists.txt +++ b/openair2/F1AP/lib/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(f1ap_lib OBJECT f1ap_lib_common.c + f1ap_rrc_message_transfer.c ) target_link_libraries(f1ap_lib PRIVATE asn1_f1ap) target_include_directories(f1ap_lib PUBLIC diff --git a/openair2/F1AP/lib/f1ap_lib_extern.h b/openair2/F1AP/lib/f1ap_lib_extern.h index 88cc11d3b1..f95b685540 100644 --- a/openair2/F1AP/lib/f1ap_lib_extern.h +++ b/openair2/F1AP/lib/f1ap_lib_extern.h @@ -22,4 +22,6 @@ #ifndef F1AP_LIB_EXTERN_H_ #define F1AP_LIB_EXTERN_H_ +#include "f1ap_rrc_message_transfer.h" + #endif /* F1AP_LIB_EXTERN_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_includes.h b/openair2/F1AP/lib/f1ap_lib_includes.h index d68189d277..e9ebeab266 100644 --- a/openair2/F1AP/lib/f1ap_lib_includes.h +++ b/openair2/F1AP/lib/f1ap_lib_includes.h @@ -23,5 +23,9 @@ #define F1AP_LIB_INCLUDES_H_ #include "F1AP_F1AP-PDU.h" +#include "F1AP_InitialULRRCMessageTransfer.h" +#include "F1AP_InitiatingMessage.h" +#include "F1AP_NRCellIdentity.h" +#include "F1AP_ProtocolIE-Field.h" #endif /* F1AP_LIB_INCLUDES_H_ */ diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c new file mode 100644 index 0000000000..7d9dd9c682 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c @@ -0,0 +1,199 @@ +/* + * 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 "f1ap_rrc_message_transfer.h" + +#include "f1ap_lib_common.h" +#include "f1ap_lib_includes.h" + +#include "f1ap_messages_types.h" + +#include "common/utils/assertions.h" +#include "openair3/UTILS/conversions.h" +#include "common/utils/oai_asn1.h" +#include "common/utils/utils.h" + +/* ==================================== + * F1AP Initial UL RRC Message Transfer + * ==================================== */ + +/** + * @brief Initial UL RRC Message Transfer encoding + */ +F1AP_F1AP_PDU_t *encode_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + + /* 0. Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_InitialULRRCMessageTransfer; + tmp->criticality = F1AP_Criticality_ignore; + tmp->value.present = F1AP_InitiatingMessage__value_PR_InitialULRRCMessageTransfer; + F1AP_InitialULRRCMessageTransfer_t *out = &tmp->value.choice.InitialULRRCMessageTransfer; + + /* mandatory */ + /* c1. GNB_DU_UE_F1AP_ID */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; + + /* mandatory */ + /* c2. NRCGI */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_NRCGI; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI; + MCC_MNC_TO_PLMNID(msg->plmn.mcc, msg->plmn.mnc, msg->plmn.mnc_digit_length, &ie2->value.choice.NRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(msg->nr_cellid, &ie2->value.choice.NRCGI.nRCellIdentity); + + /* mandatory */ + /* c3. C_RNTI */ // 16 + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI; + ie3->value.choice.C_RNTI = msg->crnti; + + /* mandatory */ + /* c4. RRCContainer */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); + + /* optional */ + /* c5. DUtoCURRCContainer */ + if (msg->du2cu_rrc_container != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer; + ie5->criticality = F1AP_Criticality_reject; + ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; + OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer, + (const char *)msg->du2cu_rrc_container, + msg->du2cu_rrc_container_length); + } + + /* mandatory */ + /* c6. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie6->criticality = F1AP_Criticality_ignore; + ie6->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_TransactionID; + ie6->value.choice.TransactionID = msg->transaction_id; + + return pdu; +} + +/** + * @brief Initial UL RRC Message Transfer decoding + */ +bool decode_initial_ul_rrc_message_transfer(const F1AP_F1AP_PDU_t *pdu, f1ap_initial_ul_rrc_message_t *out) +{ + DevAssert(out != NULL); + memset(out, 0, sizeof(*out)); + + F1AP_InitialULRRCMessageTransfer_t *container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer; + F1AP_InitialULRRCMessageTransferIEs_t *ie; + + F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_NRCGI, true); + PLMNID_TO_MCC_MNC(&ie->value.choice.NRCGI.pLMN_Identity, out->plmn.mcc, out->plmn.mnc, out->plmn.mnc_digit_length); + BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity, out->nr_cellid); + + F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_C_RNTI, true); + out->crnti = ie->value.choice.C_RNTI; + + F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); + out->rrc_container = cp_octet_string(&ie->value.choice.RRCContainer, &out->rrc_container_length); + + F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false); + if (ie != NULL) + out->du2cu_rrc_container = cp_octet_string(&ie->value.choice.DUtoCURRCContainer, &out->du2cu_rrc_container_length); + + F1AP_LIB_FIND_IE(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true); + out->transaction_id = ie->value.choice.TransactionID; + + return true; +} + +/** + * @brief Initial UL RRC Message Transfer deep copy + */ +f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg) +{ + uint8_t *rrc_container = calloc_or_fail(msg->rrc_container_length, sizeof(*rrc_container)); + memcpy(rrc_container, msg->rrc_container, msg->rrc_container_length); + uint8_t *du2cu_rrc_container = NULL; + if (msg->du2cu_rrc_container_length > 0) { + DevAssert(msg->du2cu_rrc_container != NULL); + du2cu_rrc_container = calloc_or_fail(msg->du2cu_rrc_container_length, sizeof(*du2cu_rrc_container)); + memcpy(du2cu_rrc_container, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); + } + f1ap_initial_ul_rrc_message_t cp = { + .gNB_DU_ue_id = msg->gNB_DU_ue_id, + .plmn = msg->plmn, + .nr_cellid = msg->nr_cellid, + .crnti = msg->crnti, + .rrc_container = rrc_container, + .rrc_container_length = msg->rrc_container_length, + .du2cu_rrc_container = du2cu_rrc_container, + .du2cu_rrc_container_length = msg->du2cu_rrc_container_length, + .transaction_id = msg->transaction_id + }; + return cp; +} + +/** + * @brief Initial UL RRC Message Transfer equality check + */ +bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b) +{ + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + if (!eq_f1ap_plmn(&a->plmn, &b->plmn)) + return false; + _F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid); + _F1_EQ_CHECK_INT(a->crnti, b->crnti); + _F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length); + _F1_EQ_CHECK_LONG(a->nr_cellid, b->nr_cellid); + if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0) + return false; + _F1_EQ_CHECK_INT(a->du2cu_rrc_container_length, b->du2cu_rrc_container_length); + if (memcmp(a->du2cu_rrc_container, b->du2cu_rrc_container, a->du2cu_rrc_container_length) != 0) + return false; + _F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id); + return true; +} + +/** + * @brief Initial UL RRC Message Transfer memory management + */ +void free_initial_ul_rrc_message_transfer(f1ap_initial_ul_rrc_message_t *msg) +{ + DevAssert(msg != NULL); + free(msg->rrc_container); + free(msg->du2cu_rrc_container); +} diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h new file mode 100644 index 0000000000..b38b98cc38 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h @@ -0,0 +1,36 @@ +/* + * 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 F1AP_RRC_MESSAGE_TRANSFER_H_ +#define F1AP_RRC_MESSAGE_TRANSFER_H_ + +#include +#include "f1ap_messages_types.h" + +struct F1AP_F1AP_PDU; + +struct F1AP_F1AP_PDU *encode_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg); +bool decode_initial_ul_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_initial_ul_rrc_message_t *out); +f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg); +bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b); +void free_initial_ul_rrc_message_transfer(f1ap_initial_ul_rrc_message_t *msg); + +#endif /* F1AP_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 39f69b5beb..896ea127e6 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -7,6 +7,8 @@ #include "f1ap_messages_types.h" #include "F1AP_F1AP-PDU.h" +#include "f1ap_lib_extern.h" + void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) { printf("detected error at %s:%d:%s: %s\n", file, line, function, s); @@ -41,7 +43,47 @@ static void f1ap_msg_free(F1AP_F1AP_PDU_t *pdu) ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); } +/** + * @brief Test Initial UL RRC Message Transfer encoding/decoding + */ +static void test_initial_ul_rrc_message_transfer(void) +{ + f1ap_plmn_t plmn = { .mcc = 208, .mnc = 95, .mnc_digit_length = 2 }; + uint8_t rrc[] = "RRC Container"; + uint8_t du2cu[] = "DU2CU Container"; + f1ap_initial_ul_rrc_message_t orig = { + .gNB_DU_ue_id = 12, + .plmn = plmn, + .nr_cellid = 135, + .crnti = 0x1234, + .rrc_container = rrc, + .rrc_container_length = sizeof(rrc), + .du2cu_rrc_container = du2cu, + .du2cu_rrc_container_length = sizeof(du2cu), + .transaction_id = 2, + }; + + F1AP_F1AP_PDU_t *f1enc = encode_initial_ul_rrc_message_transfer(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_initial_ul_rrc_message_t decoded; + bool ret = decode_initial_ul_rrc_message_transfer(f1dec, &decoded); + AssertFatal(ret, "decode_initial_ul_rrc_message_transfer(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_initial_ul_rrc_message_transfer(&orig, &decoded); + AssertFatal(ret, "eq_initial_ul_rrc_message_transfer(): decoded message doesn't match\n"); + free_initial_ul_rrc_message_transfer(&decoded); + + f1ap_initial_ul_rrc_message_t cp = cp_initial_ul_rrc_message_transfer(&orig); + ret = eq_initial_ul_rrc_message_transfer(&orig, &cp); + AssertFatal(ret, "eq_initial_ul_rrc_message_transfer(): copied message doesn't match\n"); + free_initial_ul_rrc_message_transfer(&cp); +} + int main() { + test_initial_ul_rrc_message_transfer(); return 0; } From 57ecb11d5352d8f12cc8db9dcd1f8fc670f579a6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 30 Apr 2024 13:41:09 +0200 Subject: [PATCH 13/73] Use F1AP lib Init UL RRC Msg in stack Co-authored-by: Guido Casati --- CMakeLists.txt | 5 +- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 56 ++----------- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 82 ++++--------------- openair2/F1AP/lib/f1ap_rrc_message_transfer.c | 2 +- openair2/F1AP/lib/f1ap_rrc_message_transfer.h | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 15 +--- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 16 +--- openair2/RRC/NR/rrc_gNB.c | 7 +- 8 files changed, 38 insertions(+), 147 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 034bc89fc9..e6c9abdb9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -445,7 +445,8 @@ add_library(f1ap ${F1AP_DIR}/f1ap_itti_messaging.c) target_include_directories(f1ap PUBLIC F1AP_DIR) target_link_libraries(f1ap PUBLIC asn1_f1ap L2_NR) -target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE) +target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE f1ap_lib) +target_include_directories(f1ap PRIVATE ${F1AP_DIR}/lib) # LPP ############## @@ -1435,6 +1436,8 @@ add_library(L2_NR ${GNB_APP_SRC} ) target_link_libraries(L2_NR PRIVATE ds alg) +target_link_libraries(L2_NR PRIVATE f1ap_lib) +target_include_directories(L2_NR PRIVATE ${F1AP_DIR}/lib) add_library(e1_if ${NR_RRC_DIR}/cucp_cuup_direct.c diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 8ccca9f478..020c3be50d 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -39,67 +39,25 @@ #include "openair3/UTILS/conversions.h" #include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h" +#include "f1ap_rrc_message_transfer.h" + /* Initial UL RRC Message Transfer */ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - LOG_D(F1AP, "CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER\n"); - // decode the F1 message - // get the rrc message from the contauiner - // call func rrc_eNB_decode_ccch: <-- needs some update here - MessageDef *message_p; - F1AP_InitialULRRCMessageTransfer_t *container; - F1AP_InitialULRRCMessageTransferIEs_t *ie; - DevAssert(pdu != NULL); - - if (stream != 0) { - LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n", - assoc_id, stream); + f1ap_initial_ul_rrc_message_t msg; + if (!decode_initial_ul_rrc_message_transfer(pdu, &msg)) { + LOG_E(F1AP, "cannot decode F1 initial UL RRC message Transfer\n"); return -1; } - container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer; - /* GNB_DU_UE_F1AP_ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - uint32_t du_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - - /* NRCGI - * Fixme: process NRCGI - */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_NRCGI, true); - uint64_t nr_cellid; - BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid); - /* RNTI */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_C_RNTI, true); - rnti_t rnti = ie->value.choice.C_RNTI; - F1AP_InitialULRRCMessageTransferIEs_t *rrccont; - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container, - F1AP_ProtocolIE_ID_id_RRCContainer, true); - AssertFatal(rrccont!=NULL,"RRCContainer is missing\n"); - - F1AP_InitialULRRCMessageTransferIEs_t *du2cu; - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container, - F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false); - // create an ITTI message and copy SDU - message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + MessageDef *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 - ul_rrc->crnti = rnti; - ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; - ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); - memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); - AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); - ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; - ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); - memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); + *ul_rrc = msg; /* "move" message into ITTI, RRC thread will free it */ itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); return 0; diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 4a3526dd0a..62e6c1f0e3 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -53,6 +53,8 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" +#include "f1ap_rrc_message_transfer.h" + /* DL RRC Message Transfer */ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { @@ -141,74 +143,26 @@ 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(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg) { - F1AP_F1AP_PDU_t pdu= {0}; - F1AP_InitialULRRCMessageTransfer_t *out; - uint8_t *buffer=NULL; - uint32_t len=0; + F1AP_F1AP_PDU_t *pdu = encode_initial_ul_rrc_message_transfer(msg); + /* free F1AP message after encoding */ + free_initial_ul_rrc_message_transfer(msg); - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, tmp); - tmp->procedureCode = F1AP_ProcedureCode_id_InitialULRRCMessageTransfer; - tmp->criticality = F1AP_Criticality_ignore; - tmp->value.present = F1AP_InitiatingMessage__value_PR_InitialULRRCMessageTransfer; - out = &tmp->value.choice.InitialULRRCMessageTransfer; - /* mandatory */ - /* c1. GNB_DU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; - /* mandatory */ - /* c2. NRCGI */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_NRCGI; - 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(0)->setupReq.cell[0].info); - /* mandatory */ - /* c3. C_RNTI */ // 16 - asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI; - ie3->value.choice.C_RNTI = msg->crnti; - /* mandatory */ - /* c4. RRCContainer */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); - - /* optional */ - /* c5. DUtoCURRCContainer */ - if (msg->du2cu_rrc_container != NULL) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer; - ie5->criticality = F1AP_Criticality_reject; - ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; - OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer, - (const char *)msg->du2cu_rrc_container, - msg->du2cu_rrc_container_length); - } - /* mandatory */ - /* c6. Transaction ID (integer value) */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_TransactionID; - ie6->criticality = F1AP_Criticality_ignore; - ie6->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_TransactionID; - ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0); - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode F1 INITIAL UL RRC MESSAGE TRANSFER\n"); + if (pdu == NULL) { + LOG_E(F1AP, "cannot encode F1 INITIAL UL RRC MESSAGE TRANSFER, can't send message\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } + /* encode */ + uint8_t *buffer = NULL; + uint32_t len = 0; + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 INITIAL UL RRC MESSAGE TRANSFER\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + return -1; + } + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c index 7d9dd9c682..4c4a353cee 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c @@ -191,7 +191,7 @@ bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, /** * @brief Initial UL RRC Message Transfer memory management */ -void free_initial_ul_rrc_message_transfer(f1ap_initial_ul_rrc_message_t *msg) +void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg) { DevAssert(msg != NULL); free(msg->rrc_container); diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h index b38b98cc38..30a884e8fc 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h @@ -31,6 +31,6 @@ struct F1AP_F1AP_PDU *encode_initial_ul_rrc_message_transfer(const f1ap_initial_ bool decode_initial_ul_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_initial_ul_rrc_message_t *out); f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg); bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b); -void free_initial_ul_rrc_message_transfer(f1ap_initial_ul_rrc_message_t *msg); +void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg); #endif /* F1AP_RRC_MESSAGE_TRANSFER_H_ */ 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 29a7bc8621..b06abeb5bc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -23,6 +23,7 @@ #include "intertask_interface.h" #include "mac_rrc_ul.h" +#include "f1ap_lib_extern.h" static void f1_reset_du_initiated_direct(const f1ap_reset_t *reset) { @@ -277,20 +278,8 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const { 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; - - f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length); - DevAssert(f1ap_msg->rrc_container); - memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length); - f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length; - - f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); - DevAssert(f1ap_msg->du2cu_rrc_container); - memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); - f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length; - + *f1ap_msg = cp_initial_ul_rrc_message_transfer(ul_rrc); itti_send_msg_to_task(TASK_RRC_GNB, module_id, msg); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 3fe7fcf91a..e3e46310eb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -29,6 +29,8 @@ #include "mac_rrc_ul.h" +#include "f1ap_lib_extern.h" + static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const char *f1u_ip_addr) { f1ap_net_config_t nc = {0}; @@ -265,20 +267,8 @@ static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_compl static void initial_ul_rrc_message_transfer_f1ap(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); - /* 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; - - f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length); - DevAssert(f1ap_msg->rrc_container); - memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length); - f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length; - - f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); - DevAssert(f1ap_msg->du2cu_rrc_container); - memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); - f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length; - + *f1ap_msg = cp_initial_ul_rrc_message_transfer(ul_rrc); itti_send_msg_to_task(TASK_DU_F1, module_id, msg); } diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ffd22e6a7d..53b158aac0 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -94,6 +94,7 @@ #include #include "openair2/F1AP/f1ap_common.h" #include "openair2/F1AP/f1ap_ids.h" +#include "openair2/F1AP/lib/f1ap_lib_extern.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "openair2/E1AP/e1ap.h" #include "cucp_cuup_if.h" @@ -1839,11 +1840,6 @@ void rrc_gNB_process_initial_ul_rrc_message(sctp_assoc_t assoc_id, const f1ap_in } } ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - - if (ul_rrc->rrc_container) - free(ul_rrc->rrc_container); - if (ul_rrc->du2cu_rrc_container) - free(ul_rrc->du2cu_rrc_container); } void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) @@ -2439,6 +2435,7 @@ void *rrc_gnb_task(void *args_p) { 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(msg_p->ittiMsgHeader.originInstance, &F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); + free_initial_ul_rrc_message_transfer(&F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); break; /* Messages from PDCP */ From 3374327752ac5575bb48ad81b4ae5cec6df2d80d Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 13 May 2024 15:55:00 +0200 Subject: [PATCH 14/73] Add encoding/decoding lib for F1AP DL RRC Transfer message --- openair2/F1AP/lib/f1ap_rrc_message_transfer.c | 162 ++++++++++++++++++ openair2/F1AP/lib/f1ap_rrc_message_transfer.h | 7 + 2 files changed, 169 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c index 4c4a353cee..e449d68096 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c @@ -197,3 +197,165 @@ void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *m free(msg->rrc_container); free(msg->du2cu_rrc_container); } + +/* ============================ + * F1AP DL RRC Message Transfer + * ============================ */ + +/** + * @brief DL RRC Message Transfer encoding (9.2.3.2 of 3GPP TS 38.473) + * gNB-CU → gNB-DU + */ +F1AP_F1AP_PDU_t *encode_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc(1, sizeof(*pdu)); + AssertFatal(pdu != NULL, "out of memory\n"); + + /* Create */ + /* 0. Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer; + tmp->criticality = F1AP_Criticality_ignore; + tmp->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer; + F1AP_DLRRCMessageTransfer_t *out = &tmp->value.choice.DLRRCMessageTransfer; + // gNB-CU UE F1AP ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id; + // gNB-DU UE F1AP ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; + // old gNB-DU UE F1AP ID (O) + if (msg->old_gNB_DU_ue_id) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1; + ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *msg->old_gNB_DU_ue_id; + } + // SRB ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_SRBID; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID; + ie4->value.choice.SRBID = msg->srb_id; + // Execute Duplication (O) + if (msg->execute_duplication) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_ExecuteDuplication; + ie5->criticality = F1AP_Criticality_ignore; + ie5->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication; + ie5->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true; + } + // RRC-Container (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie6->criticality = F1AP_Criticality_reject; + ie6->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie6->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); + + return pdu; +} + +/** + * @brief DL RRC Message Transfer decoding (9.2.3.2 of 3GPP TS 38.473) + * gNB-CU → gNB-DU + */ +bool decode_dl_rrc_message_transfer(const F1AP_F1AP_PDU_t *pdu, f1ap_dl_rrc_message_t *out) +{ + DevAssert(out != NULL); + memset(out, 0, sizeof(*out)); + + DevAssert(pdu != NULL); + F1AP_DLRRCMessageTransfer_t *container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer; + F1AP_DLRRCMessageTransferIEs_t *ie; + // gNB-CU UE F1AP ID (M) + F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + // gNB-DU UE F1AP ID (M) + F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + // old gNB-DU UE F1AP ID (O) + out->old_gNB_DU_ue_id = NULL; + F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false); + if (ie) { + out->old_gNB_DU_ue_id = malloc_or_fail(sizeof(*out->old_gNB_DU_ue_id)); + *out->old_gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID_1; + } + // SRB ID (M) + F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true); + out->srb_id = ie->value.choice.SRBID; + // Execute Duplication (O) + F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_ExecuteDuplication, false); + if (ie) { + out->execute_duplication = ie->value.choice.ExecuteDuplication; + } + // RRC-Container (M) + F1AP_LIB_FIND_IE(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); + out->rrc_container = cp_octet_string(&ie->value.choice.RRCContainer, &out->rrc_container_length); + + return true; +} + +/** + * @brief DL RRC Message Transfer deep copy + */ +f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg) +{ + uint8_t *rrc_container = calloc_or_fail(msg->rrc_container_length, sizeof(*rrc_container)); + memcpy(rrc_container, msg->rrc_container, msg->rrc_container_length); + + uint32_t *old_gNB_DU_ue_id = NULL; + if (msg->old_gNB_DU_ue_id) { + old_gNB_DU_ue_id = malloc_or_fail(sizeof(*old_gNB_DU_ue_id)); + *old_gNB_DU_ue_id = *(msg->old_gNB_DU_ue_id); + } + + f1ap_dl_rrc_message_t cp = { + .gNB_DU_ue_id = msg->gNB_DU_ue_id, + .gNB_CU_ue_id = msg->gNB_CU_ue_id, + .old_gNB_DU_ue_id = old_gNB_DU_ue_id, + .srb_id = msg->srb_id, + .execute_duplication = msg->execute_duplication, + .rrc_container = rrc_container, + .rrc_container_length = msg->rrc_container_length, + }; + + return cp; +} + +/** + * @brief DL RRC Message Transfer equality check + */ +bool eq_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *a, const f1ap_dl_rrc_message_t *b) +{ + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + _F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id); + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + if (!(a->old_gNB_DU_ue_id == NULL && b->old_gNB_DU_ue_id == NULL)) + _F1_EQ_CHECK_INT(*a->old_gNB_DU_ue_id, *b->old_gNB_DU_ue_id); + _F1_EQ_CHECK_INT(a->srb_id, b->srb_id); + _F1_EQ_CHECK_INT(a->execute_duplication, b->execute_duplication); + _F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length); + if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0) + return false; + return true; +} + +/** + * @brief DL RRC Message Transfer memory management + */ +void free_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg) +{ + DevAssert(msg != NULL); + free(msg->rrc_container); + free(msg->old_gNB_DU_ue_id); +} diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h index 30a884e8fc..60aae835ab 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h @@ -33,4 +33,11 @@ f1ap_initial_ul_rrc_message_t cp_initial_ul_rrc_message_transfer(const f1ap_init bool eq_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *a, const f1ap_initial_ul_rrc_message_t *b); void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *msg); +/* DL RRC Message transfer */ +struct F1AP_F1AP_PDU *encode_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg); +bool decode_dl_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_dl_rrc_message_t *out); +f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg); +bool eq_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *a, const f1ap_dl_rrc_message_t *b); +void free_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg); + #endif /* F1AP_RRC_MESSAGE_TRANSFER_H_ */ From 718269f1eb3af2b1d4886cf8aebcf6a4aa9d600f Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 13 May 2024 15:55:21 +0200 Subject: [PATCH 15/73] Add test for F1AP DL RRC Transfer enc/dec messages --- openair2/F1AP/tests/f1ap_lib_test.c | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 896ea127e6..3bd71c97b5 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -82,8 +82,48 @@ static void test_initial_ul_rrc_message_transfer(void) free_initial_ul_rrc_message_transfer(&cp); } +/** + * @brief Test DL RRC Message Transfer encoding/decoding + */ +static void test_dl_rrc_message_transfer(void) +{ + uint8_t *rrc = (uint8_t *)calloc(strlen("RRC Container") + 1, sizeof(uint8_t)); + uint32_t *old_gNB_DU_ue_id = calloc(1, sizeof(uint32_t)); + AssertFatal(rrc != NULL && old_gNB_DU_ue_id != NULL, "out of memory\n"); + memcpy((void *)rrc, "RRC Container", strlen("RRC Container") + 1); + + f1ap_dl_rrc_message_t orig = { + .gNB_DU_ue_id = 12, + .gNB_CU_ue_id = 12, + .old_gNB_DU_ue_id = old_gNB_DU_ue_id, + .srb_id = 1, + .rrc_container = rrc, + .rrc_container_length = sizeof(rrc), + }; + + F1AP_F1AP_PDU_t *f1enc = encode_dl_rrc_message_transfer(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_dl_rrc_message_t decoded = {0}; + bool ret = decode_dl_rrc_message_transfer(f1dec, &decoded); + AssertFatal(ret, "decode_initial_ul_rrc_message_transfer(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_dl_rrc_message_transfer(&orig, &decoded); + AssertFatal(ret, "eq_dl_rrc_message_transfer(): decoded message doesn't match\n"); + free_dl_rrc_message_transfer(&decoded); + + f1ap_dl_rrc_message_t cp = cp_dl_rrc_message_transfer(&orig); + ret = eq_dl_rrc_message_transfer(&orig, &cp); + AssertFatal(ret, "eq_dl_rrc_message_transfer(): copied message doesn't match\n"); + free_dl_rrc_message_transfer(&orig); + free_dl_rrc_message_transfer(&cp); +} + int main() { test_initial_ul_rrc_message_transfer(); + test_dl_rrc_message_transfer(); return 0; } From 1d0d7e7bafe457376d171ac4db241dae5c62ea6f Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:45:55 +0200 Subject: [PATCH 16/73] Use F1AP lib for DL RRC Message Transfer in stack --- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 114 +++---------------- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 85 ++------------ openair2/RRC/NR/mac_rrc_dl_f1ap.c | 14 +-- 3 files changed, 28 insertions(+), 185 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 020c3be50d..66be251d04 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -66,105 +66,27 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t /* DL RRC Message Transfer. */ -int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, 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 *msg) { - LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n"); - F1AP_F1AP_PDU_t pdu= {0}; - F1AP_DLRRCMessageTransfer_t *out; - uint8_t *buffer=NULL; - uint32_t len=0; - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, tmp); - tmp->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer; - tmp->criticality = F1AP_Criticality_ignore; - tmp->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer; - out = &tmp->value.choice.DLRRCMessageTransfer; - /* mandatory */ - /* c1. GNB_CU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; - DevAssert(f1ap_dl_rrc->gNB_CU_ue_id != 0); - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_dl_rrc->gNB_CU_ue_id; - - /* mandatory */ - /* c2. GNB_DU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; - ie2->criticality = F1AP_Criticality_reject; - ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - DevAssert(f1ap_dl_rrc->gNB_DU_ue_id != 0); - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_dl_rrc->gNB_DU_ue_id; - - /* optional */ - /* c3. oldgNB_DU_UE_F1AP_ID */ - if (f1ap_dl_rrc->old_gNB_DU_ue_id != NULL) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1; - ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *f1ap_dl_rrc->old_gNB_DU_ue_id; - } - - /* mandatory */ - /* c4. SRBID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_SRBID; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID; - ie4->value.choice.SRBID = f1ap_dl_rrc->srb_id; - - /* optional */ - /* c5. ExecuteDuplication */ - if (f1ap_dl_rrc->execute_duplication) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_ExecuteDuplication; - ie5->criticality = F1AP_Criticality_ignore; - ie5->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication; - ie5->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true; - } - - // issue in here - /* mandatory */ - /* c6. RRCContainer */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie6->criticality = F1AP_Criticality_reject; - ie6->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie6->value.choice.RRCContainer, - (const char *)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length); - - /* optional */ - /* c7. RAT_FrequencyPriorityInformation */ - /* TODO */ - if (0) { - int endc=1; - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation; - ie7->criticality = F1AP_Criticality_reject; - ie7->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation; - - if (endc==1) { - ie7->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC; - ie7->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 123L; - } else { - ie7->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN; - ie7->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L; - } - - //ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority; - //ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L; - } - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER \n"); + /* encode DL RRC Message Transfer */ + F1AP_F1AP_PDU_t *pdu = encode_dl_rrc_message_transfer(msg); + if (pdu == NULL) { + LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER: can't send message!\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } - + /* encode F1AP PDU */ + uint8_t *buffer = NULL; + uint32_t len = 0; + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 DL RRC MESSAGE TRANSFER \n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + return -1; + } + /* Free F1AP PDU */ + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + /* Send to DU */ + LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n"); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 62e6c1f0e3..74178b17c3 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -58,85 +58,16 @@ /* DL RRC Message Transfer */ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - F1AP_DLRRCMessageTransfer_t *container; - F1AP_DLRRCMessageTransferIEs_t *ie; - int executeDuplication; - //uint64_t subscriberProfileIDforRFP; - //uint64_t rAT_FrequencySelectionPriority; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer; - /* GNB_CU_UE_F1AP_ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - uint32_t cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - /* GNB_DU_UE_F1AP_ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - uint32_t du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - - /* optional */ - /* oldgNB_DU_UE_F1AP_ID */ - uint32_t *old_gNB_DU_ue_id = NULL; - uint32_t old_gNB_DU_ue_id_stack = 0; - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false); - if (ie) { - /* strange: it is not named OLD_GNB_DU_UE... */ - old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1; - old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack; + f1ap_dl_rrc_message_t msg = {0}; + if (!decode_dl_rrc_message_transfer(pdu, &msg)) { + LOG_E(F1AP, "cannot decode F1 DL RRC message Transfer\n"); + free_dl_rrc_message_transfer(&msg); + return -1; } - /* mandatory */ - /* SRBID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_SRBID, true); - uint64_t srb_id = ie->value.choice.SRBID; - LOG_D(F1AP, "srb_id %lu \n", srb_id); - - /* optional */ - /* ExecuteDuplication */ - if (0) { - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_ExecuteDuplication, true); - executeDuplication = ie->value.choice.ExecuteDuplication; - LOG_D(F1AP, "ExecuteDuplication %d \n", executeDuplication); - } - - // issue in here - /* mandatory */ - /* RRC Container */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_RRCContainer, true); - /* optional */ - /* RAT_FrequencyPriorityInformation */ - if (0) { - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true); - - switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) { - case F1AP_RAT_FrequencyPriorityInformation_PR_eNDC: - //subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP; - break; - - case F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN: - //rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority; - break; - - default: - LOG_W(F1AP, "unhandled IE RAT_FrequencyPriorityInformation.present\n"); - break; - } - } - - f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = cu_ue_f1ap_id, - .gNB_DU_ue_id = du_ue_f1ap_id, - .old_gNB_DU_ue_id = old_gNB_DU_ue_id, - .rrc_container_length = ie->value.choice.RRCContainer.size, - .rrc_container = ie->value.choice.RRCContainer.buf, - .srb_id = srb_id - }; - dl_rrc_message_transfer(&dl_rrc); + dl_rrc_message_transfer(&msg); + /* Free DL RRC Message Transfer */ + free_dl_rrc_message_transfer(&msg); return 0; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 439712ec7e..9f1b8b4b53 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -23,6 +23,7 @@ #include "mac_rrc_dl.h" #include "nr_rrc_defs.h" +#include "openair2/F1AP/lib/f1ap_rrc_message_transfer.h" static void f1_reset_cu_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) { @@ -210,18 +211,7 @@ static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rr 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) { - msg->old_gNB_DU_ue_id = malloc(sizeof(*msg->old_gNB_DU_ue_id)); - AssertFatal(msg->old_gNB_DU_ue_id != NULL, "out of memory\n"); - *msg->old_gNB_DU_ue_id = *dl_rrc->old_gNB_DU_ue_id; - } - if (dl_rrc->rrc_container) { - msg->rrc_container = malloc(dl_rrc->rrc_container_length); - AssertFatal(msg->rrc_container != NULL, "out of memory\n"); - msg->rrc_container_length = dl_rrc->rrc_container_length; - memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length); - } + *msg = cp_dl_rrc_message_transfer(dl_rrc); itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } From b85fd159b840a811f9bec243e98976ebf8d23f1b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 13 May 2024 15:19:06 +0200 Subject: [PATCH 17/73] Add encoding/decoding lib for UL RRC Message Trasfer --- openair2/F1AP/lib/f1ap_rrc_message_transfer.c | 120 +++++++++++++++++- openair2/F1AP/lib/f1ap_rrc_message_transfer.h | 7 + 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c index e449d68096..5fc9e2d622 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.c +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.c @@ -23,7 +23,6 @@ #include "f1ap_lib_common.h" #include "f1ap_lib_includes.h" - #include "f1ap_messages_types.h" #include "common/utils/assertions.h" @@ -198,6 +197,125 @@ void free_initial_ul_rrc_message_transfer(const f1ap_initial_ul_rrc_message_t *m free(msg->du2cu_rrc_container); } +/* ==================================== + * F1AP UL RRC Message Transfer + * ==================================== */ + +/** + * @brief UL RRC Message Transfer encoding (9.2.3.3 of 3GPP TS 38.473) + * gNB-DU → gNB-CU + */ +F1AP_F1AP_PDU_t *encode_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg) +{ + + F1AP_F1AP_PDU_t *pdu = calloc(1, sizeof(*pdu)); + AssertFatal(pdu != NULL, "out of memory\n"); + + /* Create */ + /* 0. Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_ULRRCMessageTransfer; + tmp->criticality = F1AP_Criticality_ignore; + tmp->value.present = F1AP_InitiatingMessage__value_PR_ULRRCMessageTransfer; + F1AP_ULRRCMessageTransfer_t *out = &tmp->value.choice.ULRRCMessageTransfer; + // gNB-CU UE F1AP ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id; + // gNB-DU UE F1AP ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; + // SRB ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_SRBID; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_SRBID; + ie3->value.choice.SRBID = msg->srb_id; + // RRC-Container (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); + + return pdu; +} + +/** + * @brief UL RRC Message Transfer decoding (9.2.3.3 of 3GPP TS 38.473) + * gNB-DU → gNB-CU + */ +bool decode_ul_rrc_message_transfer(const F1AP_F1AP_PDU_t *pdu, f1ap_ul_rrc_message_t *out) +{ + DevAssert(out != NULL); + memset(out, 0, sizeof(*out)); + DevAssert(pdu != NULL); + + F1AP_ULRRCMessageTransfer_t *container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer; + F1AP_ULRRCMessageTransferIEs_t *ie; + + // gNB-CU UE F1AP ID (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + // gNB-DU UE F1AP ID (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + // SRB ID (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true); + out->srb_id = ie->value.choice.SRBID; + // RRC-Container (M) + F1AP_LIB_FIND_IE(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); + out->rrc_container = cp_octet_string(&ie->value.choice.RRCContainer, &out->rrc_container_length); + + return true; +} + +/** + * @brief UL RRC Message Transfer deep copy + */ +f1ap_ul_rrc_message_t cp_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg) +{ + uint8_t *rrc_container = calloc_or_fail(msg->rrc_container_length, sizeof(*rrc_container)); + memcpy(rrc_container, msg->rrc_container, msg->rrc_container_length); + f1ap_ul_rrc_message_t cp = { + .gNB_DU_ue_id = msg->gNB_DU_ue_id, + .gNB_CU_ue_id = msg->gNB_CU_ue_id, + .srb_id = msg->srb_id, + .rrc_container = rrc_container, + .rrc_container_length = msg->rrc_container_length, + }; + return cp; +} + +/** + * @brief UL RRC Message Transfer equality check + */ +bool eq_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *a, const f1ap_ul_rrc_message_t *b) +{ + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + _F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id); + _F1_EQ_CHECK_INT(a->rrc_container_length, b->rrc_container_length); + _F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id); + if (memcmp(a->rrc_container, b->rrc_container, a->rrc_container_length) != 0) + return false; + return true; +} + +/** + * @brief UL RRC Message Transfer memory management + */ +void free_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg) +{ + DevAssert(msg != NULL); + free(msg->rrc_container); +} + /* ============================ * F1AP DL RRC Message Transfer * ============================ */ diff --git a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h index 60aae835ab..4e6d682f78 100644 --- a/openair2/F1AP/lib/f1ap_rrc_message_transfer.h +++ b/openair2/F1AP/lib/f1ap_rrc_message_transfer.h @@ -40,4 +40,11 @@ f1ap_dl_rrc_message_t cp_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *ms bool eq_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *a, const f1ap_dl_rrc_message_t *b); void free_dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *msg); +/* UL RRC Message transfer */ +struct F1AP_F1AP_PDU *encode_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg); +bool decode_ul_rrc_message_transfer(const struct F1AP_F1AP_PDU *pdu, f1ap_ul_rrc_message_t *out); +f1ap_ul_rrc_message_t cp_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg); +bool eq_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *a, const f1ap_ul_rrc_message_t *b); +void free_ul_rrc_message_transfer(const f1ap_ul_rrc_message_t *msg); + #endif /* F1AP_RRC_MESSAGE_TRANSFER_H_ */ From cc0ad07aa0025bb4e6a050a8b8091e8c44926569 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 13 May 2024 15:51:22 +0200 Subject: [PATCH 18/73] Add test for F1AP UL RRC Message Transfer enc/dec lib --- openair2/F1AP/tests/f1ap_lib_test.c | 37 ++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 3bd71c97b5..5974e52f7a 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -87,7 +87,7 @@ static void test_initial_ul_rrc_message_transfer(void) */ static void test_dl_rrc_message_transfer(void) { - uint8_t *rrc = (uint8_t *)calloc(strlen("RRC Container") + 1, sizeof(uint8_t)); + uint8_t *rrc = calloc(strlen("RRC Container") + 1, sizeof(uint8_t)); uint32_t *old_gNB_DU_ue_id = calloc(1, sizeof(uint32_t)); AssertFatal(rrc != NULL && old_gNB_DU_ue_id != NULL, "out of memory\n"); memcpy((void *)rrc, "RRC Container", strlen("RRC Container") + 1); @@ -121,9 +121,44 @@ static void test_dl_rrc_message_transfer(void) free_dl_rrc_message_transfer(&cp); } +/** + * @brief Test UL RRC Message Transfer encoding/decoding + */ +static void test_ul_rrc_message_transfer(void) +{ + uint8_t rrc[] = "RRC Container"; + + f1ap_ul_rrc_message_t orig = { + .gNB_DU_ue_id = 12, + .gNB_CU_ue_id = 12, + .srb_id = 1, + .rrc_container = rrc, + .rrc_container_length = sizeof(rrc), + }; + + F1AP_F1AP_PDU_t *f1enc = encode_ul_rrc_message_transfer(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_ul_rrc_message_t decoded = {0}; + bool ret = decode_ul_rrc_message_transfer(f1dec, &decoded); + AssertFatal(ret, "decode_initial_ul_rrc_message_transfer(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_ul_rrc_message_transfer(&orig, &decoded); + AssertFatal(ret, "eq_dl_rrc_message_transfer(): decoded message doesn't match\n"); + free_ul_rrc_message_transfer(&decoded); + + f1ap_ul_rrc_message_t cp = cp_ul_rrc_message_transfer(&orig); + ret = eq_ul_rrc_message_transfer(&orig, &cp); + AssertFatal(ret, "eq_dl_rrc_message_transfer(): copied message doesn't match\n"); + free_ul_rrc_message_transfer(&cp); +} + int main() { test_initial_ul_rrc_message_transfer(); test_dl_rrc_message_transfer(); + test_ul_rrc_message_transfer(); return 0; } From 1a8ed8642fef7a010ecd3d1cfe9c7f71bff1228b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:47:19 +0200 Subject: [PATCH 19/73] Use F1AP lib for UL RRC Message Trasfer in stack --- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 89 +++++++++----------- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 67 ++++----------- 2 files changed, 56 insertions(+), 100 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 66be251d04..cf85961ff5 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -96,76 +96,67 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t */ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n"); - F1AP_ULRRCMessageTransfer_t *container; - F1AP_ULRRCMessageTransferIEs_t *ie; - uint64_t cu_ue_f1ap_id; - uint64_t du_ue_f1ap_id; - uint64_t srb_id; - DevAssert(pdu != NULL); - if (stream != 0) { LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n", assoc_id, stream); return -1; } - container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer; - /* GNB_CU_UE_F1AP_ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - /* GNB_DU_UE_F1AP_ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + f1ap_ul_rrc_message_t msg = {0}; - if (!cu_exists_f1_ue_data(cu_ue_f1ap_id)) { - LOG_E(F1AP, "unknown CU UE ID %ld\n", cu_ue_f1ap_id); - return 1; + LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n"); + if (!decode_ul_rrc_message_transfer(pdu, &msg)) { + LOG_E(F1AP, "cannot decode F1 UL RRC message Transfer\n"); + free_ul_rrc_message_transfer(&msg); + return -1; + } + + if (!cu_exists_f1_ue_data(msg.gNB_CU_ue_id)) { + LOG_E(F1AP, "unknown CU UE ID %d\n", msg.gNB_CU_ue_id); + free_ul_rrc_message_transfer(&msg); + return -1; } /* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here. * For the moment, let's hope this won't become relevant; to sleep in peace, * let's put an assert to check that it is the expected DU UE ID. */ - f1_ue_data_t ue_data = cu_get_f1_ue_data(cu_ue_f1ap_id); - if (ue_data.secondary_ue != du_ue_f1ap_id) { - LOG_E(F1AP, "unexpected DU UE ID %u received, expected it to be %lu\n", ue_data.secondary_ue, du_ue_f1ap_id); - return 1; + f1_ue_data_t ue_data = cu_get_f1_ue_data(msg.gNB_CU_ue_id); + if (ue_data.secondary_ue != msg.gNB_DU_ue_id) { + LOG_E(F1AP, "unexpected DU UE ID %u received, expected it to be %u\n", ue_data.secondary_ue, msg.gNB_DU_ue_id); + free_ul_rrc_message_transfer(&msg); + return -1; } - /* mandatory */ - /* SRBID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_SRBID, true); - srb_id = ie->value.choice.SRBID; - - if (srb_id < 1 ) - LOG_E(F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id); + if (msg.srb_id < 1) + LOG_E(F1AP, "Unexpected UL RRC MESSAGE for SRB %d \n", msg.srb_id); else - LOG_D(F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id); + LOG_D(F1AP, "UL RRC MESSAGE for SRB %d in DCCH \n", msg.srb_id); + + protocol_ctxt_t ctxt = { + .instance = instance, + .module_id = instance, + .enb_flag = 1, + .eNB_index = 0, + .rntiMaybeUEid = msg.gNB_CU_ue_id, + }; + + LOG_D(F1AP, + "[UE %lx] calling pdcp_data_ind for SRB %d with size %d (DCCH) \n", + ctxt.rntiMaybeUEid, + msg.srb_id, + msg.rrc_container_length); + uint8_t *mb = malloc16(msg.rrc_container_length); + memcpy(mb, msg.rrc_container, msg.rrc_container_length); - // issue in here - /* mandatory */ - /* RRC Container */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_RRCContainer, true); - protocol_ctxt_t ctxt={0}; - ctxt.instance = instance; - ctxt.module_id = instance; - ctxt.rntiMaybeUEid = cu_ue_f1ap_id; - ctxt.enb_flag = 1; - ctxt.eNB_index = 0; - uint8_t *mb = malloc16(ie->value.choice.RRCContainer.size); - memcpy(mb, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); - LOG_D(F1AP, "Calling pdcp_data_ind for UE RNTI %lx srb_id %lu with size %ld (DCCH) \n", ctxt.rntiMaybeUEid, srb_id, ie->value.choice.RRCContainer.size); nr_pdcp_data_ind(&ctxt, 1, // srb_flag 0, // embms_flag - srb_id, - ie->value.choice.RRCContainer.size, + msg.srb_id, + msg.rrc_container_length, mb, NULL, NULL); + /* Free UL RRC Message Transfer */ + free_ul_rrc_message_transfer(&msg); return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 74178b17c3..5f150bf25c 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -100,64 +100,29 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_in 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, "size %d UE RNTI %x in SRB %d\n", msg->rrc_container_length, msg->gNB_DU_ue_id, msg->srb_id); - //for (int i = 0;i < msg->rrc_container_length; i++) - // printf("%02x ", msg->rrc_container[i]); - //printf("\n"); - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, tmp); - tmp->procedureCode = F1AP_ProcedureCode_id_ULRRCMessageTransfer; - tmp->criticality = F1AP_Criticality_ignore; - tmp->value.present = F1AP_InitiatingMessage__value_PR_ULRRCMessageTransfer; - out = &tmp->value.choice.ULRRCMessageTransfer; - /* mandatory */ - /* c1. GNB_CU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id; - /* mandatory */ - /* c2. GNB_DU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; - ie2->criticality = F1AP_Criticality_reject; - ie2->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; - /* mandatory */ - /* c3. SRBID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_SRBID; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_SRBID; - ie3->value.choice.SRBID = msg->srb_id; - // issue in here - /* mandatory */ - /* c4. RRCContainer */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, - (const char *) msg->rrc_container, - msg->rrc_container_length); - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n"); + /* encode UL RRC Message Transfer */ + F1AP_F1AP_PDU_t *pdu = encode_ul_rrc_message_transfer(msg); + if (pdu == NULL) { + LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER: cannot send message\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } - + /* encode F1AP PDU */ + uint8_t *buffer = NULL; + uint32_t len; + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + return -1; + } + /* Free F1AP PDU */ + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + /* Send to ITTI */ f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } From f278b008375d415ad4b6a6d381647581d9afe434 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 21 May 2024 22:36:49 +0200 Subject: [PATCH 20/73] Add encoding/decoding library for F1AP Setup Request (Interface Management) --- openair2/COMMON/f1ap_messages_types.h | 2 +- openair2/F1AP/f1ap_cu_interface_management.c | 2 + openair2/F1AP/lib/CMakeLists.txt | 1 + openair2/F1AP/lib/f1ap_interface_management.c | 521 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 36 ++ openair2/F1AP/lib/f1ap_lib_common.c | 75 ++- openair2/F1AP/lib/f1ap_lib_common.h | 9 + openair2/F1AP/lib/f1ap_lib_includes.h | 10 + 8 files changed, 654 insertions(+), 2 deletions(-) create mode 100644 openair2/F1AP/lib/f1ap_interface_management.c create mode 100644 openair2/F1AP/lib/f1ap_interface_management.h diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index f34b1dfea7..2224cf822f 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -190,7 +190,7 @@ typedef struct served_cells_to_activate_s { f1ap_plmn_t plmn; // NR Global Cell Id uint64_t nr_cellid; - /// NRPCI + /// NRPCI [int 0..1007] uint16_t nrpci; /// num SI messages per DU cell uint8_t num_SI; diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index afd2775863..e420ddf295 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -34,6 +34,8 @@ #include "f1ap_encoder.h" #include "f1ap_itti_messaging.h" #include "f1ap_cu_interface_management.h" +#include "f1ap_default_values.h" +#include "lib/f1ap_interface_management.h" int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { diff --git a/openair2/F1AP/lib/CMakeLists.txt b/openair2/F1AP/lib/CMakeLists.txt index 7e08cb18b1..cb8d8b9712 100644 --- a/openair2/F1AP/lib/CMakeLists.txt +++ b/openair2/F1AP/lib/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(f1ap_lib OBJECT f1ap_lib_common.c f1ap_rrc_message_transfer.c + f1ap_interface_management.c ) target_link_libraries(f1ap_lib PRIVATE asn1_f1ap) target_include_directories(f1ap_lib PUBLIC diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c new file mode 100644 index 0000000000..437fa4f36d --- /dev/null +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -0,0 +1,521 @@ +/* + * 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 + +#include "common/utils/assertions.h" +#include "openair3/UTILS/conversions.h" +#include "common/utils/oai_asn1.h" +#include "common/utils/utils.h" + +#include "f1ap_interface_management.h" +#include "f1ap_lib_common.h" +#include "f1ap_lib_includes.h" +#include "f1ap_messages_types.h" +#include "f1ap_lib_extern.h" + +static const int nrb_lut[29] = {11, 18, 24, 25, 31, 32, 38, 51, 52, 65, 66, 78, 79, 93, 106, + 107, 121, 132, 133, 135, 160, 162, 189, 216, 217, 245, 264, 270, 273}; + +static int to_NRNRB(int nrb) +{ + for (int i = 0; i < sizeofArray(nrb_lut); i++) + if (nrb_lut[i] == nrb) + return i; + AssertFatal(1 == 0, "nrb %d is not in the list of possible NRNRB\n", nrb); +} + +static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, int max_nssai) +{ + if (plmn->iE_Extensions == NULL) + return 0; + + const F1AP_ProtocolExtensionContainer_10696P34_t *p = (F1AP_ProtocolExtensionContainer_10696P34_t *)plmn->iE_Extensions; + if (p->list.count == 0) + return 0; + + const F1AP_ServedPLMNs_ItemExtIEs_t *splmn = p->list.array[0]; + DevAssert(splmn->id == F1AP_ProtocolIE_ID_id_TAISliceSupportList); + DevAssert(splmn->extensionValue.present == F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList); + const F1AP_SliceSupportList_t *ssl = &splmn->extensionValue.choice.SliceSupportList; + AssertFatal(ssl->list.count <= max_nssai, "cannot handle more than 16 slices\n"); + for (int s = 0; s < ssl->list.count; ++s) { + const F1AP_SliceSupportItem_t *sl = ssl->list.array[s]; + nssai_t *n = &nssai[s]; + OCTET_STRING_TO_INT8(&sl->sNSSAI.sST, n->sst); + n->sd = 0xffffff; + if (sl->sNSSAI.sD != NULL) + OCTET_STRING_TO_INT24(sl->sNSSAI.sD, n->sd); + } + + return ssl->list.count; +} + +/** + * @brief F1AP Setup Request memory management + */ +static void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info) +{ + if (sys_info) { + free(sys_info->mib); + free(sys_info->sib1); + free((void *)sys_info); + } + free(info->measurement_timing_config); + free(info->tac); +} + +/** + * @brief Encoding of Served Cell Information (9.3.1.10 of 3GPP TS 38.473) + */ +static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_cell_info_t *c) +{ + F1AP_Served_Cell_Information_t scell_info = {0}; + // NR CGI + MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &(scell_info.nRCGI.pLMN_Identity)); + NR_CELL_ID_TO_BIT_STRING(c->nr_cellid, &(scell_info.nRCGI.nRCellIdentity)); + // NR PCI + scell_info.nRPCI = c->nr_pci; // int 0..1007 + // 5GS TAC + if (c->tac != NULL) { + uint32_t tac = htonl(*c->tac); + asn1cCalloc(scell_info.fiveGS_TAC, netOrder); + OCTET_STRING_fromBuf(netOrder, ((char *)&tac) + 1, 3); + } + // Served PLMNs + asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item); + MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity); + // NR-Mode-Info + F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info; + if (c->mode == F1AP_MODE_FDD) { // FDD + const f1ap_fdd_info_t *fdd = &c->fdd; + nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; + asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); + /* FDD.1.1 UL NRFreqInfo ARFCN */ + fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn; + /* FDD.1.3 freqBandListNr */ + int ul_band = 1; + for (int j = 0; j < ul_band; j++) { + asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); + /* FDD.1.3.1 freqBandIndicatorNr*/ + nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band; + } + /* FDD.2.1 DL NRFreqInfo ARFCN */ + fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn; + /* FDD.2.3 freqBandListNr */ + int dl_bands = 1; + for (int j = 0; j < dl_bands; j++) { + asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); + /* FDD.2.3.1 freqBandIndicatorNr*/ + nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band; + } // for FDD : DL freq_Bands + /* FDD.3 UL Transmission Bandwidth */ + fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs; + fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb); + /* FDD.4 DL Transmission Bandwidth */ + fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs; + fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb); + } else if (c->mode == F1AP_MODE_TDD) { + const f1ap_tdd_info_t *tdd = &c->tdd; + nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD; + asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info); + /* TDD.1.1 nRFreqInfo ARFCN */ + tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn; + /* TDD.1.3 freqBandListNr */ + int bands = 1; + for (int j = 0; j < bands; j++) { + asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); + /* TDD.1.3.1 freqBandIndicatorNr*/ + nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band; + } + /* TDD.2 transmission_Bandwidth */ + tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs; + tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb); + } else { + AssertFatal(false, "unknown duplex mode %d\n", c->mode); + } + // Measurement Timing Configuration + OCTET_STRING_fromBuf(&scell_info.measurementTimingConfiguration, + (const char *)c->measurement_timing_config, + c->measurement_timing_config_len); + + return scell_info; +} + +static bool decode_served_cell_info(const F1AP_Served_Cell_Information_t *in, f1ap_served_cell_info_t *info) +{ + AssertError(in != NULL, return false, "Input message pointer is NULL"); + // 5GS TAC (O) + if (in->fiveGS_TAC) { + info->tac = malloc_or_fail(sizeof(*info->tac)); + OCTET_STRING_TO_INT24(in->fiveGS_TAC, *info->tac); + } + // NR CGI (M) + TBCD_TO_MCC_MNC(&(in->nRCGI.pLMN_Identity), info->plmn.mcc, info->plmn.mnc, info->plmn.mnc_digit_length); + // NR Cell Identity (M) + BIT_STRING_TO_NR_CELL_IDENTITY(&in->nRCGI.nRCellIdentity, info->nr_cellid); + // NR PCI (M) + info->nr_pci = in->nRPCI; + // Served PLMNs (>= 1) + AssertError(in->servedPLMNs.list.count == 1, return false, "at least and only 1 PLMN must be present"); + info->num_ssi = read_slice_info(in->servedPLMNs.list.array[0], info->nssai, 16); + // FDD Info + if (in->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_fDD) { + info->mode = F1AP_MODE_FDD; + f1ap_fdd_info_t *FDDs = &info->fdd; + F1AP_FDD_Info_t *fDD_Info = in->nR_Mode_Info.choice.fDD; + FDDs->ul_freqinfo.arfcn = fDD_Info->uL_NRFreqInfo.nRARFCN; + // Note: cannot handle more than one UL frequency band + int num_ulBands = fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count; + AssertError(num_ulBands == 1, return false, "1 FDD UL frequency band must be present, more is not supported"); + for (int f = 0; f < num_ulBands && f < 1; f++) { + F1AP_FreqBandNrItem_t *FreqItem = fDD_Info->uL_NRFreqInfo.freqBandListNr.list.array[f]; + FDDs->ul_freqinfo.band = FreqItem->freqBandIndicatorNr; + AssertError(FreqItem->supportedSULBandList.list.count == 0, return false, "cannot handle FDD SUL bands"); + } + // Note: cannot handle more than one DL frequency band + FDDs->dl_freqinfo.arfcn = fDD_Info->dL_NRFreqInfo.nRARFCN; + int num_dlBands = fDD_Info->dL_NRFreqInfo.freqBandListNr.list.count; + AssertError(num_dlBands == 1, return false, "1 FDD DL frequency band must be present, more is not supported"); + for (int dlB = 0; dlB < num_dlBands && dlB < 1; dlB++) { + F1AP_FreqBandNrItem_t *FreqItem = fDD_Info->dL_NRFreqInfo.freqBandListNr.list.array[dlB]; + FDDs->dl_freqinfo.band = FreqItem->freqBandIndicatorNr; + AssertError(FreqItem->supportedSULBandList.list.count == 0, return false, "cannot handle FDD SUL bands"); + } + FDDs->ul_tbw.scs = fDD_Info->uL_Transmission_Bandwidth.nRSCS; + FDDs->ul_tbw.nrb = nrb_lut[fDD_Info->uL_Transmission_Bandwidth.nRNRB]; + FDDs->dl_tbw.scs = fDD_Info->dL_Transmission_Bandwidth.nRSCS; + FDDs->dl_tbw.nrb = nrb_lut[fDD_Info->dL_Transmission_Bandwidth.nRNRB]; + } else if (in->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_tDD) { + info->mode = F1AP_MODE_TDD; + f1ap_tdd_info_t *TDDs = &info->tdd; + F1AP_TDD_Info_t *tDD_Info = in->nR_Mode_Info.choice.tDD; + TDDs->freqinfo.arfcn = tDD_Info->nRFreqInfo.nRARFCN; + // Handle frequency bands + int num_tddBands = tDD_Info->nRFreqInfo.freqBandListNr.list.count; + AssertError(num_tddBands == 1, return false, "1 TDD DL frequency band must be present, more is not supported"); + for (int f = 0; f < num_tddBands && f < 1; f++) { + struct F1AP_FreqBandNrItem *FreqItem = tDD_Info->nRFreqInfo.freqBandListNr.list.array[f]; + TDDs->freqinfo.band = FreqItem->freqBandIndicatorNr; + AssertError(FreqItem->supportedSULBandList.list.count == 0, return false, "cannot handle TDD SUL bands"); + } + TDDs->tbw.scs = tDD_Info->transmission_Bandwidth.nRSCS; + TDDs->tbw.nrb = nrb_lut[tDD_Info->transmission_Bandwidth.nRNRB]; + } else { + AssertError(1 == 0, return false, "unknown or missing NR Mode info %d\n", in->nR_Mode_Info.present); + } + // MeasurementConfig (M) + AssertError(in->measurementTimingConfiguration.size > 0, return false, "measurementTimingConfigurationc size is 0"); + info->measurement_timing_config = cp_octet_string(&in->measurementTimingConfiguration, &info->measurement_timing_config_len); + return true; +} + +static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_system_info_t *sys_info) +{ + if (sys_info == NULL) + return NULL; /* optional: can be NULL */ + + F1AP_GNB_DU_System_Information_t *enc_sys_info = calloc_or_fail(1, sizeof(*enc_sys_info)); + + AssertFatal(sys_info->mib != NULL, "MIB must be present in DU sys info\n"); + OCTET_STRING_fromBuf(&enc_sys_info->mIB_message, (const char *)sys_info->mib, sys_info->mib_length); + + AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n"); + OCTET_STRING_fromBuf(&enc_sys_info->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length); + + return enc_sys_info; +} + +static void decode_system_info(struct F1AP_GNB_DU_System_Information *DUsi, f1ap_gnb_du_system_info_t *sys_info) +{ + /* mib */ + sys_info->mib = calloc_or_fail(DUsi->mIB_message.size, sizeof(*sys_info->mib)); + memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size); + sys_info->mib_length = DUsi->mIB_message.size; + /* sib1 */ + sys_info->sib1 = calloc_or_fail(DUsi->sIB1_message.size, sizeof(*sys_info->sib1)); + memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); + sys_info->sib1_length = DUsi->sIB1_message.size; +} + +/* ==================================== + * F1 SETUP REQUEST + * ==================================== */ + +/** + * @brief F1 SETUP REQUEST encoding (9.2.1.4 of 3GPP TS 38.473) + * gNB-DU → gNB-CU + */ +F1AP_F1AP_PDU_t *encode_f1ap_setup_request(const f1ap_setup_req_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + + /* Create */ + /* 0. pdu Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, initMsg); + initMsg->procedureCode = F1AP_ProcedureCode_id_F1Setup; + initMsg->criticality = F1AP_Criticality_reject; + initMsg->value.present = F1AP_InitiatingMessage__value_PR_F1SetupRequest; + F1AP_F1SetupRequest_t *f1Setup = &initMsg->value.choice.F1SetupRequest; + // Transaction ID (M) + asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC1); + ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = F1AP_Criticality_reject; + ieC1->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = msg->transaction_id; + // gNB-DU ID (M) + asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC2); + ieC2->id = F1AP_ProtocolIE_ID_id_gNB_DU_ID; + ieC2->criticality = F1AP_Criticality_reject; + ieC2->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID; + asn_int642INTEGER(&ieC2->value.choice.GNB_DU_ID, msg->gNB_DU_id); + // gNB-DU Name (O) + if (msg->gNB_DU_name) { + asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC3); + ieC3->id = F1AP_ProtocolIE_ID_id_gNB_DU_Name; + ieC3->criticality = F1AP_Criticality_ignore; + ieC3->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name; + OCTET_STRING_fromBuf(&ieC3->value.choice.GNB_DU_Name, msg->gNB_DU_name, strlen(msg->gNB_DU_name)); + } + /// gNB-DU Served Cells List (0..1) + asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieCells); + ieCells->id = F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List; + ieCells->criticality = F1AP_Criticality_reject; + ieCells->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List; + for (int i = 0; i < msg->num_cells_available; i++) { + // gNB-DU Served Cells Item (M) + const f1ap_served_cell_info_t *cell = &msg->cell[i].info; + const f1ap_gnb_du_system_info_t *sys_info = msg->cell[i].sys_info; + asn1cSequenceAdd(ieCells->value.choice.GNB_DU_Served_Cells_List.list, F1AP_GNB_DU_Served_Cells_ItemIEs_t, duServedCell); + duServedCell->id = F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item; + duServedCell->criticality = F1AP_Criticality_reject; + duServedCell->value.present = F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item; + F1AP_GNB_DU_Served_Cells_Item_t *scell_item = &duServedCell->value.choice.GNB_DU_Served_Cells_Item; + scell_item->served_Cell_Information = encode_served_cell_info(cell); + scell_item->gNB_DU_System_Information = encode_system_info(sys_info); + } + // gNB-DU RRC version (M) + asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_F1SetupRequestIEs__value_PR_RRC_Version; + // RRC Version: "This IE is not used in this release." + // we put one bit for each byte in rrc_ver that is != 0 + uint8_t bits = 0; + for (int i = 0; i < sizeofArray(msg->rrc_ver); ++i) + bits |= (msg->rrc_ver[i] != 0) << i; + BIT_STRING_t *bs = &ie2->value.choice.RRC_Version.latest_RRC_Version; + bs->buf = calloc_or_fail(1, sizeof(*bs->buf)); + bs->buf[0] = bits; + bs->size = 1; + bs->bits_unused = 5; + + F1AP_ProtocolExtensionContainer_10696P228_t *p = calloc_or_fail(1, sizeof(*p)); + asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext); + rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced; + rrcv_ext->criticality = F1AP_Criticality_ignore; + rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_; + OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_; + os->size = sizeofArray(msg->rrc_ver); + os->buf = malloc_or_fail(sizeof(msg->rrc_ver)); + for (int i = 0; i < sizeofArray(msg->rrc_ver); ++i) + os->buf[i] = msg->rrc_ver[i]; + ie2->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p; + return pdu; +} + +/** + * @brief F1AP Setup Request decoding + */ +bool decode_f1ap_setup_request(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_req_t *out) +{ + /* Check presence of message type */ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage); + AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL"); + _F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_F1Setup); + _F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_F1SetupRequest); + /* Check presence of mandatory IEs */ + F1AP_F1SetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.F1SetupRequest; + F1AP_F1SetupRequestIEs_t *ie; + F1AP_LIB_FIND_IE(F1AP_F1SetupRequestIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + F1AP_LIB_FIND_IE(F1AP_F1SetupRequestIEs_t, ie, in, F1AP_ProtocolIE_ID_id_gNB_DU_ID, true); + F1AP_LIB_FIND_IE(F1AP_F1SetupRequestIEs_t, ie, in, F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + AssertError(in->protocolIEs.list.array[i] != NULL, return false, "in->protocolIEs.list.array[i] is NULL"); + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + // Transaction ID (M) + _F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupRequestIEs__value_PR_TransactionID); + AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1"); + out->transaction_id = ie->value.choice.TransactionID; + break; + case F1AP_ProtocolIE_ID_id_gNB_DU_ID: + // gNB-DU ID (M) + _F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID); + asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, &out->gNB_DU_id); + break; + case F1AP_ProtocolIE_ID_id_gNB_DU_Name: { + const F1AP_GNB_DU_Name_t *du_name = &ie->value.choice.GNB_DU_Name; + out->gNB_DU_name = calloc_or_fail(du_name->size + 1, sizeof(*out->gNB_DU_name)); + strncpy(out->gNB_DU_name, (char *)du_name->buf, du_name->size); + break; + } + case F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List: + /* GNB_DU_Served_Cells_List */ + out->num_cells_available = ie->value.choice.GNB_DU_Served_Cells_List.list.count; + AssertError(out->num_cells_available > 0, return false, "at least 1 cell must be present"); + /* Loop over gNB-DU Served Cells Items */ + for (int i = 0; i < out->num_cells_available; i++) { + F1AP_GNB_DU_Served_Cells_Item_t *served_cells_item = + &(((F1AP_GNB_DU_Served_Cells_ItemIEs_t *)ie->value.choice.GNB_DU_Served_Cells_List.list.array[i]) + ->value.choice.GNB_DU_Served_Cells_Item); + // gNB-DU System Information (O) + struct F1AP_GNB_DU_System_Information *DUsi = served_cells_item->gNB_DU_System_Information; + if (DUsi != NULL) { + // System Information + out->cell[i].sys_info = calloc_or_fail(1, sizeof(*out->cell[i].sys_info)); + f1ap_gnb_du_system_info_t *sys_info = out->cell[i].sys_info; + /* mib */ + sys_info->mib = cp_octet_string(&DUsi->mIB_message, &sys_info->mib_length); + /* sib1 */ + sys_info->sib1 = cp_octet_string(&DUsi->sIB1_message, &sys_info->sib1_length); + } + /* Served Cell Information (M) */ + if (!decode_served_cell_info(&served_cells_item->served_Cell_Information, &out->cell[i].info)) + return false; + } + break; + case F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version: + /* gNB-DU RRC version (M) */ + if (ie->value.choice.RRC_Version.iE_Extensions) { + F1AP_ProtocolExtensionContainer_10696P228_t *ext = + (F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions; + if (ext->list.count > 0) { + F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0]; + OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_; + DevAssert(os->size == sizeofArray(out->rrc_ver)); + for (int i = 0; i < os->size; ++i) + out->rrc_ver[i] = os->buf[i]; + } + } + break; + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id); + break; + } + } + return true; +} + +static void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *dest, const f1ap_served_cell_info_t *src) { + *dest = *src; + dest->mode = src->mode; + dest->tdd = src->tdd; + dest->fdd = src->fdd; + dest->plmn = src->plmn; + if (src->tac) { + dest->tac = malloc_or_fail(sizeof(*dest->tac)); + *dest->tac = *src->tac; + } + if (src->measurement_timing_config_len) { + dest->measurement_timing_config = calloc_or_fail(src->measurement_timing_config_len, sizeof(*dest->measurement_timing_config)); + memcpy(dest->measurement_timing_config, src->measurement_timing_config, src->measurement_timing_config_len); + } +} + +/** + * @brief F1AP Setup Request deep copy + */ +f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg) +{ + f1ap_setup_req_t cp = {0}; + /* gNB_DU_id */ + cp.gNB_DU_id = msg->gNB_DU_id; + /* gNB_DU_name */ + if (msg->gNB_DU_name != NULL) + cp.gNB_DU_name = strdup(msg->gNB_DU_name); + /* transaction_id */ + cp.transaction_id = msg->transaction_id; + /* num_cells_available */ + cp.num_cells_available = msg->num_cells_available; + for (int n = 0; n < msg->num_cells_available; n++) { + /* cell.info */ + f1ap_served_cell_info_t *sci = &cp.cell[n].info; + const f1ap_served_cell_info_t *msg_sci = &msg->cell[n].info; + copy_f1ap_served_cell_info(sci, msg_sci); + /* cell.sys_info */ + if (msg->cell[n].sys_info) { + f1ap_gnb_du_system_info_t *orig_sys_info = msg->cell[n].sys_info; + f1ap_gnb_du_system_info_t *copy_sys_info = calloc_or_fail(1, sizeof(*copy_sys_info)); + cp.cell[n].sys_info = copy_sys_info; + if (orig_sys_info->mib_length > 0) { + copy_sys_info->mib = calloc_or_fail(orig_sys_info->mib_length, sizeof(*copy_sys_info->mib)); + copy_sys_info->mib_length = orig_sys_info->mib_length; + memcpy(copy_sys_info->mib, orig_sys_info->mib, copy_sys_info->mib_length); + } + if (orig_sys_info->sib1_length > 0) { + copy_sys_info->sib1 = calloc_or_fail(orig_sys_info->sib1_length, sizeof(*copy_sys_info->sib1)); + copy_sys_info->sib1_length = orig_sys_info->sib1_length; + memcpy(copy_sys_info->sib1, orig_sys_info->sib1, copy_sys_info->sib1_length); + } + } + } + for (int i = 0; i < sizeofArray(msg->rrc_ver); i++) + cp.rrc_ver[i] = msg->rrc_ver[i]; + return cp; +} + +/** + * @brief F1AP Setup Request equality check + */ +bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b) +{ + _F1_EQ_CHECK_LONG(a->gNB_DU_id, b->gNB_DU_id); + _F1_EQ_CHECK_STR(a->gNB_DU_name, b->gNB_DU_name); + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + _F1_EQ_CHECK_INT(a->num_cells_available, b->num_cells_available); + for (int i = 0; i < a->num_cells_available; i++) { + if (!eq_f1ap_cell_info(&a->cell[i].info, &b->cell[i].info)) + return false; + if (!eq_f1ap_sys_info(a->cell[i].sys_info, b->cell[i].sys_info)) + return false; + } + _F1_EQ_CHECK_LONG(sizeofArray(a->rrc_ver), sizeofArray(b->rrc_ver)); + for (int i = 0; i < sizeofArray(a->rrc_ver); i++) { + _F1_EQ_CHECK_INT(a->rrc_ver[i], b->rrc_ver[i]); + } + return true; +} + +/** + * @brief F1AP Setup Request memory management + */ +void free_f1ap_setup_request(const f1ap_setup_req_t *msg) +{ + DevAssert(msg != NULL); + free(msg->gNB_DU_name); + for (int i = 0; i < msg->num_cells_available; i++) { + free_f1ap_cell(&msg->cell[i].info, msg->cell[i].sys_info); + } +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h new file mode 100644 index 0000000000..6b196b9999 --- /dev/null +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -0,0 +1,36 @@ +/* + * 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 F1AP_INTERFACE_MANAGEMENT_H_ +#define F1AP_INTERFACE_MANAGEMENT_H_ + +#include +#include "f1ap_messages_types.h" + +struct F1AP_F1AP_PDU; + +struct F1AP_F1AP_PDU *encode_f1ap_setup_request(const f1ap_setup_req_t *msg); +bool decode_f1ap_setup_request(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_req_t *out); +f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg); +bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b); +void free_f1ap_setup_request(const f1ap_setup_req_t *msg); + +#endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_common.c b/openair2/F1AP/lib/f1ap_lib_common.c index a7d47c990f..edf48f426c 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.c +++ b/openair2/F1AP/lib/f1ap_lib_common.c @@ -23,7 +23,7 @@ #include "f1ap_messages_types.h" #include "OCTET_STRING.h" - +#include "common/utils/utils.h" #include "common/utils/assertions.h" #include "common/utils/utils.h" @@ -35,6 +35,79 @@ bool eq_f1ap_plmn(const f1ap_plmn_t *a, const f1ap_plmn_t *b) return true; } +bool eq_f1ap_freq_info(const f1ap_nr_frequency_info_t *a, const f1ap_nr_frequency_info_t *b) +{ + if (a->arfcn != b->arfcn) + return false; + if (a->band != b->band) + return false; + return true; +} + +bool eq_f1ap_tx_bandwidth(const f1ap_transmission_bandwidth_t *a, const f1ap_transmission_bandwidth_t *b) +{ + if (a->nrb != b->nrb) + return false; + if (a->scs != b->scs) + return false; + return true; +} + +bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b) +{ + if (a->nr_cellid != b->nr_cellid) + return false; + if (a->nr_pci != b->nr_pci) + return false; + if (*a->tac != *b->tac) + return false; + if (a->mode != b->mode) + return false; + if (a->mode == F1AP_MODE_TDD) { + /* TDD */ + if (!eq_f1ap_tx_bandwidth(&a->tdd.tbw, &b->tdd.tbw)) + return false; + if (!eq_f1ap_freq_info(&a->tdd.freqinfo, &b->tdd.freqinfo)) + return false; + } else if (a->mode == F1AP_MODE_FDD) { + /* FDD */ + if (!eq_f1ap_tx_bandwidth(&a->fdd.dl_tbw, &b->fdd.dl_tbw)) + return false; + if (!eq_f1ap_freq_info(&a->fdd.dl_freqinfo, &b->fdd.dl_freqinfo)) + return false; + if (!eq_f1ap_tx_bandwidth(&a->fdd.ul_tbw, &b->fdd.ul_tbw)) + return false; + if (!eq_f1ap_freq_info(&a->fdd.ul_freqinfo, &b->fdd.ul_freqinfo)) + return false; + } + if (a->measurement_timing_config_len != b->measurement_timing_config_len) + return false; + if (*a->measurement_timing_config != *b->measurement_timing_config) + return false; + if (!eq_f1ap_plmn(&a->plmn, &b->plmn)) + return false; + return true; +} + +bool eq_f1ap_sys_info(const f1ap_gnb_du_system_info_t *a, const f1ap_gnb_du_system_info_t *b) +{ + /* MIB */ + if (a->mib_length != b->mib_length) + return false; + for (int i = 0; i < a->mib_length; i++) { + if (a->mib[i] != b->mib[i]) + return false; + } + /* SIB1 */ + if (a->sib1_length != b->sib1_length) + return false; + for (int i = 0; i < a->sib1_length; i++) { + if (a->sib1[i] != b->sib1[i]) + return false; + } + return true; +} + uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) { uint8_t *buf = calloc_or_fail(os->size, sizeof(*buf)); diff --git a/openair2/F1AP/lib/f1ap_lib_common.h b/openair2/F1AP/lib/f1ap_lib_common.h index 97e4f7eac4..2380a2da87 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.h +++ b/openair2/F1AP/lib/f1ap_lib_common.h @@ -25,6 +25,7 @@ #include #include #include +#include "openair3/UTILS/conversions.h" #ifdef ENABLE_TESTS #define PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__) @@ -69,6 +70,14 @@ struct f1ap_plmn_t; bool eq_f1ap_plmn(const struct f1ap_plmn_t *a, const struct f1ap_plmn_t *b); +struct f1ap_served_cell_info_t; +bool eq_f1ap_cell_info(const struct f1ap_served_cell_info_t *a, const struct f1ap_served_cell_info_t *b); +struct f1ap_gnb_du_system_info_t; +bool eq_f1ap_sys_info(const struct f1ap_gnb_du_system_info_t *a, const struct f1ap_gnb_du_system_info_t *b); +struct f1ap_nr_frequency_info_t; +bool eq_f1ap_freq_info(const struct f1ap_nr_frequency_info_t *a, const struct f1ap_nr_frequency_info_t *b); +struct f1ap_transmission_bandwidth_t; +bool eq_f1ap_tx_bandwidth(const struct f1ap_transmission_bandwidth_t *a, const struct f1ap_transmission_bandwidth_t *b); struct OCTET_STRING; uint8_t *cp_octet_string(const struct OCTET_STRING *os, int *len); diff --git a/openair2/F1AP/lib/f1ap_lib_includes.h b/openair2/F1AP/lib/f1ap_lib_includes.h index e9ebeab266..0e5ace104d 100644 --- a/openair2/F1AP/lib/f1ap_lib_includes.h +++ b/openair2/F1AP/lib/f1ap_lib_includes.h @@ -27,5 +27,15 @@ #include "F1AP_InitiatingMessage.h" #include "F1AP_NRCellIdentity.h" #include "F1AP_ProtocolIE-Field.h" +#include "F1AP_ServedPLMNs-Item.h" +#include "F1AP_ProtocolExtensionContainer.h" +#include "F1AP_ProtocolExtensionField.h" +#include "F1AP_ProtocolIE-Field.h" +#include "F1AP_SliceSupportItem.h" +#include "F1AP_NR-Mode-Info.h" +#include "F1AP_GNB-DU-System-Information.h" +#include "F1AP_FDD-Info.h" +#include "F1AP_TDD-Info.h" +#include "F1AP_FreqBandNrItem.h" #endif /* F1AP_LIB_INCLUDES_H_ */ From c433f4de156f65851f1b3f3ff62e904b3ccd415d Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:50:50 +0200 Subject: [PATCH 21/73] Add test for F1 Setup Request enc/dec lib --- openair2/F1AP/tests/f1ap_lib_test.c | 117 ++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 5974e52f7a..005ebe5bb8 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -8,6 +8,7 @@ #include "F1AP_F1AP-PDU.h" #include "f1ap_lib_extern.h" +#include "lib/f1ap_interface_management.h" void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) { @@ -155,10 +156,126 @@ static void test_ul_rrc_message_transfer(void) free_ul_rrc_message_transfer(&cp); } +/** + * @brief Test F1AP Setup Request Encoding/Decoding + */ +static void test_f1ap_setup_request(void) +{ + /* allocate memory */ + /* gNB_DU_name */ + uint8_t *gNB_DU_name = calloc(strlen("OAI DU") + 1, sizeof(uint8_t)); + AssertFatal(gNB_DU_name != NULL, "out of memory\n"); + memcpy((void *)gNB_DU_name, "OAI DU", strlen("OAI DU") + 1); + /* sys_info */ + uint8_t *mib = calloc(3, sizeof(uint8_t)); + uint8_t *sib1 = calloc(3, sizeof(uint8_t)); + f1ap_gnb_du_system_info_t sys_info = { + .mib_length = 3, + .mib = mib, + .sib1_length = 3, + .sib1 = sib1, + }; + /* measurement_timing_information */ + int measurement_timing_config_len = strlen("0") + 1; + uint8_t *measurement_timing_information = calloc(measurement_timing_config_len, sizeof(uint8_t)); + AssertFatal(measurement_timing_information != NULL, "out of memory\n"); + memcpy((void *)measurement_timing_information, "0", measurement_timing_config_len); + /* TAC */ + uint32_t *tac = calloc(1, sizeof(uint32_t)); + /* + * TDD test + */ + // Served Cell Info + f1ap_served_cell_info_t info = { + .mode = F1AP_MODE_TDD, + .tdd.freqinfo.arfcn = 640000, + .tdd.freqinfo.band = 78, + .tdd.tbw.nrb = 66, + .tdd.tbw.scs = 1, + .measurement_timing_config_len = measurement_timing_config_len, + .measurement_timing_config = measurement_timing_information, + .nr_cellid = 123456, + .plmn.mcc = 1, + .plmn.mnc = 1, + .plmn.mnc_digit_length = 3, + .num_ssi = 1, + .nssai[0].sst = 1, + .nssai[0].sd = 1, + .tac = tac, + }; + // create message + f1ap_setup_req_t orig = { + .gNB_DU_id = 1, + .gNB_DU_name = (char *)gNB_DU_name, + .num_cells_available = 1, + .transaction_id = 2, + .rrc_ver[0] = 12, + .rrc_ver[1] = 34, + .rrc_ver[2] = 56, + .cell[0].info = info, + }; + orig.cell[0].sys_info = calloc(1, sizeof(*orig.cell[0].sys_info)); + *orig.cell[0].sys_info = sys_info; + // encode + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_request(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + // decode + f1ap_setup_req_t decoded = {0}; + bool ret = decode_f1ap_setup_request(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n"); + f1ap_msg_free(f1dec); + // equality check + ret = eq_f1ap_setup_request(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n"); + free_f1ap_setup_request(&decoded); + // deep copy + f1ap_setup_req_t cp = cp_f1ap_setup_request(&orig); + ret = eq_f1ap_setup_request(&orig, &cp); + AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n"); + free_f1ap_setup_request(&cp); + /* + * FDD test + */ + info.mode = F1AP_MODE_FDD; + info.tdd.freqinfo.arfcn = 0; + info.tdd.freqinfo.band = 0; + info.tdd.tbw.nrb = 0; + info.tdd.tbw.scs = 0; + info.fdd.ul_freqinfo.arfcn = 640000; + info.fdd.ul_freqinfo.band = 78; + info.fdd.dl_freqinfo.arfcn = 641000; + info.fdd.dl_freqinfo.band = 78; + info.fdd.ul_tbw.nrb = 66; + info.fdd.ul_tbw.scs = 1; + info.fdd.dl_tbw.nrb = 66; + info.fdd.dl_tbw.scs = 1; + // encode + f1enc = encode_f1ap_setup_request(&orig); + f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + // decode + ret = decode_f1ap_setup_request(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n"); + f1ap_msg_free(f1dec); + // equality check + ret = eq_f1ap_setup_request(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n"); + free_f1ap_setup_request(&decoded); + // copy + cp = cp_f1ap_setup_request(&orig); + ret = eq_f1ap_setup_request(&orig, &cp); + AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n"); + free_f1ap_setup_request(&cp); + // free original message + free_f1ap_setup_request(&orig); +} + int main() { test_initial_ul_rrc_message_transfer(); test_dl_rrc_message_transfer(); test_ul_rrc_message_transfer(); + test_f1ap_setup_request(); return 0; } From 1d8e896567fe2ea6811b5499b4c9e6cc71feacac Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:49:53 +0200 Subject: [PATCH 22/73] Use F1AP lib for F1 Setup Request in stack --- openair2/F1AP/f1ap_cu_interface_management.c | 171 ++---------------- openair2/F1AP/f1ap_du_interface_management.c | 107 ++--------- openair2/F1AP/f1ap_du_task.c | 2 + .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 44 +---- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 46 +---- openair2/RRC/NR/rrc_gNB_du.c | 7 +- 6 files changed, 38 insertions(+), 339 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index e420ddf295..2685325d6e 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -36,6 +36,7 @@ #include "f1ap_cu_interface_management.h" #include "f1ap_default_values.h" #include "lib/f1ap_interface_management.h" +#include "lib/f1ap_lib_common.h" int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { @@ -47,15 +48,6 @@ int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack AssertFatal(1 == 0, "Not implemented yet\n"); } -static uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) -{ - uint8_t *buf = calloc(os->size, sizeof(*buf)); - AssertFatal(buf != NULL, "out of memory\n"); - memcpy(buf, os->buf, os->size); - *len = os->size; - return buf; -} - static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, int max_nssai) { if (plmn->iE_Extensions == NULL) @@ -82,168 +74,31 @@ static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, return ssl->list.count; } -/* - F1 Setup -*/ +/** + * @brief F1AP Setup Request decoding (9.2.1.4 of 3GPP TS 38.473) and transfer to RRC + */ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { LOG_D(F1AP, "CU_handle_F1_SETUP_REQUEST\n"); - F1AP_F1SetupRequest_t *container; - F1AP_F1SetupRequestIEs_t *ie; - int i = 0; DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage->value.choice.F1SetupRequest; - /* F1 Setup Request == Non UE-related procedure -> stream 0 */ if (stream != 0) { LOG_W(F1AP, "[SCTP %d] Received f1 setup request on stream != 0 (%d)\n", assoc_id, stream); } - + f1ap_setup_req_t msg = {0}; + /* Decode */ + if (!decode_f1ap_setup_request(pdu, &msg)) { + LOG_E(F1AP, "cannot decode F1AP Setup Request\n"); + free_f1ap_setup_request(&msg); + return -1; + } + /* Send to RRC (ITTI) */ MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_SETUP_REQ); message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_req_t *req = &F1AP_SETUP_REQ(message_p); - - /* Transaction ID*/ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true); - req->transaction_id = ie->value.choice.TransactionID; - LOG_D(F1AP, "req->transaction_id %lu \n", req->transaction_id); - - /* gNB_DU_id */ - // this function exits if the ie is mandatory - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_DU_ID, true); - asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, &req->gNB_DU_id); - LOG_D(F1AP, "req->gNB_DU_id %lu \n", req->gNB_DU_id); - /* gNB_DU_name */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_Name, false); - req->gNB_DU_name = NULL; - if (ie != NULL) { - req->gNB_DU_name = calloc(ie->value.choice.GNB_DU_Name.size + 1, sizeof(char)); - memcpy(req->gNB_DU_name, ie->value.choice.GNB_DU_Name.buf, ie->value.choice.GNB_DU_Name.size); - LOG_D(F1AP, "req->gNB_DU_name %s \n", req->gNB_DU_name); - } - /* GNB_DU_Served_Cells_List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List, true); - req->num_cells_available = ie->value.choice.GNB_DU_Served_Cells_List.list.count; - LOG_D(F1AP, "req->num_cells_available %d \n", req->num_cells_available); - - for (i=0; inum_cells_available; i++) { - F1AP_GNB_DU_Served_Cells_Item_t *served_cells_item = &(((F1AP_GNB_DU_Served_Cells_ItemIEs_t *) - ie->value.choice.GNB_DU_Served_Cells_List.list.array[i])-> - value.choice.GNB_DU_Served_Cells_Item); - F1AP_Served_Cell_Information_t *servedCellInformation= &served_cells_item->served_Cell_Information; - /* tac */ - if (servedCellInformation->fiveGS_TAC) { - req->cell[i].info.tac = malloc(sizeof(*req->cell[i].info.tac)); - AssertFatal(req->cell[i].info.tac != NULL, "out of memory\n"); - OCTET_STRING_TO_INT24(servedCellInformation->fiveGS_TAC, *req->cell[i].info.tac); - LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell[i].info.tac); - } - - /* - nRCGI */ - TBCD_TO_MCC_MNC(&(servedCellInformation->nRCGI.pLMN_Identity), - req->cell[i].info.plmn.mcc, - req->cell[i].info.plmn.mnc, - req->cell[i].info.plmn.mnc_digit_length); - // NR cellID - BIT_STRING_TO_NR_CELL_IDENTITY(&servedCellInformation->nRCGI.nRCellIdentity, - req->cell[i].info.nr_cellid); - LOG_D(F1AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id, - req->cell[i].info.plmn.mcc, - req->cell[i].info.plmn.mnc, - (long long unsigned int)req->cell[i].info.nr_cellid); - /* - nRPCI */ - req->cell[i].info.nr_pci = servedCellInformation->nRPCI; - LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell[i].info.nr_pci); - - AssertFatal(servedCellInformation->servedPLMNs.list.count == 1, "only one PLMN handled\n"); - req->cell[i].info.num_ssi = read_slice_info(servedCellInformation->servedPLMNs.list.array[0], req->cell[i].info.nssai, 16); - - // FDD Cells - if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_fDD) { - req->cell[i].info.mode = F1AP_MODE_FDD; - f1ap_fdd_info_t *FDDs = &req->cell[i].info.fdd; - F1AP_FDD_Info_t * fDD_Info=servedCellInformation->nR_Mode_Info.choice.fDD; - FDDs->ul_freqinfo.arfcn = fDD_Info->uL_NRFreqInfo.nRARFCN; - AssertFatal(fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n"); - for (int f=0; f < fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count; f++) { - F1AP_FreqBandNrItem_t * FreqItem=fDD_Info->uL_NRFreqInfo.freqBandListNr.list.array[f]; - FDDs->ul_freqinfo.band = FreqItem->freqBandIndicatorNr; - AssertFatal(FreqItem->supportedSULBandList.list.count == 0, "cannot handle SUL bands!\n"); - } - FDDs->dl_freqinfo.arfcn = fDD_Info->dL_NRFreqInfo.nRARFCN; - int dlBands=fDD_Info->dL_NRFreqInfo.freqBandListNr.list.count; - AssertFatal(dlBands == 1, "cannot handled more than one frequency band\n"); - for (int dlB=0; dlB < dlBands; dlB++) { - F1AP_FreqBandNrItem_t * FreqItem=fDD_Info->dL_NRFreqInfo.freqBandListNr.list.array[dlB]; - FDDs->dl_freqinfo.band = FreqItem->freqBandIndicatorNr; - int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count; - AssertFatal(num_available_supported_SULBands == 0, "cannot handle SUL bands!\n"); - } - FDDs->ul_tbw.scs = fDD_Info->uL_Transmission_Bandwidth.nRSCS; - FDDs->ul_tbw.nrb = nrb_lut[fDD_Info->uL_Transmission_Bandwidth.nRNRB]; - FDDs->dl_tbw.scs = fDD_Info->dL_Transmission_Bandwidth.nRSCS; - FDDs->dl_tbw.nrb = nrb_lut[fDD_Info->dL_Transmission_Bandwidth.nRNRB]; - } else if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_tDD) { - req->cell[i].info.mode = F1AP_MODE_TDD; - f1ap_tdd_info_t *TDDs = &req->cell[i].info.tdd; - F1AP_TDD_Info_t *tDD_Info = servedCellInformation->nR_Mode_Info.choice.tDD; - TDDs->freqinfo.arfcn = tDD_Info->nRFreqInfo.nRARFCN; - AssertFatal(tDD_Info->nRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n"); - for (int f=0; f < tDD_Info->nRFreqInfo.freqBandListNr.list.count; f++) { - struct F1AP_FreqBandNrItem * FreqItem=tDD_Info->nRFreqInfo.freqBandListNr.list.array[f]; - TDDs->freqinfo.band = FreqItem->freqBandIndicatorNr; - int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count; - AssertFatal(num_available_supported_SULBands == 0, "cannot hanlde SUL bands!\n"); - } - TDDs->tbw.scs = tDD_Info->transmission_Bandwidth.nRSCS; - TDDs->tbw.nrb = nrb_lut[tDD_Info->transmission_Bandwidth.nRNRB]; - } else { - AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present); - } - - /* MeasurementConfig */ - if (servedCellInformation->measurementTimingConfiguration.size > 0) - req->cell[i].info.measurement_timing_config = - cp_octet_string(&servedCellInformation->measurementTimingConfiguration, &req->cell[i].info.measurement_timing_config_len); - - struct F1AP_GNB_DU_System_Information * DUsi=served_cells_item->gNB_DU_System_Information; - if (DUsi != NULL) { - // System Information - req->cell[i].sys_info = calloc(1, sizeof(*req->cell[i].sys_info)); - AssertFatal(req->cell[i].sys_info != NULL, "out of memory\n"); - f1ap_gnb_du_system_info_t *sys_info = req->cell[i].sys_info; - /* mib */ - sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char)); - memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size); - sys_info->mib_length = DUsi->mIB_message.size; - /* sib1 */ - sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char)); - memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); - sys_info->sib1_length = DUsi->sIB1_message.size; - } - } - - /* Handle RRC Version */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version, true); - // Latest RRC Version: "This IE is not used in this release." - // BIT_STRING_to_uint8(&ie->value.choice.RRC_Version.latest_RRC_Version); - if (ie->value.choice.RRC_Version.iE_Extensions) { - F1AP_ProtocolExtensionContainer_10696P228_t *ext = - (F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions; - if (ext->list.count > 0) { - F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0]; - OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_; - DevAssert(os->size == 3); - for (int i = 0; i < 3; ++i) - req->rrc_ver[i] = os->buf[i]; - } - } + *req = msg; /* "move" message into ITTI, RRC thread will free it */ itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); - return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 56cb9d0e7b..ab55fd0f05 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -34,6 +34,8 @@ #include "f1ap_encoder.h" #include "f1ap_itti_messaging.h" #include "f1ap_du_interface_management.h" +#include "lib/f1ap_interface_management.h" +#include "lib/f1ap_lib_common.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" #include "assertions.h" @@ -297,110 +299,25 @@ static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_sy return enc_sys_info; } -// SETUP REQUEST +/** + * @brief F1AP Setup Request + */ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req) { LOG_D(F1AP, "DU_send_F1_SETUP_REQUEST\n"); - - F1AP_F1AP_PDU_t pdu= {0}; + F1AP_F1AP_PDU_t *pdu = encode_f1ap_setup_request(setup_req); uint8_t *buffer; uint32_t len; - /* Create */ - /* 0. pdu Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, initMsg); - initMsg->procedureCode = F1AP_ProcedureCode_id_F1Setup; - initMsg->criticality = F1AP_Criticality_reject; - initMsg->value.present = F1AP_InitiatingMessage__value_PR_F1SetupRequest; - F1AP_F1SetupRequest_t *f1Setup = &initMsg->value.choice.F1SetupRequest; - /* mandatory */ - /* c1. Transaction ID (integer value) */ - asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC1); - ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID; - ieC1->criticality = F1AP_Criticality_reject; - ieC1->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID; - ieC1->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0); - /* mandatory */ - /* c2. GNB_DU_ID (integer value) */ - asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC2); - ieC2->id = F1AP_ProtocolIE_ID_id_gNB_DU_ID; - ieC2->criticality = F1AP_Criticality_reject; - ieC2->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID; - asn_int642INTEGER(&ieC2->value.choice.GNB_DU_ID, setup_req->gNB_DU_id); - - /* optional */ - /* c3. GNB_DU_Name */ - if (setup_req->gNB_DU_name != NULL) { - asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieC3); - ieC3->id = F1AP_ProtocolIE_ID_id_gNB_DU_Name; - ieC3->criticality = F1AP_Criticality_ignore; - ieC3->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name; - char *gNB_DU_name=setup_req->gNB_DU_name; - OCTET_STRING_fromBuf(&ieC3->value.choice.GNB_DU_Name, gNB_DU_name, strlen(gNB_DU_name)); - } - - /* mandatory */ - /* c4. served cells list */ - asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ieCells); - ieCells->id = F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List; - ieCells->criticality = F1AP_Criticality_reject; - ieCells->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List; - int num_cells_available = setup_req->num_cells_available; - LOG_D(F1AP, "num_cells_available = %d \n", num_cells_available); - - for (int i=0; icell[i].info; - const f1ap_gnb_du_system_info_t *sys_info = setup_req->cell[i].sys_info; - asn1cSequenceAdd(ieCells->value.choice.GNB_DU_Served_Cells_List.list, - F1AP_GNB_DU_Served_Cells_ItemIEs_t, duServedCell); - duServedCell->id = F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item; - duServedCell->criticality = F1AP_Criticality_reject; - duServedCell->value.present = F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item; - F1AP_GNB_DU_Served_Cells_Item_t *scell_item = &duServedCell->value.choice.GNB_DU_Served_Cells_Item; - scell_item->served_Cell_Information = encode_served_cell_info(cell); - scell_item->gNB_DU_System_Information = encode_system_info(sys_info); - } - - /* mandatory */ - /* c5. RRC VERSION */ - asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version; - ie2->criticality = F1AP_Criticality_reject; - ie2->value.present = F1AP_F1SetupRequestIEs__value_PR_RRC_Version; - // RRC Version: "This IE is not used in this release." - // we put one bit for each byte in rrc_ver that is != 0 - uint8_t bits = 0; - for (int i = 0; i < 3; ++i) - bits |= (setup_req->rrc_ver[i] != 0) << i; - BIT_STRING_t *bs = &ie2->value.choice.RRC_Version.latest_RRC_Version; - bs->buf = calloc(1, sizeof(char)); - AssertFatal(bs->buf != NULL, "out of memory\n"); - bs->buf[0] = bits; - bs->size = 1; - bs->bits_unused = 5; - - F1AP_ProtocolExtensionContainer_10696P228_t *p = calloc(1, sizeof(F1AP_ProtocolExtensionContainer_10696P228_t)); - asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext); - rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced; - rrcv_ext->criticality = F1AP_Criticality_ignore; - rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_; - OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_; - os->size = 3; - os->buf = malloc(3 * sizeof(*os->buf)); - AssertFatal(os->buf != NULL, "out of memory\n"); - for (int i = 0; i < 3; ++i) - os->buf[i] = setup_req->rrc_ver[i]; - ie2->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)p; - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { LOG_E(F1AP, "Failed to encode F1 setup request\n"); + /* free PDU */ + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } - - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + /* free PDU */ + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + /* Send to ITTI */ f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 02e23c0281..6c4f8c3be6 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -100,6 +100,8 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat 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; + /* next transaction ID */ + f1ap_du_data->setupReq.transaction_id = F1AP_get_next_transaction_identifier(0, 0); /* setup parameters for F1U and start the server */ DU_send_F1_SETUP_REQUEST(f1ap_du_data->du.assoc_id, &f1ap_du_data->setupReq); } 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 b06abeb5bc..7bdad73d21 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -24,6 +24,7 @@ #include "mac_rrc_ul.h" #include "f1ap_lib_extern.h" +#include "lib/f1ap_interface_management.h" static void f1_reset_du_initiated_direct(const f1ap_reset_t *reset) { @@ -41,47 +42,8 @@ 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); - f1ap_msg->num_cells_available = req->num_cells_available; - for (int n = 0; n < req->num_cells_available; ++n) { - f1ap_msg->cell[n].info = req->cell[n].info; // copy most fields - if (req->cell[n].info.tac) { - f1ap_msg->cell[n].info.tac = malloc(sizeof(*f1ap_msg->cell[n].info.tac)); - AssertFatal(f1ap_msg->cell[n].info.tac != NULL, "out of memory\n"); - *f1ap_msg->cell[n].info.tac = *req->cell[n].info.tac; - } - if (req->cell[n].info.measurement_timing_config_len > 0) { - f1ap_msg->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t)); - AssertFatal(f1ap_msg->cell[n].info.measurement_timing_config != NULL, "out of memory\n"); - memcpy(f1ap_msg->cell[n].info.measurement_timing_config, - req->cell[n].info.measurement_timing_config, - req->cell[n].info.measurement_timing_config_len); - f1ap_msg->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len; - } - - if (req->cell[n].sys_info) { - f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info; - f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info)); - AssertFatal(copy_sys_info, "out of memory\n"); - f1ap_msg->cell[n].sys_info = copy_sys_info; - - copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->mib, "out of memory\n"); - memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length); - copy_sys_info->mib_length = orig_sys_info->mib_length; - - if (orig_sys_info->sib1_length > 0) { - copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->sib1, "out of memory\n"); - memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length); - copy_sys_info->sib1_length = orig_sys_info->sib1_length; - } - } - } - memcpy(f1ap_msg->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver)); - + f1ap_setup_req_t cp = cp_f1ap_setup_request(req); + F1AP_SETUP_REQ(msg) = cp; itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index e3e46310eb..caf4309bec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -30,6 +30,7 @@ #include "mac_rrc_ul.h" #include "f1ap_lib_extern.h" +#include "lib/f1ap_interface_management.h" static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const char *f1u_ip_addr) { @@ -68,50 +69,9 @@ static void f1_reset_acknowledge_cu_initiated_f1ap(const f1ap_reset_ack_t *ack) static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_DU_REGISTER_REQ); - - f1ap_setup_req_t *f1ap_setup = &F1AP_DU_REGISTER_REQ(msg).setup_req; - f1ap_setup->gNB_DU_id = req->gNB_DU_id; - f1ap_setup->gNB_DU_name = strdup(req->gNB_DU_name); - f1ap_setup->num_cells_available = req->num_cells_available; - for (int n = 0; n < req->num_cells_available; ++n) { - f1ap_setup->cell[n].info = req->cell[n].info; // copy most fields - if (req->cell[n].info.tac) { - f1ap_setup->cell[n].info.tac = malloc(sizeof(*f1ap_setup->cell[n].info.tac)); - AssertFatal(f1ap_setup->cell[n].info.tac != NULL, "out of memory\n"); - *f1ap_setup->cell[n].info.tac = *req->cell[n].info.tac; - } - if (req->cell[n].info.measurement_timing_config_len > 0) { - f1ap_setup->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t)); - AssertFatal(f1ap_setup->cell[n].info.measurement_timing_config != NULL, "out of memory\n"); - memcpy(f1ap_setup->cell[n].info.measurement_timing_config, - req->cell[n].info.measurement_timing_config, - req->cell[n].info.measurement_timing_config_len); - f1ap_setup->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len; - } - - if (req->cell[n].sys_info) { - f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info; - f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info)); - AssertFatal(copy_sys_info, "out of memory\n"); - f1ap_setup->cell[n].sys_info = copy_sys_info; - - copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->mib, "out of memory\n"); - memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length); - copy_sys_info->mib_length = orig_sys_info->mib_length; - - if (orig_sys_info->sib1_length > 0) { - copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->sib1, "out of memory\n"); - memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length); - copy_sys_info->sib1_length = orig_sys_info->sib1_length; - } - } - } - memcpy(f1ap_setup->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver)); - + f1ap_setup_req_t f1ap_setup = cp_f1ap_setup_request(req); + F1AP_DU_REGISTER_REQ(msg).setup_req = f1ap_setup; F1AP_DU_REGISTER_REQ(msg).net_config = read_DU_IP_config(&RC.nrmac[0]->eth_params_n, RC.nrmac[0]->f1u_addr); - itti_send_msg_to_task(TASK_DU_F1, 0, msg); } diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index e20121e8c2..d9fe4ef416 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -29,6 +29,7 @@ #include "executables/softmodem-common.h" #include "common/utils/ds/seq_arr.h" #include "common/utils/alg/foreach.h" +#include "lib/f1ap_interface_management.h" int get_dl_band(const struct f1ap_served_cell_info_t *cell_info) { @@ -261,7 +262,6 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) 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 one cell // - PLMN and Cell ID matches @@ -358,7 +358,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) * allocate memory and copy it in */ du->setup_req = calloc(1,sizeof(*du->setup_req)); AssertFatal(du->setup_req, "out of memory\n"); - *du->setup_req = *req; + // Copy F1AP message + *du->setup_req = cp_f1ap_setup_request(req); // MIB can be null and configured later via DU Configuration Update du->mib = mib; du->sib1 = sib1; @@ -379,6 +380,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) f1ap_setup_resp_t resp = {.transaction_id = req->transaction_id, .num_cells_to_activate = 1, .cells_to_activate[0] = cell}; + // free F1AP message after use + free_f1ap_setup_request(req); int num = read_version(TO_STRING(NR_RRC_VERSION), &resp.rrc_ver[0], &resp.rrc_ver[1], &resp.rrc_ver[2]); AssertFatal(num == 3, "could not read RRC version string %s\n", TO_STRING(NR_RRC_VERSION)); if (rrc->node_name != NULL) From 711afedfe158e3760d7e45d8943193f705a01e20 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 29 Aug 2024 20:48:49 +0200 Subject: [PATCH 23/73] warmup RF board in UE --- executables/nr-ue.c | 5 +++++ openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index a742ea2e9d..55a012106d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -812,6 +812,11 @@ void *UE_thread(void *arg) if (get_softmodem_params()->sync_ref && UE->sl_mode == 2) { UE->is_synchronized = 1; + } else { + //warm up the RF board + int64_t tmp; + for (int i=0; i< 50; i++) + readFrame(UE, &tmp, true); } while (!oai_exit) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index d08a1ed5f3..f61cb715dd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -202,7 +202,7 @@ void nr_scan_ssb(void *arg) /* process pss search on received buffer */ ssbInfo->syncRes.frame_id = frame_id; int nid2; - int freq_offset_pss; + int freq_offset_pss=0; const int sync_pos = pss_synchro_nr((const c16_t **)rxdata, fp, pssTime, From 30628b820c3be6a341e98df2caecf991f439bd49 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 24 May 2024 14:42:09 +0200 Subject: [PATCH 24/73] Add encoding/decoding lib for F1AP Setup Response (Interface Management) --- openair2/F1AP/lib/f1ap_interface_management.c | 337 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 7 + openair2/F1AP/lib/f1ap_lib_includes.h | 2 + 3 files changed, 346 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 437fa4f36d..674bae84de 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -256,6 +256,108 @@ static void decode_system_info(struct F1AP_GNB_DU_System_Information *DUsi, f1ap sys_info->sib1_length = DUsi->sIB1_message.size; } +static void encode_cells_to_activate(const served_cells_to_activate_t *cell, F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_ies) +{ + cells_to_be_activated_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; + cells_to_be_activated_ies->criticality = F1AP_Criticality_reject; + cells_to_be_activated_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; + // Cells to be Activated List Item (M) + F1AP_Cells_to_be_Activated_List_Item_t *cells_to_be_activated_item = + &cells_to_be_activated_ies->value.choice.Cells_to_be_Activated_List_Item; + // NR CGI (M) + MCC_MNC_TO_PLMNID(cell->plmn.mcc, + cell->plmn.mnc, + cell->plmn.mnc_digit_length, + &(cells_to_be_activated_item->nRCGI.pLMN_Identity)); + NR_CELL_ID_TO_BIT_STRING(cell->nr_cellid, &(cells_to_be_activated_item->nRCGI.nRCellIdentity)); + // NR PCI (O) + asn1cCalloc(cells_to_be_activated_item->nRPCI, tmp); + *tmp = cell->nrpci; + // gNB-CU System Information (O) + for (int n = 0; n < cell->num_SI; n++) { + F1AP_ProtocolExtensionContainer_10696P112_t *p = calloc_or_fail(1, sizeof(*p)); + cells_to_be_activated_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p; + asn1cSequenceAdd(p->list, F1AP_Cells_to_be_Activated_List_ItemExtIEs_t, cells_to_be_activated_itemExtIEs); + cells_to_be_activated_itemExtIEs->id = F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation; + cells_to_be_activated_itemExtIEs->criticality = F1AP_Criticality_reject; + cells_to_be_activated_itemExtIEs->extensionValue.present = + F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation; + // gNB-CU System Information message + F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = + &cells_to_be_activated_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; + const f1ap_sib_msg_t *SI_msg = &cell->SI_msg[n]; + if (SI_msg->SI_container != NULL) { + if (SI_msg->SI_type > 6 && SI_msg->SI_type != 9) { + asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); + sib_item->sIBtype = SI_msg->SI_type; + OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container, SI_msg->SI_container_length); + } + } + } +} + +static bool decode_cells_to_activate(served_cells_to_activate_t *out, const F1AP_Cells_to_be_Activated_List_ItemIEs_t *in) +{ + AssertError(in->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item, + return false, + "ID != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item\n"); + AssertError(in->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item, + return false, + "in->value.present != F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item\n"); + const F1AP_Cells_to_be_Activated_List_Item_t *cell = &in->value.choice.Cells_to_be_Activated_List_Item; + // NR CGI (M) + TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, out->plmn.mcc, out->plmn.mnc, out->plmn.mnc_digit_length); + BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, out->nr_cellid); + // NR PCI (O) + if (cell->nRPCI != NULL) + out->nrpci = *cell->nRPCI; + /* IE extensions (O) */ + F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions; + if (ext != NULL) { + for (int cnt = 0; cnt < ext->list.count; cnt++) { + AssertError(ext->list.count == 1, return false, "At least one SI message should be present, and only 1 is supported"); + F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs = + (F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt]; + /* IE extensions items (O) */ + switch (cells_to_be_activated_list_itemExtIEs->id) { + /* gNB-CU System Information */ + case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation: { + out->nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0; + F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = + (F1AP_GNB_CUSystemInformation_t *)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; + /* System Information */ + out->num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; + for (int s = 0; s < out->num_SI; s++) { + F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[s]; + /* SI container */ + f1ap_sib_msg_t *SI_msg = &out->SI_msg[s]; + SI_msg->SI_container = cp_octet_string(&sib_item->sIBmessage, &SI_msg->SI_container_length); + /* SIB type */ + SI_msg->SI_type = sib_item->sIBtype; + } + break; + } + case F1AP_ProtocolIE_ID_id_AvailablePLMNList: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_AvailablePLMNList is not supported"); + break; + case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List is not supported"); + break; + case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU is not supported"); + break; + case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List is not supported"); + break; + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", cells_to_be_activated_list_itemExtIEs->id); + break; + } + } + } + return true; +} + /* ==================================== * F1 SETUP REQUEST * ==================================== */ @@ -519,3 +621,238 @@ void free_f1ap_setup_request(const f1ap_setup_req_t *msg) free_f1ap_cell(&msg->cell[i].info, msg->cell[i].sys_info); } } + +/* ==================================== + * F1 Setup Response + * ==================================== */ + +/** + * @brief F1 Setup Response encoding (9.2.1.5 of 3GPP TS 38.473) + * gNB-CU → gNB-DU + */ +F1AP_F1AP_PDU_t *encode_f1ap_setup_response(const f1ap_setup_resp_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + + /* Create */ + /* 0. Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_F1Setup; + tmp->criticality = F1AP_Criticality_reject; + tmp->value.present = F1AP_SuccessfulOutcome__value_PR_F1SetupResponse; + F1AP_F1SetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse; + // Transaction ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_F1SetupResponseIEs__value_PR_TransactionID; + ie1->value.choice.TransactionID = msg->transaction_id; + // gNB-CU Name (O) + if (msg->gNB_CU_name != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_gNB_CU_Name; + ie2->criticality = F1AP_Criticality_ignore; + ie2->value.present = F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name; + OCTET_STRING_fromBuf(&ie2->value.choice.GNB_CU_Name, msg->gNB_CU_name, strlen(msg->gNB_CU_name)); + } + // Cells to be Activated List (O) + for (int i = 0; i < msg->num_cells_to_activate; i++) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List; + asn1cSequenceAdd(ie3->value.choice.Cells_to_be_Activated_List.list, + F1AP_Cells_to_be_Activated_List_ItemIEs_t, + cells_to_be_activated_ies); + encode_cells_to_activate(&msg->cells_to_activate[i], cells_to_be_activated_ies); + } + // gNB-CU RRC version (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_F1SetupResponseIEs__value_PR_RRC_Version; + // RRC Version: "This IE is not used in this release." + // we put one bit for each byte in rrc_ver that is != 0 + uint8_t bits = 0; + for (int i = 0; i < sizeofArray(msg->rrc_ver); ++i) + bits |= (msg->rrc_ver[i] != 0) << i; + BIT_STRING_t *bs = &ie4->value.choice.RRC_Version.latest_RRC_Version; + bs->buf = calloc_or_fail(1, sizeof(*bs->buf)); + bs->buf[0] = bits; + bs->size = 1; + bs->bits_unused = 5; + + F1AP_ProtocolExtensionContainer_10696P228_t *p = calloc_or_fail(1, sizeof(*p)); + asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext); + rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced; + rrcv_ext->criticality = F1AP_Criticality_ignore; + rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_; + OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_; + os->size = sizeofArray(msg->rrc_ver); + os->buf = malloc_or_fail(sizeof(msg->rrc_ver)); + for (int i = 0; i < sizeofArray(msg->rrc_ver); ++i) + os->buf[i] = msg->rrc_ver[i]; + ie4->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p; + + return pdu; +} + +/** + * @brief F1 Setup Response decoding (9.2.1.5 of 3GPP TS 38.473) + * gNB-CU → gNB-DU + */ +bool decode_f1ap_setup_response(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_resp_t *out) +{ + /* Check presence of message type */ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome); + _F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_F1Setup); + _F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, F1AP_SuccessfulOutcome__value_PR_F1SetupResponse); + /* Check presence of mandatory IEs */ + F1AP_F1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse; + F1AP_F1SetupResponseIEs_t *ie; + F1AP_LIB_FIND_IE(F1AP_F1SetupResponseIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + F1AP_LIB_FIND_IE(F1AP_F1SetupResponseIEs_t, ie, in, F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + // Transaction ID (M) + _F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_TransactionID); + AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1"); + out->transaction_id = ie->value.choice.TransactionID; + break; + + case F1AP_ProtocolIE_ID_id_gNB_CU_Name: { + // gNB-CU Name (O) + _F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name); + const F1AP_GNB_CU_Name_t *cu_name = &ie->value.choice.GNB_CU_Name; + out->gNB_CU_name = calloc_or_fail(cu_name->size + 1, sizeof(*out->gNB_CU_name)); + strncpy(out->gNB_CU_name, (char *)cu_name->buf, cu_name->size); + } break; + + case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version: + // gNB-CU RRC version (M) + _F1_EQ_CHECK_INT(ie->value.present, F1AP_F1SetupResponseIEs__value_PR_RRC_Version); + // RRC Version: "This IE is not used in this release." + if (ie->value.choice.RRC_Version.iE_Extensions) { + F1AP_ProtocolExtensionContainer_10696P228_t *ext = + (F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions; + if (ext->list.count > 0) { + F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0]; + OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_; + for (int i = 0; i < sizeofArray(out->rrc_ver); i++) + out->rrc_ver[i] = os->buf[i]; + } + } + break; + + case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: { + // Cells to be Activated List (O) + if (ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List) + break; + struct F1AP_Cells_to_be_Activated_List *Cells_to_be_Activated_List = &ie->value.choice.Cells_to_be_Activated_List; + out->num_cells_to_activate = Cells_to_be_Activated_List->list.count; + // Loop Cells to be Activated List Items (count >= 1) + AssertError(out->num_cells_to_activate > 0, return false, "At least 1 cell must be present"); + for (int i = 0; i < out->num_cells_to_activate; i++) { + const F1AP_Cells_to_be_Activated_List_ItemIEs_t *itemIEs + = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)Cells_to_be_Activated_List->list.array[i]; + if (!decode_cells_to_activate(&out->cells_to_activate[i], itemIEs)) + return false; + } + break; + } + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id); + break; + } + } + + return true; +} + +/** + * @brief F1AP Setup Response equality check + */ +bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t *b) +{ + _F1_EQ_CHECK_STR(a->gNB_CU_name, b->gNB_CU_name); + _F1_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate); + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + if (a->num_cells_to_activate) { + for (int i = 0; i < a->num_cells_to_activate; i++) { + const served_cells_to_activate_t *a_cell = &a->cells_to_activate[i]; + const served_cells_to_activate_t *b_cell = &b->cells_to_activate[i]; + _F1_EQ_CHECK_LONG(a_cell->nr_cellid, b_cell->nr_cellid); + _F1_EQ_CHECK_INT(a_cell->nrpci, b_cell->nrpci); + _F1_EQ_CHECK_INT(a_cell->num_SI, b_cell->num_SI); + _F1_EQ_CHECK_LONG(a_cell->nr_cellid, b_cell->nr_cellid); + if (!eq_f1ap_plmn(&a_cell->plmn, &b_cell->plmn)) + return false; + if (sizeofArray(a->cells_to_activate[i].SI_msg) != sizeofArray(b->cells_to_activate[i].SI_msg)) + return false; + for (int j = 0; j < b->cells_to_activate[i].num_SI; j++) { + const f1ap_sib_msg_t *a_SI_msg = &a->cells_to_activate[i].SI_msg[j]; + const f1ap_sib_msg_t *b_SI_msg = &b->cells_to_activate[i].SI_msg[j]; + _F1_EQ_CHECK_INT(*a_SI_msg->SI_container, *b_SI_msg->SI_container); + _F1_EQ_CHECK_INT(a_SI_msg->SI_container_length, b_SI_msg->SI_container_length); + _F1_EQ_CHECK_INT(a_SI_msg->SI_type, b_SI_msg->SI_type); + } + } + } + _F1_EQ_CHECK_LONG(sizeofArray(a->rrc_ver), sizeofArray(b->rrc_ver)); + for (int i = 0; i < sizeofArray(a->rrc_ver); i++) { + _F1_EQ_CHECK_INT(a->rrc_ver[i], b->rrc_ver[i]); + } + return true; +} + +/** + * @brief F1AP Setup Response deep copy + */ +f1ap_setup_resp_t cp_f1ap_setup_response(const f1ap_setup_resp_t *msg) +{ + f1ap_setup_resp_t cp = {0}; + /* gNB_CU_name */ + if (msg->gNB_CU_name != NULL) + cp.gNB_CU_name = strdup(msg->gNB_CU_name); + /* transaction_id */ + cp.transaction_id = msg->transaction_id; + /* num_cells_available */ + cp.num_cells_to_activate = msg->num_cells_to_activate; + for (int n = 0; n < msg->num_cells_to_activate; n++) { + /* cell.info */ + served_cells_to_activate_t *cp_cell = &cp.cells_to_activate[n]; + const served_cells_to_activate_t *msg_cell = &msg->cells_to_activate[n]; + cp_cell->nr_cellid = msg_cell->nr_cellid; + cp_cell->nrpci = msg_cell->nrpci; + cp_cell->num_SI = msg_cell->num_SI; + cp_cell->plmn = msg_cell->plmn; + for (int j = 0; j < cp_cell->num_SI; j++) { + f1ap_sib_msg_t *cp_SI_msg = &cp_cell->SI_msg[j]; + const f1ap_sib_msg_t *b_SI_msg = &msg_cell->SI_msg[j]; + cp_SI_msg->SI_container_length = b_SI_msg->SI_container_length; + cp_SI_msg->SI_container = malloc_or_fail(cp_SI_msg->SI_container_length); + *cp_SI_msg->SI_container = *b_SI_msg->SI_container; + cp_SI_msg->SI_type = b_SI_msg->SI_type; + } + } + for (int i = 0; i < sizeofArray(msg->rrc_ver); i++) + cp.rrc_ver[i] = msg->rrc_ver[i]; + return cp; +} + +/** + * @brief F1AP Setup Response memory management + */ +void free_f1ap_setup_response(const f1ap_setup_resp_t *msg) +{ + DevAssert(msg != NULL); + free(msg->gNB_CU_name); + for (int i = 0; i < msg->num_cells_to_activate; i++) + for (int j = 0; j < msg->cells_to_activate[i].num_SI; j++) + if (msg->cells_to_activate[i].SI_msg[j].SI_container_length > 0) + free(msg->cells_to_activate[i].SI_msg[j].SI_container); +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index 6b196b9999..33a5f8402b 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -33,4 +33,11 @@ f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg); bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b); void free_f1ap_setup_request(const f1ap_setup_req_t *msg); +/* F1 Setup Response */ +struct F1AP_F1AP_PDU *encode_f1ap_setup_response(const f1ap_setup_resp_t *msg); +bool decode_f1ap_setup_response(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_resp_t *out); +void free_f1ap_setup_response(const f1ap_setup_resp_t *msg); +f1ap_setup_resp_t cp_f1ap_setup_response(const f1ap_setup_resp_t *msg); +bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t *b); + #endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_includes.h b/openair2/F1AP/lib/f1ap_lib_includes.h index 0e5ace104d..2386073dee 100644 --- a/openair2/F1AP/lib/f1ap_lib_includes.h +++ b/openair2/F1AP/lib/f1ap_lib_includes.h @@ -37,5 +37,7 @@ #include "F1AP_FDD-Info.h" #include "F1AP_TDD-Info.h" #include "F1AP_FreqBandNrItem.h" +#include "F1AP_SuccessfulOutcome.h" +#include "F1AP_SibtypetobeupdatedListItem.h" #endif /* F1AP_LIB_INCLUDES_H_ */ From df2c92e652eee9a642e22aa8687c4217969d4087 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 27 May 2024 17:23:33 +0200 Subject: [PATCH 25/73] Add test for F1AP Setup Response enc/dec lib --- openair2/F1AP/tests/f1ap_lib_test.c | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 005ebe5bb8..16c404b722 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -3,6 +3,7 @@ #include #include "common/utils/assertions.h" +#include "common/utils/utils.h" #include "f1ap_messages_types.h" #include "F1AP_F1AP-PDU.h" @@ -271,11 +272,70 @@ static void test_f1ap_setup_request(void) free_f1ap_setup_request(&orig); } +/** + * @brief Test F1AP Setup Response Encoding/Decoding + */ +static void test_f1ap_setup_response(void) +{ + /* allocate memory */ + /* gNB_CU_name */ + char *cu_name = "OAI-CU"; + int len = strlen(cu_name) + 1; + uint8_t *gNB_CU_name = calloc(len, sizeof(uint8_t)); + AssertFatal(gNB_CU_name != NULL, "out of memory\n"); + memcpy((void *)gNB_CU_name, cu_name, len); + /* create message */ + f1ap_setup_resp_t orig = { + .gNB_CU_name = (char *)gNB_CU_name, + .transaction_id = 2, + .rrc_ver[0] = 12, + .rrc_ver[1] = 34, + .rrc_ver[2] = 56, + .num_cells_to_activate = 1, + .cells_to_activate[0].nr_cellid = 123456, + .cells_to_activate[0].nrpci = 1, + .cells_to_activate[0].plmn.mcc = 12, + .cells_to_activate[0].plmn.mnc = 123, + .cells_to_activate[0].plmn.mnc_digit_length = 3, + }; + /* Cells to activate */ + if (orig.num_cells_to_activate) { + /* SI_container */ + char *s = "test"; + int SI_container_length = strlen(s) + 1; + orig.cells_to_activate[0].num_SI = 1; + f1ap_sib_msg_t *SI_msg = &orig.cells_to_activate[0].SI_msg[0]; + SI_msg->SI_container = malloc_or_fail(SI_container_length); + memcpy(SI_msg->SI_container, (uint8_t *)s, SI_container_length); + SI_msg->SI_container_length = SI_container_length; + SI_msg->SI_type = 7; + } + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_response(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_setup_resp_t decoded = {0}; + bool ret = decode_f1ap_setup_response(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_setup_response(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_f1ap_setup_response(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_setup_response(): decoded message doesn't match\n"); + free_f1ap_setup_response(&decoded); + + f1ap_setup_resp_t cp = cp_f1ap_setup_response(&orig); + ret = eq_f1ap_setup_response(&orig, &cp); + AssertFatal(ret, "eq_f1ap_setup_response(): copied message doesn't match\n"); + free_f1ap_setup_response(&cp); + free_f1ap_setup_response(&orig); +} + int main() { test_initial_ul_rrc_message_transfer(); test_dl_rrc_message_transfer(); test_ul_rrc_message_transfer(); test_f1ap_setup_request(); + test_f1ap_setup_response(); return 0; } From 3a5ace00d274ae1a595aec984231a813a8d43c4f Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:51:29 +0200 Subject: [PATCH 26/73] Use F1AP lib for F1 Setup Response in stack --- openair2/F1AP/f1ap_cu_interface_management.c | 138 ++------------ openair2/F1AP/f1ap_du_interface_management.c | 176 +----------------- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 9 +- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 2 + 4 files changed, 24 insertions(+), 301 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 2685325d6e..c3a9f39d7d 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -102,142 +102,26 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 return 0; } +/** + * @brief F1AP Setup Response encoding (9.2.1.5 of 3GPP TS 38.473) and message transfer + */ 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; - uint32_t len=0; - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; - asn1cCalloc(pdu.choice.successfulOutcome, tmp); - tmp->procedureCode = F1AP_ProcedureCode_id_F1Setup; - tmp->criticality = F1AP_Criticality_reject; - tmp->value.present = F1AP_SuccessfulOutcome__value_PR_F1SetupResponse; - F1AP_F1SetupResponse_t *out = &pdu.choice.successfulOutcome->value.choice.F1SetupResponse; - /* mandatory */ - /* c1. Transaction ID (integer value)*/ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_F1SetupResponseIEs__value_PR_TransactionID; - ie1->value.choice.TransactionID = f1ap_setup_resp->transaction_id; + uint32_t len = 0; - /* optional */ - /* c2. GNB_CU_Name */ - if (f1ap_setup_resp->gNB_CU_name != NULL) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_gNB_CU_Name; - ie2->criticality = F1AP_Criticality_ignore; - ie2->value.present = F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name; - OCTET_STRING_fromBuf(&ie2->value.choice.GNB_CU_Name, f1ap_setup_resp->gNB_CU_name, - strlen(f1ap_setup_resp->gNB_CU_name)); - } - - /* mandatory */ - /* c3. cells to be Activated list */ - int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate; - LOG_D(F1AP, "num_cells_to_activate = %d \n", num_cells_to_activate); - - if (num_cells_to_activate >0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List; - - for (int i=0; ivalue.choice.Cells_to_be_Activated_List.list, - F1AP_Cells_to_be_Activated_List_ItemIEs_t, cells_to_be_activated_ies); - cells_to_be_activated_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; - cells_to_be_activated_ies->criticality = F1AP_Criticality_reject; - cells_to_be_activated_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; - /* 3.1 cells to be Activated list item */ - F1AP_Cells_to_be_Activated_List_Item_t *cells_to_be_activated_item= - &cells_to_be_activated_ies->value.choice.Cells_to_be_Activated_List_Item; - /* - nRCGI */ - addnRCGI(cells_to_be_activated_item->nRCGI, f1ap_setup_resp->cells_to_activate+i); - - /* optional */ - /* - nRPCI */ - if (1) { - cells_to_be_activated_item->nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t)); - *cells_to_be_activated_item->nRPCI = f1ap_setup_resp->cells_to_activate[i].nrpci; // int 0..1007 - } - - /* optional */ - /* - gNB-CU System Information */ - if (f1ap_setup_resp->cells_to_activate[i].num_SI > 0) { - /* 3.1.2 gNB-CUSystem Information */ - F1AP_ProtocolExtensionContainer_10696P112_t *p = calloc(1, sizeof(* p)); - cells_to_be_activated_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *) p; - asn1cSequenceAdd(p->list, F1AP_Cells_to_be_Activated_List_ItemExtIEs_t, cells_to_be_activated_itemExtIEs); - cells_to_be_activated_itemExtIEs->id = F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation; - cells_to_be_activated_itemExtIEs->criticality = F1AP_Criticality_reject; - cells_to_be_activated_itemExtIEs->extensionValue.present = F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation; - F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = - &cells_to_be_activated_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; - - // for (int sIBtype=2;sIBtype<33;sIBtype++) { //21 ? 33 ? - for (int sIBtype=2; sIBtype<21; sIBtype++) { - for (int n = 0; n < f1ap_setup_resp->cells_to_activate[i].num_SI; n++) { - if (f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container != NULL) { - if (f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_type > 6 - && f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_type != 9) { - asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); - sib_item->sIBtype = f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_type; - OCTET_STRING_fromBuf(&sib_item->sIBmessage, - (const char *)f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container, - f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container_length); - LOG_D(F1AP, - "f1ap_setup_resp->cells_to_activate[%d].SI_msg[%d].SI_container_length = %d \n", - i, - n, - f1ap_setup_resp->cells_to_activate[i].SI_msg[n].SI_container_length); - } - } - } - } - } - } - } - - /* c5. RRC VERSION */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_F1SetupResponseIEs__value_PR_RRC_Version; - // RRC Version: "This IE is not used in this release." - // we put one bit for each byte in rrc_ver that is != 0 - uint8_t bits = 0; - for (int i = 0; i < 3; ++i) - bits |= (f1ap_setup_resp->rrc_ver[i] != 0) << i; - BIT_STRING_t *bs = &ie4->value.choice.RRC_Version.latest_RRC_Version; - bs->buf = calloc(1, sizeof(char)); - AssertFatal(bs->buf != NULL, "out of memory\n"); - bs->buf[0] = bits; - bs->size = 1; - bs->bits_unused = 5; - - F1AP_ProtocolExtensionContainer_10696P228_t *p = (F1AP_ProtocolExtensionContainer_10696P228_t*)calloc(1, sizeof(F1AP_ProtocolExtensionContainer_10696P228_t)); - asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext); - rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced; - rrcv_ext->criticality = F1AP_Criticality_ignore; - rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_; - OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_; - os->size = 3; - os->buf = malloc(3 * sizeof(*os->buf)); - AssertFatal(os->buf != NULL, "out of memory\n"); - for (int i = 0; i < 3; ++i) - os->buf[i] = f1ap_setup_resp->rrc_ver[i]; - ie4->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p; + /* Encode F1 Setup Response */ + F1AP_F1AP_PDU_t *pdu = encode_f1ap_setup_response(f1ap_setup_resp); + /* Free after encode */ + free_f1ap_setup_response(f1ap_setup_resp); /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { LOG_E(F1AP, "Failed to encode F1 setup response\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } - - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index ab55fd0f05..5d1f44dbdc 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -325,177 +325,13 @@ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setu int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { LOG_D(F1AP, "DU_handle_F1_SETUP_RESPONSE\n"); - AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_successfulOutcome, - "pdu->present != F1AP_F1AP_PDU_PR_successfulOutcome\n"); - AssertFatal(pdu->choice.successfulOutcome->procedureCode == F1AP_ProcedureCode_id_F1Setup, - "pdu->choice.successfulOutcome->procedureCode != F1AP_ProcedureCode_id_F1Setup\n"); - AssertFatal(pdu->choice.successfulOutcome->criticality == F1AP_Criticality_reject, - "pdu->choice.successfulOutcome->criticality != F1AP_Criticality_reject\n"); - AssertFatal(pdu->choice.successfulOutcome->value.present == F1AP_SuccessfulOutcome__value_PR_F1SetupResponse, - "pdu->choice.successfulOutcome->value.present != F1AP_SuccessfulOutcome__value_PR_F1SetupResponse\n"); - F1AP_F1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse; - F1AP_F1SetupResponseIEs_t *ie; - int TransactionId = -1; - int num_cells_to_activate = 0; + /* Decode */ f1ap_setup_resp_t resp = {0}; - - for (int i=0; i < in->protocolIEs.list.count; i++) { - ie = in->protocolIEs.list.array[i]; - - switch (ie->id) { - case F1AP_ProtocolIE_ID_id_TransactionID: - AssertFatal(ie->criticality == F1AP_Criticality_reject, - "ie->criticality != F1AP_Criticality_reject\n"); - AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_TransactionID, - "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n"); - TransactionId=ie->value.choice.TransactionID; - LOG_D(F1AP, "F1AP: F1Setup-Resp: TransactionId %d\n", - TransactionId); - break; - - case F1AP_ProtocolIE_ID_id_gNB_CU_Name: - AssertFatal(ie->criticality == F1AP_Criticality_ignore, - "ie->criticality != F1AP_Criticality_ignore\n"); - AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name, - "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name\n"); - resp.gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1); - memcpy(resp.gNB_CU_name, ie->value.choice.GNB_CU_Name.buf, ie->value.choice.GNB_CU_Name.size); - resp.gNB_CU_name[ie->value.choice.GNB_CU_Name.size] = '\0'; - LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n", resp.gNB_CU_name); - break; - - case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version: - AssertFatal(ie->criticality == F1AP_Criticality_reject, - "ie->criticality != F1AP_Criticality_reject\n"); - AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_RRC_Version, - "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_RRC_Version\n"); - // RRC Version: "This IE is not used in this release." - if(ie->value.choice.RRC_Version.iE_Extensions) { - F1AP_ProtocolExtensionContainer_10696P228_t *ext = - (F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions; - if(ext->list.count > 0){ - F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0]; - OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_; - for (int i = 0; i < 3; i++) - resp.rrc_ver[i] = os->buf[i]; - } - } - break; - - case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: { - AssertFatal(ie->criticality == F1AP_Criticality_reject, - "ie->criticality != F1AP_Criticality_reject\n"); - AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List, - "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List\n"); - num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count; - LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate); - - for (int i=0; ivalue.choice.Cells_to_be_Activated_List.list.array[i]; - AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item, - "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item"); - AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject, - "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"); - 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, - resp.cells_to_activate[i].plmn.mnc_digit_length); - LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n", - cell->nRCGI.nRCellIdentity.buf[0], - cell->nRCGI.nRCellIdentity.buf[1], - cell->nRCGI.nRCellIdentity.buf[2], - cell->nRCGI.nRCellIdentity.buf[3], - cell->nRCGI.nRCellIdentity.buf[4]); - BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, 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) - continue; - - for (int cnt=0; cntlist.count; cnt++) { - F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs=(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt]; - - switch (cells_to_be_activated_list_itemExtIEs->id) { - /* - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING: - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List - */ - case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation: { - resp.cells_to_activate[i].nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0; - F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; - resp.cells_to_activate[i].num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; - AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n"); - LOG_D(F1AP, - "F1AP: Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n", - i, - resp.cells_to_activate[i].plmn.mcc, - resp.cells_to_activate[i].plmn.mnc, - resp.cells_to_activate[i].nr_cellid, - resp.cells_to_activate[i].num_SI); - for (int s = 0; s < resp.cells_to_activate[i].num_SI; s++) { - F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[s]; - f1ap_sib_msg_t *SI_msg = &resp.cells_to_activate[i].SI_msg[s]; - SI_msg->SI_container = calloc(sib_item->sIBmessage.size, sizeof(uint8_t)); - AssertFatal(SI_msg->SI_container != NULL, "out of memory\n"); - memcpy(SI_msg->SI_container, sib_item->sIBmessage.buf, sib_item->sIBmessage.size); - SI_msg->SI_container_length = sib_item->sIBmessage.size; - SI_msg->SI_type = sib_item->sIBtype; - LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, sib_item->sIBmessage.size); - } - - break; - } - - case F1AP_ProtocolIE_ID_id_AvailablePLMNList: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - default: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id); - break; - } - } // for (cnt=... - } // for (cells_to_activate... - - break; - } // case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List - - default: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n", (int)ie->id); - break; - } // switch ie - } // for IE - - AssertFatal(TransactionId!=-1,"TransactionId was not sent\n"); - LOG_D(F1AP,"F1AP: num_cells_to_activate %d\n",num_cells_to_activate); - resp.num_cells_to_activate = num_cells_to_activate; - - // tmp - for (int i=0; if1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp)); AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n"); - *mac->f1_config.setup_resp = *resp; - if (resp->gNB_CU_name) - mac->f1_config.setup_resp->gNB_CU_name = strdup(resp->gNB_CU_name); - + // Copy F1AP message + *mac->f1_config.setup_resp = cp_f1ap_setup_response(resp); + // free F1AP message after copy + free_f1ap_setup_response(resp); NR_SCHED_UNLOCK(&mac->sched_lock); // NOTE: Before accepting any UEs, we should initialize the UE states. diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 9f1b8b4b53..e2e094d866 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -24,6 +24,7 @@ #include "mac_rrc_dl.h" #include "nr_rrc_defs.h" #include "openair2/F1AP/lib/f1ap_rrc_message_transfer.h" +#include "openair2/F1AP/lib/f1ap_interface_management.h" static void f1_reset_cu_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) { @@ -45,6 +46,7 @@ static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_ *f1ap_msg = *resp; if (resp->gNB_CU_name != NULL) f1ap_msg->gNB_CU_name = strdup(resp->gNB_CU_name); + free_f1ap_setup_response(resp); itti_send_msg_to_task(TASK_CU_F1, 0, msg); } From 28e2d67ee5dfc5c04cacefd0d27f47107e974b42 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 28 May 2024 10:25:59 +0200 Subject: [PATCH 27/73] Fixes to F1 Setup Failure * added missing Transaction ID to te F1 Setup Failure message struct * fill F1 Setup Failure transaction ID in RRC before calling the F1 Setup Failure function --- openair2/COMMON/f1ap_messages_types.h | 4 +++- openair2/RRC/NR/rrc_gNB_du.c | 13 ++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 2224cf822f..f46fe3b55b 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -233,7 +233,9 @@ typedef struct f1ap_gnb_cu_configuration_update_s { typedef struct f1ap_setup_failure_s { uint16_t cause; uint16_t time_to_wait; - uint16_t criticality_diagnostics; + uint16_t criticality_diagnostics; + /// Transaction ID (M) + uint64_t transaction_id; } f1ap_setup_failure_t; typedef struct f1ap_gnb_cu_configuration_update_acknowledge_s { diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index d9fe4ef416..1322c52141 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -262,6 +262,9 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) 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); + // pre-fill F1 Setup Failure message + f1ap_setup_failure_t fail = {.transaction_id = F1AP_get_next_transaction_identifier(0, 0)}; + // check: // - it is one cell // - PLMN and Cell ID matches @@ -269,7 +272,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) // else reject 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}; + fail.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } @@ -283,7 +286,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) cell_info->plmn.mcc, cell_info->plmn.mnc_digit_length, cell_info->plmn.mnc); - f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU}; + fail.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } @@ -295,7 +298,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) it->setup_req->gNB_DU_name, it->assoc_id, it->setup_req->gNB_DU_id); - f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified}; + fail.cause = F1AP_CauseMisc_unspecified; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } @@ -312,7 +315,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) exist_info->nr_pci, new_info->nr_cellid, new_info->nr_pci); - f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified}; + fail.cause = F1AP_CauseMisc_unspecified; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } @@ -339,7 +342,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)) { if (!extract_sys_info(sys_info, &mib, &sib1)) { LOG_W(RRC, "rejecting DU ID %ld\n", req->gNB_DU_id); - f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + fail.cause = F1AP_CauseProtocol_semantic_error; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc); return; From 7e495db5ec03df79529a91e3f0b33a2d09a77588 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 28 May 2024 10:27:19 +0200 Subject: [PATCH 28/73] Add encoding/decoding lib for F1 Setup Failure (interface management) --- openair2/F1AP/lib/f1ap_interface_management.c | 114 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 6 + openair2/F1AP/lib/f1ap_lib_includes.h | 1 + 3 files changed, 121 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 674bae84de..544b89893b 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -856,3 +856,117 @@ void free_f1ap_setup_response(const f1ap_setup_resp_t *msg) if (msg->cells_to_activate[i].SI_msg[j].SI_container_length > 0) free(msg->cells_to_activate[i].SI_msg[j].SI_container); } + +/* ==================================== + * F1AP Setup Failure + * ==================================== */ + +/** + * @brief F1AP Setup Failure encoding + */ +F1AP_F1AP_PDU_t *encode_f1ap_setup_failure(const f1ap_setup_failure_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + /* Create */ + /* 0. Message Type */ + asn1cCalloc(pdu->choice.unsuccessfulOutcome, UnsuccessfulOutcome); + pdu->present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; + UnsuccessfulOutcome->procedureCode = F1AP_ProcedureCode_id_F1Setup; + UnsuccessfulOutcome->criticality = F1AP_Criticality_reject; + UnsuccessfulOutcome->value.present = F1AP_UnsuccessfulOutcome__value_PR_F1SetupFailure; + F1AP_F1SetupFailure_t *out = &pdu->choice.unsuccessfulOutcome->value.choice.F1SetupFailure; + /* mandatory */ + /* c1. Transaction ID (integer value)*/ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_F1SetupFailureIEs__value_PR_TransactionID; + ie1->value.choice.TransactionID = msg->transaction_id; + /* mandatory */ + /* c2. Cause */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_Cause; + ie2->criticality = F1AP_Criticality_ignore; + ie2->value.present = F1AP_F1SetupFailureIEs__value_PR_Cause; + ie2->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork; + ie2->value.choice.Cause.choice.radioNetwork = msg->cause; + /* optional */ + /* c3. TimeToWait */ + if (msg->time_to_wait > 0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_TimeToWait; + ie3->criticality = F1AP_Criticality_ignore; + ie3->value.present = F1AP_F1SetupFailureIEs__value_PR_TimeToWait; + ie3->value.choice.TimeToWait = F1AP_TimeToWait_v10s; + } + /* optional */ + /* c4. CriticalityDiagnostics*/ + if (msg->criticality_diagnostics) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie4->criticality = F1AP_Criticality_ignore; + ie4->value.present = F1AP_F1SetupFailureIEs__value_PR_CriticalityDiagnostics; + asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.procedureCode, F1AP_ProcedureCode_id_UEContextSetup); + asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.triggeringMessage, F1AP_TriggeringMessage_initiating_message); + asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.procedureCriticality, F1AP_Criticality_reject); + asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.transactionID, 0); + } + return pdu; +} + +/** + * @brief F1AP Setup Failure decoding + */ +bool decode_f1ap_setup_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_failure_t *out) +{ + F1AP_F1SetupFailureIEs_t *ie; + F1AP_F1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.F1SetupFailure; + /* Check presence of mandatory IEs */ + F1AP_LIB_FIND_IE(F1AP_F1SetupFailureIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + F1AP_LIB_FIND_IE(F1AP_F1SetupFailureIEs_t, ie, in, F1AP_ProtocolIE_ID_id_Cause, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + /* Transaction ID (M) */ + out->transaction_id = ie->value.choice.TransactionID; + break; + case F1AP_ProtocolIE_ID_id_Cause: + /* Cause (M) */ + out->cause = ie->value.choice.Cause.choice.radioNetwork; + break; + case F1AP_ProtocolIE_ID_id_TimeToWait: + out->time_to_wait = ie->value.choice.TimeToWait; + break; + case F1AP_ProtocolIE_ID_id_CriticalityDiagnostics: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_CriticalityDiagnostics is not supported"); + break; + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id); + break; + } + } + return true; +} + +/** + * @brief F1AP Setup Failure equality check + */ +bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b) +{ + if (a->transaction_id != b->transaction_id) + return false; + return true; +} + +/** + * @brief F1AP Setup Failure deep copy + */ +f1ap_setup_failure_t cp_f1ap_setup_failure(const f1ap_setup_failure_t *msg) +{ + f1ap_setup_failure_t cp = {0}; + /* transaction_id */ + cp.transaction_id = msg->transaction_id; + return cp; +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index 33a5f8402b..ca0b7df491 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -40,4 +40,10 @@ void free_f1ap_setup_response(const f1ap_setup_resp_t *msg); f1ap_setup_resp_t cp_f1ap_setup_response(const f1ap_setup_resp_t *msg); bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t *b); +/* F1 Setup Failure */ +struct F1AP_F1AP_PDU *encode_f1ap_setup_failure(const f1ap_setup_failure_t *msg); +bool decode_f1ap_setup_failure(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_failure_t *out); +bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b); +f1ap_setup_failure_t cp_f1ap_setup_failure(const f1ap_setup_failure_t *msg); + #endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_includes.h b/openair2/F1AP/lib/f1ap_lib_includes.h index 2386073dee..6ff60a4897 100644 --- a/openair2/F1AP/lib/f1ap_lib_includes.h +++ b/openair2/F1AP/lib/f1ap_lib_includes.h @@ -39,5 +39,6 @@ #include "F1AP_FreqBandNrItem.h" #include "F1AP_SuccessfulOutcome.h" #include "F1AP_SibtypetobeupdatedListItem.h" +#include "F1AP_UnsuccessfulOutcome.h" #endif /* F1AP_LIB_INCLUDES_H_ */ From 6146c470e233e49eb8453bfb61e9643ed37667ee Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 28 May 2024 10:30:49 +0200 Subject: [PATCH 29/73] Add test for F1AP Setup Failure enc/dec lib --- openair2/F1AP/tests/f1ap_lib_test.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 16c404b722..42f07e4c2a 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -330,6 +330,33 @@ static void test_f1ap_setup_response(void) free_f1ap_setup_response(&orig); } +/** + * @brief Test F1AP Setup Failure Encoding/Decoding + */ +static void test_f1ap_setup_failure(void) +{ + /* create message */ + f1ap_setup_failure_t orig = { + .transaction_id = 2, + .cause = 4, + }; + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_failure(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_setup_failure_t decoded = {0}; + bool ret = decode_f1ap_setup_failure(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_setup_failure(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_f1ap_setup_failure(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_setup_failure(): decoded message doesn't match\n"); + + f1ap_setup_failure_t cp = cp_f1ap_setup_failure(&orig); + ret = eq_f1ap_setup_failure(&orig, &cp); + AssertFatal(ret, "eq_f1ap_setup_failure(): copied message doesn't match\n"); +} + int main() { test_initial_ul_rrc_message_transfer(); @@ -337,5 +364,6 @@ int main() test_ul_rrc_message_transfer(); test_f1ap_setup_request(); test_f1ap_setup_response(); + test_f1ap_setup_failure(); return 0; } From 289fdfe3814b70fc486c75e1daac105a0c304ccd Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:52:00 +0200 Subject: [PATCH 30/73] Use F1AP Setup Failure enc/dec lib in stack --- openair2/F1AP/f1ap_cu_interface_management.c | 68 +++----------------- openair2/F1AP/f1ap_du_interface_management.c | 23 ++----- 2 files changed, 17 insertions(+), 74 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index c3a9f39d7d..49f887ad49 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -126,70 +126,22 @@ int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_set return 0; } +/** + * @brief F1 Setup Failure encoding and transmission + */ 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}; - uint8_t *buffer=NULL; - uint32_t len=0; - /* Create */ - /* 0. Message Type */ - asn1cCalloc(pdu.choice.unsuccessfulOutcome, UnsuccessfulOutcome); - pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; - UnsuccessfulOutcome->procedureCode = F1AP_ProcedureCode_id_F1Setup; - UnsuccessfulOutcome->criticality = F1AP_Criticality_reject; - UnsuccessfulOutcome->value.present = F1AP_UnsuccessfulOutcome__value_PR_F1SetupFailure; - F1AP_F1SetupFailure_t *out = &pdu.choice.unsuccessfulOutcome->value.choice.F1SetupFailure; - /* mandatory */ - /* c1. Transaction ID (integer value)*/ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_F1SetupFailureIEs__value_PR_TransactionID; - ie1->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0); - /* mandatory */ - /* c2. Cause */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_Cause; - ie2->criticality = F1AP_Criticality_ignore; - ie2->value.present = F1AP_F1SetupFailureIEs__value_PR_Cause; - ie2->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork; - ie2->value.choice.Cause.choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified; - - /* optional */ - /* c3. TimeToWait */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_TimeToWait; - ie3->criticality = F1AP_Criticality_ignore; - ie3->value.present = F1AP_F1SetupFailureIEs__value_PR_TimeToWait; - ie3->value.choice.TimeToWait = F1AP_TimeToWait_v10s; - } - - /* optional */ - /* c4. CriticalityDiagnostics*/ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupFailureIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics; - ie4->criticality = F1AP_Criticality_ignore; - ie4->value.present = F1AP_F1SetupFailureIEs__value_PR_CriticalityDiagnostics; - asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.procedureCode, - F1AP_ProcedureCode_id_UEContextSetup); - asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.triggeringMessage, - F1AP_TriggeringMessage_initiating_message); - asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.procedureCriticality, - F1AP_Criticality_reject); - asn1cCallocOne(ie4->value.choice.CriticalityDiagnostics.transactionID, - 0); - } - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + uint8_t *buffer = NULL; + uint32_t len = 0; + /* Encode F1 Setup Failure */ + F1AP_F1AP_PDU_t *pdu = encode_f1ap_setup_failure(fail); + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { LOG_E(F1AP, "Failed to encode F1 setup failure\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } - - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 5d1f44dbdc..62da719aa0 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -337,25 +337,16 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint return 0; } -// SETUP FAILURE +/** + * @brief F1 Setup Failure handler (DU) + */ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - F1AP_F1SetupFailure_t *out; - F1AP_F1SetupFailureIEs_t *ie; - f1ap_setup_failure_t fail = {0}; - out = &pdu->choice.unsuccessfulOutcome->value.choice.F1SetupFailure; - /* Transaction ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out, F1AP_ProtocolIE_ID_id_TransactionID, true); - /* Cause */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out, - F1AP_ProtocolIE_ID_id_Cause, true); - - if(0) { - /* TimeToWait */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupFailureIEs_t, ie, out, - F1AP_ProtocolIE_ID_id_TimeToWait, true); + f1ap_setup_failure_t fail; + if (!decode_f1ap_setup_failure(pdu, &fail)) { + LOG_E(F1AP, "Failed to decode F1AP Setup Failure\n"); + return -1; } - f1_setup_failure(&fail); return 0; } From df62abca0c5f8b669edb0ab50d2af9adbaaa204b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 28 Aug 2024 23:43:10 +0200 Subject: [PATCH 31/73] Removed gNB_CU_name from f1ap_gnb_du_configuration_update_t * not defined in 9.2.1.8 of 3GPP TS 38.473 --- openair2/COMMON/f1ap_messages_types.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index f46fe3b55b..95ff676307 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -300,8 +300,6 @@ typedef struct f1ap_gnb_du_configuration_update_s { typedef struct f1ap_gnb_du_configuration_update_acknowledge_s { /// ulong transaction id uint64_t transaction_id; - /// string holding gNB_CU_name - char *gNB_CU_name; /// number of DU cells to activate uint16_t num_cells_to_activate; // 0< num_cells_to_activate <= 512; served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS]; From 9958e53cb17c1d8029e71a82d5689a4054f9195c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 9 Aug 2024 12:33:29 +0200 Subject: [PATCH 32/73] Add encoding/decoding library for F1AP gNB-DU Configuration Update (Interface Management) --- openair2/F1AP/lib/f1ap_interface_management.c | 321 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 7 + 2 files changed, 328 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 544b89893b..667fba31be 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -970,3 +970,324 @@ f1ap_setup_failure_t cp_f1ap_setup_failure(const f1ap_setup_failure_t *msg) cp.transaction_id = msg->transaction_id; return cp; } + +/* ==================================== + * F1AP gNB-DU Configuration Update + * ==================================== */ + +/** + * @brief F1 gNB-DU Configuration Update encoding (9.2.1.7 of 3GPP TS 38.473) + */ +F1AP_F1AP_PDU_t *encode_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc(1, sizeof(*pdu)); + AssertFatal(pdu != NULL, "out of memory\n"); + /* Create */ + /* 0. Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, initMsg); + initMsg->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate; + initMsg->criticality = F1AP_Criticality_reject; + initMsg->value.present = F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate; + F1AP_GNBDUConfigurationUpdate_t *out = &initMsg->value.choice.GNBDUConfigurationUpdate; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID; + ie1->value.choice.TransactionID = msg->transaction_id; + /* mandatory */ + /* c2. Served_Cells_To_Add */ + if (msg->num_cells_to_add > 0) { + AssertFatal(false, "code for adding cells not tested\n"); + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List; + + for (int j = 0; j < msg->num_cells_to_add; j++) { + const f1ap_served_cell_info_t *cell = &msg->cell_to_add[j].info; + const f1ap_gnb_du_system_info_t *sys_info = msg->cell_to_add[j].sys_info; + asn1cSequenceAdd(ie2->value.choice.Served_Cells_To_Add_List.list, + F1AP_Served_Cells_To_Add_ItemIEs_t, + served_cells_to_add_item_ies); + served_cells_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item; + served_cells_to_add_item_ies->criticality = F1AP_Criticality_reject; + served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item; + F1AP_Served_Cells_To_Add_Item_t *served_cells_to_add_item = + &served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item; + served_cells_to_add_item->served_Cell_Information = encode_served_cell_info(cell); + served_cells_to_add_item->gNB_DU_System_Information = encode_system_info(sys_info); + } + } + + /* mandatory */ + /* c3. Served_Cells_To_Modify */ + if (msg->num_cells_to_modify > 0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List; + for (int i = 0; i < msg->num_cells_to_modify; i++) { + const f1ap_served_cell_info_t *cell = &msg->cell_to_modify[i].info; + const f1ap_gnb_du_system_info_t *sys_info = msg->cell_to_modify[i].sys_info; + asn1cSequenceAdd(ie3->value.choice.Served_Cells_To_Modify_List.list, + F1AP_Served_Cells_To_Modify_ItemIEs_t, + served_cells_to_modify_item_ies); + served_cells_to_modify_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item; + served_cells_to_modify_item_ies->criticality = F1AP_Criticality_reject; + served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item; + F1AP_Served_Cells_To_Modify_Item_t *served_cells_to_modify_item = + &served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item; + + F1AP_NRCGI_t *oldNRCGI = &served_cells_to_modify_item->oldNRCGI; + const f1ap_plmn_t *old_plmn = &msg->cell_to_modify[i].old_plmn; + MCC_MNC_TO_PLMNID(old_plmn->mcc, old_plmn->mnc, old_plmn->mnc_digit_length, &oldNRCGI->pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(msg->cell_to_modify[i].old_nr_cellid, &oldNRCGI->nRCellIdentity); + + served_cells_to_modify_item->served_Cell_Information = encode_served_cell_info(cell); + served_cells_to_modify_item->gNB_DU_System_Information = encode_system_info(sys_info); + } + } + + /* mandatory */ + /* c4. Served_Cells_To_Delete */ + if (msg->num_cells_to_delete > 0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List; + AssertFatal(msg->num_cells_to_delete == 0, "code for deleting cells not tested\n"); + for (int i = 0; i < msg->num_cells_to_delete; i++) { + asn1cSequenceAdd(ie4->value.choice.Served_Cells_To_Delete_List.list, + F1AP_Served_Cells_To_Delete_ItemIEs_t, + served_cells_to_delete_item_ies); + served_cells_to_delete_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item; + served_cells_to_delete_item_ies->criticality = F1AP_Criticality_reject; + served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item; + F1AP_Served_Cells_To_Delete_Item_t *served_cells_to_delete_item = + &served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item; + F1AP_NRCGI_t *oldNRCGI = &served_cells_to_delete_item->oldNRCGI; + const f1ap_plmn_t *plmn = &msg->cell_to_delete[i].plmn; + MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &(oldNRCGI->pLMN_Identity)); + NR_CELL_ID_TO_BIT_STRING(msg->cell_to_delete[i].nr_cellid, &(oldNRCGI->nRCellIdentity)); + } + } + + /* optional */ + /* c5. GNB_DU_ID (integer value) */ + if (msg->gNB_DU_ID != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_gNB_DU_ID; + ie5->criticality = F1AP_Criticality_reject; + ie5->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_GNB_DU_ID; + asn_int642INTEGER(&ie5->value.choice.GNB_DU_ID, *msg->gNB_DU_ID); + } + + return pdu; +} + +/** + * @brief F1 gNB-DU Configuration Update decoding (9.2.1.7 of 3GPP TS 38.473) + */ +bool decode_f1ap_du_configuration_update(const F1AP_F1AP_PDU_t *pdu, f1ap_gnb_du_configuration_update_t *out) +{ + /* Check presence of message type */ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage); + _F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_gNBDUConfigurationUpdate); + _F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate); + /* Check presence of mandatory IEs */ + F1AP_GNBDUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate; + F1AP_GNBDUConfigurationUpdateIEs_t *ie; + /* Check mandatory IEs */ + F1AP_LIB_FIND_IE(F1AP_GNBDUConfigurationUpdateIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + AssertError(in->protocolIEs.list.array[i] != NULL, return false, "in->protocolIEs.list.array[i] is NULL"); + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: { + out->transaction_id = ie->value.choice.TransactionID; + } break; + case F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List: { + /* Served Cells To Add List */ + AssertError(out->num_cells_to_add > 0, return false, "at least 1 cell to add shall to be present"); + out->num_cells_to_add = ie->value.choice.Served_Cells_To_Add_List.list.count; + for (int i = 0; i < out->num_cells_to_add; i++) { + F1AP_Served_Cells_To_Add_Item_t *served_cells_item = + &((F1AP_Served_Cells_To_Add_ItemIEs_t *)ie->value.choice.Served_Cells_To_Add_List.list.array[i]) + ->value.choice.Served_Cells_To_Add_Item; + /* Served Cell Information (M) */ + if (!decode_served_cell_info(&served_cells_item->served_Cell_Information, &out->cell_to_add[i].info)) + return false; + /* gNB-DU System Information */ + if (served_cells_item->gNB_DU_System_Information != NULL) { + out->cell_to_add[i].sys_info = calloc_or_fail(1, sizeof(*out->cell_to_add[i].sys_info)); + decode_system_info(served_cells_item->gNB_DU_System_Information, out->cell_to_add[i].sys_info); + } + } + } break; + case F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List: { + /* Served Cells To Modify List (O) */ + out->num_cells_to_modify = ie->value.choice.Served_Cells_To_Modify_List.list.count; + AssertError(out->num_cells_to_modify > 0, return false, "at least 1 cell to modify shall to be present"); + for (int i = 0; i < out->num_cells_to_modify; i++) { + /* Served Cells To Modify List item (count >= 1) */ + F1AP_Served_Cells_To_Modify_Item_t *served_cells_item = + &((F1AP_Served_Cells_To_Modify_ItemIEs_t *)ie->value.choice.Served_Cells_To_Modify_List.list.array[i]) + ->value.choice.Served_Cells_To_Modify_Item; + /* Old NR CGI (M) */ + F1AP_NRCGI_t *oldNRCGI = &served_cells_item->oldNRCGI; + f1ap_plmn_t *old_plmn = &out->cell_to_modify[i].old_plmn; + TBCD_TO_MCC_MNC(&(oldNRCGI->pLMN_Identity), old_plmn->mcc, old_plmn->mnc, old_plmn->mnc_digit_length); + /* Old NR CGI Cell ID */ + BIT_STRING_TO_NR_CELL_IDENTITY(&oldNRCGI->nRCellIdentity, out->cell_to_modify[i].old_nr_cellid); + /* Served Cell Information (M) */ + if (!decode_served_cell_info(&served_cells_item->served_Cell_Information, &out->cell_to_modify[i].info)) + return false; + /* gNB-DU System Information (O) */ + if (served_cells_item->gNB_DU_System_Information != NULL) { + out->cell_to_modify[i].sys_info = calloc_or_fail(1, sizeof(*out->cell_to_modify[i].sys_info)); + decode_system_info(served_cells_item->gNB_DU_System_Information, out->cell_to_modify[i].sys_info); + } + } + } break; + case F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List: { + /* Served Cells To Delete List */ + out->num_cells_to_delete = ie->value.choice.Served_Cells_To_Delete_List.list.count; + AssertError(out->num_cells_to_delete > 0, return false, "at least 1 cell to delete shall to be present"); + for (int i = 0; i < out->num_cells_to_delete; i++) { + F1AP_Served_Cells_To_Delete_Item_t *served_cells_item = + &((F1AP_Served_Cells_To_Delete_ItemIEs_t *)ie->value.choice.Served_Cells_To_Delete_List.list.array[i]) + ->value.choice.Served_Cells_To_Delete_Item; + F1AP_NRCGI_t *oldNRCGI = &served_cells_item->oldNRCGI; + f1ap_plmn_t *plmn = &out->cell_to_delete[i].plmn; + /* Old NR CGI (M) */ + TBCD_TO_MCC_MNC(&(oldNRCGI->pLMN_Identity), plmn->mcc, plmn->mnc, plmn->mnc_digit_length); + // NR cellID + BIT_STRING_TO_NR_CELL_IDENTITY(&oldNRCGI->nRCellIdentity, out->cell_to_delete[i].nr_cellid); + } + } break; + case F1AP_ProtocolIE_ID_id_Cells_Status_List: + /* Cells Status List (O) */ + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_Cells_Status_List is not supported"); + break; + case F1AP_ProtocolIE_ID_id_Dedicated_SIDelivery_NeededUE_List: + /* Dedicated SI Delivery Needed UE List (O) */ + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_Dedicated_SIDelivery_NeededUE_List is not supported"); + break; + case F1AP_ProtocolIE_ID_id_gNB_DU_ID: + /* gNB-DU ID (O)*/ + asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, out->gNB_DU_ID); + break; + case F1AP_ProtocolIE_ID_id_GNB_DU_TNL_Association_To_Remove_List: + /* Cells Status List (O) */ + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id_GNB_DU_TNL_Association_To_Remove_List is not supported"); + break; + } + } + return true; +} + +void free_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg) +{ + free(msg->gNB_DU_ID); + for (int i = 0; i < msg->num_cells_to_add; i++) { + free_f1ap_cell(&msg->cell_to_add[i].info, msg->cell_to_add[i].sys_info); + } + for (int i = 0; i < msg->num_cells_to_modify; i++) { + free_f1ap_cell(&msg->cell_to_modify[i].info, msg->cell_to_modify[i].sys_info); + } +} + +/** + * @brief F1 gNB-DU Configuration Update check + */ +bool eq_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *a, const f1ap_gnb_du_configuration_update_t *b) +{ + if (a->gNB_DU_ID != NULL && b->gNB_DU_ID != NULL) + _F1_EQ_CHECK_LONG(*a->gNB_DU_ID, *b->gNB_DU_ID); + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + /* to add */ + _F1_EQ_CHECK_INT(a->num_cells_to_add, b->num_cells_to_add); + for (int i = 0; i < a->num_cells_to_add; i++) { + if (!eq_f1ap_cell_info(&a->cell_to_add[i].info, &b->cell_to_add[i].info)) + return false; + if (a->cell_to_add[i].sys_info && b->cell_to_add[i].sys_info) { + if (!eq_f1ap_sys_info(a->cell_to_add[i].sys_info, b->cell_to_add[i].sys_info)) + return false; + } + } + /* to delete */ + _F1_EQ_CHECK_INT(a->num_cells_to_delete, b->num_cells_to_delete); + for (int i = 0; i < a->num_cells_to_delete; i++) { + _F1_EQ_CHECK_LONG(a->cell_to_delete[i].nr_cellid, b->cell_to_delete[i].nr_cellid); + if (!eq_f1ap_plmn(&a->cell_to_delete[i].plmn, &b->cell_to_delete[i].plmn)) + return false; + } + /* to modify */ + _F1_EQ_CHECK_INT(a->num_cells_to_modify, b->num_cells_to_modify); + for (int i = 0; i < a->num_cells_to_modify; i++) { + if (!eq_f1ap_cell_info(&a->cell_to_modify[i].info, &b->cell_to_modify[i].info)) + return false; + if (a->cell_to_modify[i].sys_info && b->cell_to_modify[i].sys_info) { + if (!eq_f1ap_sys_info(a->cell_to_modify[i].sys_info, b->cell_to_modify[i].sys_info)) + return false; + } + } + return true; +} + +/** + * @brief F1 gNB-DU Configuration Update deep copy + */ +f1ap_gnb_du_configuration_update_t cp_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg) +{ + f1ap_gnb_du_configuration_update_t cp = {0}; + /* gNB_DU_ID */ + if (msg->gNB_DU_ID != NULL) { + cp.gNB_DU_ID = calloc_or_fail(1, sizeof(*cp.gNB_DU_ID)); + *cp.gNB_DU_ID = *msg->gNB_DU_ID; + } + /* transaction_id */ + cp.transaction_id = msg->transaction_id; + /* to add */ + cp.num_cells_to_add = msg->num_cells_to_add; + /* to delete */ + cp.num_cells_to_delete = msg->num_cells_to_delete; + for (int i = 0; i < cp.num_cells_to_delete; i++) { + cp.cell_to_delete[i].nr_cellid = msg->cell_to_delete[i].nr_cellid; + cp.cell_to_delete[i].plmn = msg->cell_to_delete[i].plmn; + } + /* to modify */ + cp.num_cells_to_modify = msg->num_cells_to_modify; + for (int i = 0; i < cp.num_cells_to_modify; i++) { + cp.cell_to_modify[i].info = msg->cell_to_modify[i].info; + f1ap_served_cell_info_t *info = &cp.cell_to_modify[i].info; + if (info->measurement_timing_config_len > 0) { + info->measurement_timing_config = malloc_or_fail(info->measurement_timing_config_len * sizeof(*info->measurement_timing_config)); + for (int j = 0; j < info->measurement_timing_config_len; j++) + info->measurement_timing_config[j] = msg->cell_to_modify[i].info.measurement_timing_config[j]; + } + /* TAC */ + info->tac = calloc_or_fail(1, sizeof(*info->tac)); + *info->tac = *msg->cell_to_modify[i].info.tac; + /* System information */ + cp.cell_to_modify[i].sys_info = malloc_or_fail(sizeof(*cp.cell_to_modify[i].sys_info)); + f1ap_gnb_du_system_info_t *sys_info = cp.cell_to_modify[i].sys_info; + if (msg->cell_to_modify[i].sys_info->mib_length > 0) { + sys_info->mib_length = msg->cell_to_modify[i].sys_info->mib_length; + sys_info->mib = calloc_or_fail(msg->cell_to_modify[i].sys_info->mib_length, sizeof(*sys_info->mib)); + for (int j = 0; j < sys_info->mib_length; j++) + sys_info->mib[j] = msg->cell_to_modify[i].sys_info->mib[j]; + } + if (msg->cell_to_modify[i].sys_info->sib1_length > 0) { + sys_info->sib1_length = msg->cell_to_modify[i].sys_info->sib1_length; + sys_info->sib1 = calloc_or_fail(msg->cell_to_modify[i].sys_info->sib1_length, sizeof(*sys_info->sib1)); + for (int j = 0; j < sys_info->sib1_length; j++) + sys_info->sib1[j] = msg->cell_to_modify[i].sys_info->sib1[j]; + } + } + return cp; +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index ca0b7df491..aa7991488b 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -46,4 +46,11 @@ bool decode_f1ap_setup_failure(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_failu bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b); f1ap_setup_failure_t cp_f1ap_setup_failure(const f1ap_setup_failure_t *msg); +/* F1 gNB-DU Configuration Update */ +struct F1AP_F1AP_PDU *encode_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg); +bool decode_f1ap_du_configuration_update(const struct F1AP_F1AP_PDU *pdu, f1ap_gnb_du_configuration_update_t *out); +bool eq_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *a, const f1ap_gnb_du_configuration_update_t *b); +f1ap_gnb_du_configuration_update_t cp_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg); +void free_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg); + #endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ From 2cc50832d11a97fa1da01c0259a9c4125e010e17 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 9 Aug 2024 12:36:47 +0200 Subject: [PATCH 33/73] Add test for F1AP gNB-DU Configuration Update enc/dec library --- openair2/F1AP/tests/f1ap_lib_test.c | 75 +++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 42f07e4c2a..6ccc814cfc 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -357,6 +357,80 @@ static void test_f1ap_setup_failure(void) AssertFatal(ret, "eq_f1ap_setup_failure(): copied message doesn't match\n"); } +/** + * @brief Test F1 gNB-DU Configuration Update + */ +static void test_f1ap_du_configuration_update(void) +{ + /* sys_info */ + uint8_t *mib = calloc(3, sizeof(uint8_t)); + uint8_t *sib1 = calloc(3, sizeof(uint8_t)); + f1ap_gnb_du_system_info_t sys_info = { + .mib_length = 3, + .mib = mib, + .sib1_length = 3, + .sib1 = sib1, + }; + /* measurement_timing_information modify */ + char *s = "1"; + int measurement_timing_config_len = strlen(s) + 1; + uint8_t *measurement_timing_config_mod = calloc(measurement_timing_config_len, sizeof(uint8_t)); + AssertFatal(measurement_timing_config_mod != NULL, "out of memory\n"); + memcpy((void *)measurement_timing_config_mod, s, measurement_timing_config_len); + /* TAC modify */ + uint32_t *tac = calloc(1, sizeof(uint32_t)); + AssertFatal(tac != NULL, "out of memory\n"); + *tac = 456; + /* info modify */ + f1ap_served_cell_info_t info = { + .mode = F1AP_MODE_TDD, + .tdd.freqinfo.arfcn = 640000, + .tdd.freqinfo.band = 78, + .tdd.tbw.nrb = 66, + .tdd.tbw.scs = 1, + .measurement_timing_config_len = measurement_timing_config_len, + .measurement_timing_config = measurement_timing_config_mod, + .nr_cellid = 123456, + .plmn.mcc = 1, + .plmn.mnc = 1, + .plmn.mnc_digit_length = 3, + .tac = tac, + }; + /* create message */ + f1ap_gnb_du_configuration_update_t orig = { + .transaction_id = 2, + .num_cells_to_modify = 1, + .cell_to_modify[0].info = info, + .num_cells_to_delete = 0, + .cell_to_delete[0].nr_cellid = 1234UL, + .cell_to_delete[0].plmn.mcc = 1, + .cell_to_delete[0].plmn.mnc = 1, + .cell_to_delete[0].plmn.mnc_digit_length = 3, + }; + orig.cell_to_modify[0].sys_info = calloc(1, sizeof(*orig.cell_to_modify[0].sys_info)); + AssertFatal(orig.cell_to_modify[0].sys_info != NULL, "out of memory\n"); + *orig.cell_to_modify[0].sys_info = sys_info; + + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_gnb_du_configuration_update_t decoded = {0}; + bool ret = decode_f1ap_du_configuration_update(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_f1ap_du_configuration_update(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n"); + free_f1ap_du_configuration_update(&decoded); + + f1ap_gnb_du_configuration_update_t cp = cp_f1ap_du_configuration_update(&orig); + ret = eq_f1ap_du_configuration_update(&orig, &cp); + AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n"); + free_f1ap_du_configuration_update(&cp); + free_f1ap_du_configuration_update(&orig); +} + int main() { test_initial_ul_rrc_message_transfer(); @@ -365,5 +439,6 @@ int main() test_f1ap_setup_request(); test_f1ap_setup_response(); test_f1ap_setup_failure(); + test_f1ap_du_configuration_update(); return 0; } From 07da84ede2e65e1f606d68f88db6fc6d68c5bb19 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:53:02 +0200 Subject: [PATCH 34/73] Use F1 gNB-DU Configuration Update lib in stack --- openair2/F1AP/f1ap_common.h | 2 - openair2/F1AP/f1ap_cu_interface_management.c | 350 +----------------- openair2/F1AP/f1ap_du_interface_management.c | 263 +------------ openair2/F1AP/f1ap_du_interface_management.h | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 47 +-- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 36 +- openair2/RRC/NR/rrc_gNB_du.c | 3 +- 7 files changed, 40 insertions(+), 663 deletions(-) diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h index 13f1d8f53b..83781484c7 100644 --- a/openair2/F1AP/f1ap_common.h +++ b/openair2/F1AP/f1ap_common.h @@ -411,8 +411,6 @@ typedef struct f1ap_cudu_inst_s { instance_t gtpInst; } f1ap_cudu_inst_t; -static const int nrb_lut[29] = {11, 18, 24, 25, 31, 32, 38, 51, 52, 65, 66, 78, 79, 93, 106, 107, 121, 132, 133, 135, 160, 162, 189, 216, 217, 245, 264, 270, 273}; - uint8_t F1AP_get_next_transaction_identifier(instance_t mod_idP, instance_t cu_mod_idP); f1ap_cudu_inst_t *getCxt(instance_t instanceP); diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 49f887ad49..e6064c1502 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -48,32 +48,6 @@ int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack AssertFatal(1 == 0, "Not implemented yet\n"); } -static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, int max_nssai) -{ - if (plmn->iE_Extensions == NULL) - return 0; - - const F1AP_ProtocolExtensionContainer_10696P34_t *p = (F1AP_ProtocolExtensionContainer_10696P34_t *)plmn->iE_Extensions; - if (p->list.count == 0) - return 0; - - const F1AP_ServedPLMNs_ItemExtIEs_t *splmn = p->list.array[0]; - DevAssert(splmn->id == F1AP_ProtocolIE_ID_id_TAISliceSupportList); - DevAssert(splmn->extensionValue.present == F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList); - const F1AP_SliceSupportList_t *ssl = &splmn->extensionValue.choice.SliceSupportList; - AssertFatal(ssl->list.count <= max_nssai, "cannot handle more than 16 slices\n"); - for (int s = 0; s < ssl->list.count; ++s) { - const F1AP_SliceSupportItem_t *sl = ssl->list.array[s]; - nssai_t *n = &nssai[s]; - OCTET_STRING_TO_INT8(&sl->sNSSAI.sST, n->sst); - n->sd = 0xffffff; - if (sl->sNSSAI.sD != NULL) - OCTET_STRING_TO_INT24(sl->sNSSAI.sD, n->sd); - } - - return ssl->list.count; -} - /** * @brief F1AP Setup Request decoding (9.2.1.4 of 3GPP TS 38.473) and transfer to RRC */ @@ -146,324 +120,30 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t * return 0; } -/* - gNB-DU Configuration Update -*/ - +/** + * @brief Decode and send F1 gNB-DU Configuration Update message to RRC + */ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - LOG_D(F1AP, "CU_handle_gNB_DU_CONFIGURATION_UPDATE\n"); - F1AP_GNBDUConfigurationUpdate_t *container; - F1AP_GNBDUConfigurationUpdateIEs_t *ie; - int i = 0; + LOG_D(F1AP, "[SCTP %d] CU_handle_gNB_DU_CONFIGURATION_UPDATE\n", assoc_id); DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate; - /* gNB DU Configuration Update == Non UE-related procedure -> stream 0 */ if (stream != 0) { LOG_W(F1AP, "[SCTP %d] Received f1 setup request on stream != 0 (%d)\n", assoc_id, stream); } - + /* Decode */ + f1ap_gnb_du_configuration_update_t msg = {0}; + if (!decode_f1ap_du_configuration_update(pdu, &msg)) { + LOG_E(F1AP, "cannot decode F1AP gNB-DU Configuration Update\n"); + free_f1ap_du_configuration_update(&msg); + return -1; + } + /* Send to RRC */ MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE); message_p->ittiMsgHeader.originInstance = assoc_id; - f1ap_gnb_du_configuration_update_t *req = &F1AP_GNB_DU_CONFIGURATION_UPDATE(message_p); - - /* 3GPP TS 38.473 Transaction ID*/ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true); - req->transaction_id = ie->value.choice.TransactionID; - LOG_D(F1AP, "req->transaction_id %lu \n", req->transaction_id); - - /* 3GPP TS 38.473 Served Cells To Add List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, - ie, - container, - F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List, - false); - - if (ie != NULL) { - req->num_cells_to_add = ie->value.choice.Served_Cells_To_Add_List.list.count; - LOG_D(F1AP, "req->num_cells_to_add %d \n", req->num_cells_to_add); - - for (i = 0; i < req->num_cells_to_add; i++) { - F1AP_Served_Cells_To_Add_Item_t *served_cells_item = - &((F1AP_Served_Cells_To_Add_ItemIEs_t *)ie->value.choice.Served_Cells_To_Add_List.list.array[i]) - ->value.choice.Served_Cells_To_Add_Item; - F1AP_Served_Cell_Information_t *servedCellInformation = &served_cells_item->served_Cell_Information; - /* tac */ - if (servedCellInformation->fiveGS_TAC) { - req->cell_to_add[i].info.tac = malloc(sizeof(*req->cell_to_add[i].info.tac)); - AssertFatal(req->cell_to_add[i].info.tac != NULL, "out of memory\n"); - OCTET_STRING_TO_INT24(servedCellInformation->fiveGS_TAC, *req->cell_to_add[i].info.tac); - LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell_to_add[i].info.tac); - } - - /* - nRCGI */ - TBCD_TO_MCC_MNC(&(servedCellInformation->nRCGI.pLMN_Identity), - req->cell_to_add[i].info.plmn.mcc, - req->cell_to_add[i].info.plmn.mnc, - req->cell_to_add[i].info.plmn.mnc_digit_length); - // NR cellID - BIT_STRING_TO_NR_CELL_IDENTITY(&servedCellInformation->nRCGI.nRCellIdentity, req->cell_to_add[i].info.nr_cellid); - LOG_D(F1AP, - "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", - assoc_id, - req->cell_to_add[i].info.plmn.mcc, - req->cell_to_add[i].info.plmn.mnc, - (long long unsigned int)req->cell_to_add[i].info.nr_cellid); - - /* - nRPCI */ - req->cell_to_add[i].info.nr_pci = servedCellInformation->nRPCI; - LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell_to_add[i].info.nr_pci); - - AssertFatal(servedCellInformation->servedPLMNs.list.count == 1, "only one PLMN handled\n"); - req->cell_to_add[i].info.num_ssi = - read_slice_info(servedCellInformation->servedPLMNs.list.array[0], req->cell_to_add[i].info.nssai, 16); - - // FDD Cells - if (servedCellInformation->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_fDD) { - req->cell_to_add[i].info.mode = F1AP_MODE_FDD; - f1ap_fdd_info_t *FDDs = &req->cell_to_add[i].info.fdd; - F1AP_FDD_Info_t *fDD_Info = servedCellInformation->nR_Mode_Info.choice.fDD; - FDDs->ul_freqinfo.arfcn = fDD_Info->uL_NRFreqInfo.nRARFCN; - AssertFatal(fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n"); - for (int f = 0; f < fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count; f++) { - F1AP_FreqBandNrItem_t *FreqItem = fDD_Info->uL_NRFreqInfo.freqBandListNr.list.array[f]; - FDDs->ul_freqinfo.band = FreqItem->freqBandIndicatorNr; - AssertFatal(FreqItem->supportedSULBandList.list.count == 0, "cannot handle SUL bands!\n"); - } - FDDs->dl_freqinfo.arfcn = fDD_Info->dL_NRFreqInfo.nRARFCN; - int dlBands = fDD_Info->dL_NRFreqInfo.freqBandListNr.list.count; - AssertFatal(dlBands == 0, "cannot handled more than one frequency band\n"); - for (int dlB = 0; dlB < dlBands; dlB++) { - F1AP_FreqBandNrItem_t *FreqItem = fDD_Info->dL_NRFreqInfo.freqBandListNr.list.array[dlB]; - FDDs->dl_freqinfo.band = FreqItem->freqBandIndicatorNr; - int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count; - AssertFatal(num_available_supported_SULBands == 0, "cannot handle SUL bands!\n"); - } - FDDs->ul_tbw.scs = fDD_Info->uL_Transmission_Bandwidth.nRSCS; - FDDs->ul_tbw.nrb = nrb_lut[fDD_Info->uL_Transmission_Bandwidth.nRNRB]; - FDDs->dl_tbw.scs = fDD_Info->dL_Transmission_Bandwidth.nRSCS; - FDDs->dl_tbw.nrb = nrb_lut[fDD_Info->dL_Transmission_Bandwidth.nRNRB]; - } else if (servedCellInformation->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_tDD) { - req->cell_to_add[i].info.mode = F1AP_MODE_TDD; - f1ap_tdd_info_t *TDDs = &req->cell_to_add[i].info.tdd; - F1AP_TDD_Info_t *tDD_Info = servedCellInformation->nR_Mode_Info.choice.tDD; - TDDs->freqinfo.arfcn = tDD_Info->nRFreqInfo.nRARFCN; - AssertFatal(tDD_Info->nRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n"); - for (int f = 0; f < tDD_Info->nRFreqInfo.freqBandListNr.list.count; f++) { - struct F1AP_FreqBandNrItem *FreqItem = tDD_Info->nRFreqInfo.freqBandListNr.list.array[f]; - TDDs->freqinfo.band = FreqItem->freqBandIndicatorNr; - int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count; - AssertFatal(num_available_supported_SULBands == 0, "cannot hanlde SUL bands!\n"); - } - TDDs->tbw.scs = tDD_Info->transmission_Bandwidth.nRSCS; - TDDs->tbw.nrb = nrb_lut[tDD_Info->transmission_Bandwidth.nRNRB]; - } else { - AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present); - } - - /* MeasurementConfig */ - if (servedCellInformation->measurementTimingConfiguration.size > 0) - req->cell_to_add[i].info.measurement_timing_config = - cp_octet_string(&servedCellInformation->measurementTimingConfiguration, - &req->cell_to_add[i].info.measurement_timing_config_len); - - struct F1AP_GNB_DU_System_Information *DUsi = served_cells_item->gNB_DU_System_Information; - // System Information - req->cell_to_add[i].sys_info = calloc(1, sizeof(*req->cell_to_add[i].sys_info)); - AssertFatal(req->cell_to_add[i].sys_info != NULL, "out of memory\n"); - f1ap_gnb_du_system_info_t *sys_info = req->cell_to_add[i].sys_info; - /* mib */ - sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char)); - memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size); - sys_info->mib_length = DUsi->mIB_message.size; - /* sib1 */ - sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char)); - memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); - sys_info->sib1_length = DUsi->sIB1_message.size; - } - } else { - req->num_cells_to_add = 0; - } - /* 3GPP TS 38.473 Served Cells To Modify List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, - ie, - container, - F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List, - false); - - if (ie) { - req->num_cells_to_modify = ie->value.choice.Served_Cells_To_Modify_List.list.count; - LOG_D(F1AP, "req->num_cells_to_modify %d \n", req->num_cells_to_modify); - - for (i = 0; i < req->num_cells_to_modify; i++) { - F1AP_Served_Cells_To_Modify_Item_t *served_cells_item = - &((F1AP_Served_Cells_To_Modify_ItemIEs_t *)ie->value.choice.Served_Cells_To_Modify_List.list.array[i]) - ->value.choice.Served_Cells_To_Modify_Item; - - /* OLD NRCGI */ - TBCD_TO_MCC_MNC(&(served_cells_item->oldNRCGI.pLMN_Identity), - req->cell_to_modify[i].old_plmn.mcc, - req->cell_to_modify[i].old_plmn.mnc, - req->cell_to_modify[i].old_plmn.mnc_digit_length); - - BIT_STRING_TO_NR_CELL_IDENTITY(&served_cells_item->oldNRCGI.nRCellIdentity, req->cell_to_modify[i].old_nr_cellid); - - F1AP_Served_Cell_Information_t *servedCellInformation = &served_cells_item->served_Cell_Information; - /* SERVED CELL INFORMATION*/ - /* tac */ - if (servedCellInformation->fiveGS_TAC) { - req->cell_to_modify[i].info.tac = malloc(sizeof(*req->cell_to_modify[i].info.tac)); - AssertFatal(req->cell_to_modify[i].info.tac != NULL, "out of memory\n"); - OCTET_STRING_TO_INT24(servedCellInformation->fiveGS_TAC, *req->cell_to_modify[i].info.tac); - LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell_to_modify[i].info.tac); - } - - /* - nRCGI */ - TBCD_TO_MCC_MNC(&(servedCellInformation->nRCGI.pLMN_Identity), - req->cell_to_modify[i].info.plmn.mcc, - req->cell_to_modify[i].info.plmn.mnc, - req->cell_to_modify[i].info.plmn.mnc_digit_length); - // NR cellID - BIT_STRING_TO_NR_CELL_IDENTITY(&servedCellInformation->nRCGI.nRCellIdentity, req->cell_to_modify[i].info.nr_cellid); - LOG_D(F1AP, - "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", - assoc_id, - req->cell_to_modify[i].info.plmn.mcc, - req->cell_to_modify[i].info.plmn.mnc, - (long long unsigned int)req->cell_to_modify[i].info.nr_cellid); - - /* - nRPCI */ - req->cell_to_modify[i].info.nr_pci = servedCellInformation->nRPCI; - LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell_to_modify[i].info.nr_pci); - - // FDD Cells - if (servedCellInformation->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_fDD) { - req->cell_to_modify[i].info.mode = F1AP_MODE_FDD; - f1ap_fdd_info_t *FDDs = &req->cell_to_modify[i].info.fdd; - F1AP_FDD_Info_t *fDD_Info = servedCellInformation->nR_Mode_Info.choice.fDD; - FDDs->ul_freqinfo.arfcn = fDD_Info->uL_NRFreqInfo.nRARFCN; - AssertFatal(fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n"); - for (int f = 0; f < fDD_Info->uL_NRFreqInfo.freqBandListNr.list.count; f++) { - F1AP_FreqBandNrItem_t *FreqItem = fDD_Info->uL_NRFreqInfo.freqBandListNr.list.array[f]; - FDDs->ul_freqinfo.band = FreqItem->freqBandIndicatorNr; - AssertFatal(FreqItem->supportedSULBandList.list.count == 0, "cannot handle SUL bands!\n"); - } - FDDs->dl_freqinfo.arfcn = fDD_Info->dL_NRFreqInfo.nRARFCN; - int dlBands = fDD_Info->dL_NRFreqInfo.freqBandListNr.list.count; - AssertFatal(dlBands == 0, "cannot handled more than one frequency band\n"); - for (int dlB = 0; dlB < dlBands; dlB++) { - F1AP_FreqBandNrItem_t *FreqItem = fDD_Info->dL_NRFreqInfo.freqBandListNr.list.array[dlB]; - FDDs->dl_freqinfo.band = FreqItem->freqBandIndicatorNr; - int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count; - AssertFatal(num_available_supported_SULBands == 0, "cannot handle SUL bands!\n"); - } - FDDs->ul_tbw.scs = fDD_Info->uL_Transmission_Bandwidth.nRSCS; - FDDs->ul_tbw.nrb = nrb_lut[fDD_Info->uL_Transmission_Bandwidth.nRNRB]; - FDDs->dl_tbw.scs = fDD_Info->dL_Transmission_Bandwidth.nRSCS; - FDDs->dl_tbw.nrb = nrb_lut[fDD_Info->dL_Transmission_Bandwidth.nRNRB]; - } else if (servedCellInformation->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_tDD) { - req->cell_to_modify[i].info.mode = F1AP_MODE_TDD; - f1ap_tdd_info_t *TDDs = &req->cell_to_modify[i].info.tdd; - F1AP_TDD_Info_t *tDD_Info = servedCellInformation->nR_Mode_Info.choice.tDD; - TDDs->freqinfo.arfcn = tDD_Info->nRFreqInfo.nRARFCN; - AssertFatal(tDD_Info->nRFreqInfo.freqBandListNr.list.count == 1, "cannot handle more than one frequency band\n"); - for (int f = 0; f < tDD_Info->nRFreqInfo.freqBandListNr.list.count; f++) { - struct F1AP_FreqBandNrItem *FreqItem = tDD_Info->nRFreqInfo.freqBandListNr.list.array[f]; - TDDs->freqinfo.band = FreqItem->freqBandIndicatorNr; - int num_available_supported_SULBands = FreqItem->supportedSULBandList.list.count; - AssertFatal(num_available_supported_SULBands == 0, "cannot hanlde SUL bands!\n"); - } - TDDs->tbw.scs = tDD_Info->transmission_Bandwidth.nRSCS; - TDDs->tbw.nrb = nrb_lut[tDD_Info->transmission_Bandwidth.nRNRB]; - } else { - AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present); - } - - /* MeasurementConfig */ - if (servedCellInformation->measurementTimingConfiguration.size > 0) - req->cell_to_modify[i].info.measurement_timing_config = - cp_octet_string(&servedCellInformation->measurementTimingConfiguration, - &req->cell_to_modify[i].info.measurement_timing_config_len); - - /*gNB DU SYSTEM INFORMATION */ - struct F1AP_GNB_DU_System_Information *DUsi = served_cells_item->gNB_DU_System_Information; - if (DUsi != NULL) { - // System Information - req->cell_to_modify[i].sys_info = calloc(1, sizeof(*req->cell_to_modify[i].sys_info)); - AssertFatal(req->cell_to_modify[i].sys_info != NULL, "out of memory\n"); - f1ap_gnb_du_system_info_t *sys_info = req->cell_to_modify[i].sys_info; - /* mib */ - sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char)); - AssertFatal(req->cell_to_modify[i].sys_info->mib != NULL, "out of memory\n"); - memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size); - sys_info->mib_length = DUsi->mIB_message.size; - - /* sib1 */ - sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char)); - AssertFatal(req->cell_to_modify[i].sys_info->sib1 != NULL, "out of memory\n"); - memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); - sys_info->sib1_length = DUsi->sIB1_message.size; - } - } - } else { - req->num_cells_to_modify = 0; - } - - /* 3GPP TS 38.473 Served Cells To Delete List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, - ie, - container, - F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List, - false); - if (ie) { - req->num_cells_to_delete = ie->value.choice.Served_Cells_To_Delete_List.list.count; - LOG_D(F1AP, "req->num_cells_to_delete %d \n", req->num_cells_to_delete); - - for (i = 0; i < req->num_cells_to_delete; i++) { - F1AP_Served_Cells_To_Delete_Item_t *served_cells_item = - &((F1AP_Served_Cells_To_Delete_ItemIEs_t *)ie->value.choice.Served_Cells_To_Delete_List.list.array[i]) - ->value.choice.Served_Cells_To_Delete_Item; - /* - Old nRCGI */ - TBCD_TO_MCC_MNC(&(served_cells_item->oldNRCGI.pLMN_Identity), - req->cell_to_delete[i].plmn.mcc, - req->cell_to_delete[i].plmn.mnc, - req->cell_to_delete[i].plmn.mnc_digit_length); - // NR cellID - BIT_STRING_TO_NR_CELL_IDENTITY(&served_cells_item->oldNRCGI.nRCellIdentity, req->cell_to_delete[i].nr_cellid); - LOG_D(F1AP, - "[SCTP %d] Received nRCGI to delete: MCC %d, MNC %d, CELL_ID %llu\n", - assoc_id, - req->cell_to_delete[i].plmn.mcc, - req->cell_to_delete[i].plmn.mnc, - (long long unsigned int)req->cell_to_delete[i].nr_cellid); - } - } else { - req->num_cells_to_delete = 0; - } - - /* 3GPP TS 38.473 Cells Status List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cells_Status_List, false); - - /* 3GPP TS 38.473 Dedicated SI Delivery Needed UE List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, - ie, - container, - F1AP_ProtocolIE_ID_id_Dedicated_SIDelivery_NeededUE_List, - false); - - /* 3GPP TS 38.473 gNB-DU ID */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_ID, false); - if (ie != NULL) - asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, req->gNB_DU_ID); - - /* 3GPP TS 38.473 gNB-DU TNL Association To Remove List */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_GNBDUConfigurationUpdateIEs_t, - ie, - container, - F1AP_ProtocolIE_ID_id_GNB_DU_TNL_Association_To_Remove_List, - false); - + f1ap_gnb_du_configuration_update_t *req = &F1AP_GNB_DU_CONFIGURATION_UPDATE(message_p); // RRC thread will free it + *req = msg; // copy F1 message to ITTI + free_f1ap_du_configuration_update(&msg); LOG_D(F1AP, "Sending F1AP_GNB_DU_CONFIGURATION_UPDATE ITTI message \n"); itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); return 0; diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 62da719aa0..6104757816 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -41,17 +41,6 @@ #include "GNB_APP/gnb_paramdef.h" -int to_NRNRB(int nrb) { - for (int i=0; inr_pci; // int 0..1007 - - /* - fiveGS_TAC */ - if (c->tac != NULL) { - uint32_t tac = htonl(*c->tac); - asn1cCalloc(scell_info.fiveGS_TAC, netOrder); - OCTET_STRING_fromBuf(netOrder, ((char *)&tac) + 1, 3); - } - - /* - Configured_EPS_TAC */ - if (0) { - scell_info.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t)); - OCTET_STRING_fromBuf(scell_info.configured_EPS_TAC, "2", 2); - } - - /* servedPLMN information */ - asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item); - MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity); - - F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info; - if (c->num_ssi > 0) { - F1AP_ProtocolExtensionContainer_10696P34_t *p = calloc(1, sizeof(*p)); - servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p; - asn1cSequenceAdd(p->list, F1AP_ServedPLMNs_ItemExtIEs_t, served_plmns_itemExtIEs); - served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore; - served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList; - served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList; - F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList; - - for (int s = 0; s < c->num_ssi; s++) { - asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice); - const nssai_t *nssai = &c->nssai[s]; - INT8_TO_OCTET_STRING(nssai->sst, &slice->sNSSAI.sST); - if (nssai->sd != 0xffffff) { - asn1cCalloc(slice->sNSSAI.sD, tmp); - INT24_TO_OCTET_STRING(nssai->sd, tmp); - } - } - } - - if (c->mode == F1AP_MODE_FDD) { // FDD - const f1ap_fdd_info_t *fdd = &c->fdd; - nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; - asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); - /* FDD.1.1 UL NRFreqInfo ARFCN */ - fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn; // Integer - - /* FDD.1.2 F1AP_SUL_Information */ - - /* FDD.1.3 freqBandListNr */ - int ul_band = 1; - for (int j = 0; j < ul_band; j++) { - asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); - /* FDD.1.3.1 freqBandIndicatorNr*/ - nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band; - - /* FDD.1.3.2 supportedSULBandList*/ - } - - /* FDD.2.1 DL NRFreqInfo ARFCN */ - fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn; // Integer - - /* FDD.2.2 F1AP_SUL_Information */ - - /* FDD.2.3 freqBandListNr */ - int dl_bands = 1; - for (int j = 0; j < dl_bands; j++) { - asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); - /* FDD.2.3.1 freqBandIndicatorNr*/ - nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band; - - /* FDD.2.3.2 supportedSULBandList*/ - } // for FDD : DL freq_Bands - - /* FDD.3 UL Transmission Bandwidth */ - fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs; - fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb); - /* FDD.4 DL Transmission Bandwidth */ - fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs; - fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb); - } else if (c->mode == F1AP_MODE_TDD) { - const f1ap_tdd_info_t *tdd = &c->tdd; - nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD; - asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info); - /* TDD.1.1 nRFreqInfo ARFCN */ - tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn; - - /* TDD.1.2 F1AP_SUL_Information */ - - /* TDD.1.3 freqBandListNr */ - int bands = 1; - for (int j = 0; j < bands; j++) { - asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); - /* TDD.1.3.1 freqBandIndicatorNr*/ - nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band; - /* TDD.1.3.2 supportedSULBandList*/ - } - - /* TDD.2 transmission_Bandwidth */ - tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs; - tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb); - } else { - AssertFatal(false, "unknown mode %d\n", c->mode); - } - - /* - measurementTimingConfiguration */ - OCTET_STRING_fromBuf(&scell_info.measurementTimingConfiguration, - (const char *)c->measurement_timing_config, - c->measurement_timing_config_len); - - return scell_info; -} - -static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_system_info_t *sys_info) -{ - if (sys_info == NULL) - return NULL; /* optional: can be NULL */ - - F1AP_GNB_DU_System_Information_t *enc_sys_info = calloc(1, sizeof(*enc_sys_info)); - AssertFatal(enc_sys_info != NULL, "out of memory\n"); - - AssertFatal(sys_info->mib != NULL, "MIB must be present in DU sys info\n"); - OCTET_STRING_fromBuf(&enc_sys_info->mIB_message, (const char *)sys_info->mib, sys_info->mib_length); - - AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n"); - OCTET_STRING_fromBuf(&enc_sys_info->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length); - - return enc_sys_info; -} - /** * @brief F1AP Setup Request */ @@ -351,115 +203,24 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3 return 0; } -/* - gNB-DU Configuration Update -*/ - -int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd) +/** + * @brief F1 gNB-DU Configuration Update: encoding and ITTI transmission + */ +int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_t *msg) { - F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; uint32_t len=0; - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, initMsg); - initMsg->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate; - initMsg->criticality = F1AP_Criticality_reject; - initMsg->value.present = F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate; - F1AP_GNBDUConfigurationUpdate_t *out = &initMsg->value.choice.GNBDUConfigurationUpdate; - - /* mandatory */ - /* c1. Transaction ID (integer value) */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID; - ie1->value.choice.TransactionID = upd->transaction_id; - - /* mandatory */ - /* c2. Served_Cells_To_Add */ - if (upd->num_cells_to_add > 0) { - AssertFatal(false, "code for adding cells not tested\n"); - asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List; - ie2->criticality = F1AP_Criticality_reject; - ie2->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List; - - for (int j = 0; j < upd->num_cells_to_add; j++) { - const f1ap_served_cell_info_t *cell = &upd->cell_to_add[j].info; - const f1ap_gnb_du_system_info_t *sys_info = upd->cell_to_add[j].sys_info; - asn1cSequenceAdd(ie2->value.choice.Served_Cells_To_Add_List.list, - F1AP_Served_Cells_To_Add_ItemIEs_t, - served_cells_to_add_item_ies); - served_cells_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item; - served_cells_to_add_item_ies->criticality = F1AP_Criticality_reject; - served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item; - F1AP_Served_Cells_To_Add_Item_t *served_cells_to_add_item = - &served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item; - served_cells_to_add_item->served_Cell_Information = encode_served_cell_info(cell); - served_cells_to_add_item->gNB_DU_System_Information = encode_system_info(sys_info); - } - } - - /* mandatory */ - /* c3. Served_Cells_To_Modify */ - if (upd->num_cells_to_modify > 0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List; - for (int i = 0; i < upd->num_cells_to_modify; i++) { - const f1ap_served_cell_info_t *cell = &upd->cell_to_modify[i].info; - const f1ap_gnb_du_system_info_t *sys_info = upd->cell_to_modify[i].sys_info; - asn1cSequenceAdd(ie3->value.choice.Served_Cells_To_Modify_List.list, - F1AP_Served_Cells_To_Modify_ItemIEs_t, - served_cells_to_modify_item_ies); - served_cells_to_modify_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item; - served_cells_to_modify_item_ies->criticality = F1AP_Criticality_reject; - served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item; - F1AP_Served_Cells_To_Modify_Item_t *served_cells_to_modify_item = - &served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item; - - F1AP_NRCGI_t *oldNRCGI = &served_cells_to_modify_item->oldNRCGI; - const f1ap_plmn_t *old_plmn = &upd->cell_to_modify[i].old_plmn; - MCC_MNC_TO_PLMNID(old_plmn->mcc, old_plmn->mnc, old_plmn->mnc_digit_length, &oldNRCGI->pLMN_Identity); - NR_CELL_ID_TO_BIT_STRING(upd->cell_to_modify[i].old_nr_cellid, &oldNRCGI->nRCellIdentity); - - served_cells_to_modify_item->served_Cell_Information = encode_served_cell_info(cell); - served_cells_to_modify_item->gNB_DU_System_Information = encode_system_info(sys_info); - } - } - - /* mandatory */ - /* c4. Served_Cells_To_Delete */ - if (upd->num_cells_to_delete > 0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBDUConfigurationUpdateIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List; - AssertFatal(upd->num_cells_to_delete == 0, "code for deleting cells not tested\n"); - for (int i = 0; i < upd->num_cells_to_delete; i++) { - asn1cSequenceAdd(ie4->value.choice.Served_Cells_To_Delete_List.list, - F1AP_Served_Cells_To_Delete_ItemIEs_t, - served_cells_to_delete_item_ies); - served_cells_to_delete_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item; - served_cells_to_delete_item_ies->criticality = F1AP_Criticality_reject; - served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item; - F1AP_Served_Cells_To_Delete_Item_t *served_cells_to_delete_item = - &served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item; - addnRCGI(served_cells_to_delete_item->oldNRCGI, &upd->cell_to_delete[i]); - } - } - - AssertFatal(upd->gNB_DU_ID == 0, "encoding of gNB-DU Id not handled yet\n"); - - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + /* encode F1AP message */ + F1AP_F1AP_PDU_t *pdu = encode_f1ap_du_configuration_update(msg); + /* free anfter encoding */ + free_f1ap_du_configuration_update(msg); + /* encode F1AP pdu */ + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { LOG_E(F1AP, "Failed to encode F1 gNB-DU CONFIGURATION UPDATE\n"); return -1; } - - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + /* transfer the message */ + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h index 0cbf6adae2..c8975a2361 100644 --- a/openair2/F1AP/f1ap_du_interface_management.h +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -51,7 +51,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(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd); +int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_t *msg); /* * gNB-CU Configuration Update 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 7bdad73d21..ad8978d514 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -51,51 +51,8 @@ static void gnb_du_configuration_update_direct(const f1ap_gnb_du_configuration_u { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE); msg->ittiMsgHeader.originInstance = -1; // means monolithic - f1ap_gnb_du_configuration_update_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg); - DevAssert(upd->gNB_DU_ID == NULL); - f1ap_msg->transaction_id = upd->transaction_id; - DevAssert(upd->num_cells_to_add == 0); - DevAssert(upd->num_cells_to_delete == 0); - - f1ap_msg->num_cells_to_modify = upd->num_cells_to_modify; - for (int n = 0; n < upd->num_cells_to_modify; ++n) { - f1ap_msg->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid; - f1ap_msg->cell_to_modify[n].info = upd->cell_to_modify[n].info; // copy most fields - if (upd->cell_to_modify[n].info.tac) { - f1ap_msg->cell_to_modify[n].info.tac = malloc(sizeof(*f1ap_msg->cell_to_modify[n].info.tac)); - AssertFatal(f1ap_msg->cell_to_modify[n].info.tac != NULL, "out of memory\n"); - *f1ap_msg->cell_to_modify[n].info.tac = *upd->cell_to_modify[n].info.tac; - } - if (upd->cell_to_modify[n].info.measurement_timing_config_len > 0) { - f1ap_msg->cell_to_modify[n].info.measurement_timing_config = - calloc(upd->cell_to_modify[n].info.measurement_timing_config_len, sizeof(uint8_t)); - AssertFatal(f1ap_msg->cell_to_modify[n].info.measurement_timing_config != NULL, "out of memory\n"); - memcpy(f1ap_msg->cell_to_modify[n].info.measurement_timing_config, - upd->cell_to_modify[n].info.measurement_timing_config, - upd->cell_to_modify[n].info.measurement_timing_config_len); - f1ap_msg->cell_to_modify[n].info.measurement_timing_config_len = upd->cell_to_modify[n].info.measurement_timing_config_len; - } - - if (upd->cell_to_modify[n].sys_info) { - f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info; - f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info)); - AssertFatal(copy_sys_info != NULL, "out of memory\n"); - f1ap_msg->cell_to_modify[n].sys_info = copy_sys_info; - - copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->mib != NULL, "out of memory\n"); - memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length); - copy_sys_info->mib_length = orig_sys_info->mib_length; - - if (orig_sys_info->sib1_length > 0) { - copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n"); - memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length); - copy_sys_info->sib1_length = orig_sys_info->sib1_length; - } - } - } - + /* transfer to RRC via ITTI */ + F1AP_GNB_DU_CONFIGURATION_UPDATE(msg) = cp_f1ap_du_configuration_update(upd); itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index caf4309bec..2af81d0cfd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -78,34 +78,14 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) static void gnb_du_configuration_update_f1ap(const f1ap_gnb_du_configuration_update_t *upd) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE); - f1ap_gnb_du_configuration_update_t *f1_upd = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg); - f1_upd->transaction_id = upd->transaction_id; - AssertFatal(upd->num_cells_to_add == 0, "gNB-DU config update: cells to add not supported\n"); - f1_upd->num_cells_to_modify = upd->num_cells_to_modify; - for (int n = 0; n < upd->num_cells_to_modify; ++n) { - f1_upd->cell_to_modify[n].old_plmn = upd->cell_to_modify[n].old_plmn; - f1_upd->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid; - f1_upd->cell_to_modify[n].info = upd->cell_to_modify[n].info; - if (upd->cell_to_modify[n].sys_info) { - f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info; - f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info)); - f1_upd->cell_to_modify[n].sys_info = copy_sys_info; - - copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->mib != NULL, "out of memory\n"); - memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length); - copy_sys_info->mib_length = orig_sys_info->mib_length; - - if (orig_sys_info->sib1_length > 0) { - copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t)); - AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n"); - memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length); - copy_sys_info->sib1_length = orig_sys_info->sib1_length; - } - } - } - AssertFatal(upd->num_cells_to_delete == 0, "gNB-DU config update: cells to add not supported\n"); - itti_send_msg_to_task(TASK_DU_F1, 0, msg); + /* copy F1AP message */ + f1ap_gnb_du_configuration_update_t cp = cp_f1ap_du_configuration_update(upd); + /* transfer to ITTI message */ + F1AP_GNB_DU_CONFIGURATION_UPDATE(msg) = cp; + /* free after copy */ + free_f1ap_du_configuration_update(upd); + /* send to RRC task */ + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp) diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 1322c52141..e2806edf60 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -516,8 +516,9 @@ void rrc_gNB_process_f1_du_configuration_update(f1ap_gnb_du_configuration_update /* Send DU Configuration Acknowledgement */ f1ap_gnb_du_configuration_update_acknowledge_t ack = {.transaction_id = conf_up->transaction_id}; - rrc->mac_rrc.gnb_du_configuration_update_acknowledge(assoc_id, &ack); + /* free F1AP message after use */ + free_f1ap_du_configuration_update(conf_up); } void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) From 3b11764d1de8a7686cb087aed8f8da283c9d2cce Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 28 Aug 2024 17:22:09 +0200 Subject: [PATCH 35/73] Minor comments --- openair2/COMMON/f1ap_messages_types.h | 3 +-- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 95ff676307..f2fd001e4e 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -292,8 +292,7 @@ typedef struct f1ap_gnb_du_configuration_update_s { f1ap_plmn_t plmn; uint64_t nr_cellid; // NR Global Cell Id } cell_to_delete[F1AP_MAX_NB_CELLS]; - - /// string holding gNB_CU_name + /// gNB-DU unique ID, at least within a gNB-CU (0 .. 2^36 - 1) uint64_t *gNB_DU_ID; } f1ap_gnb_du_configuration_update_t; diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 5f150bf25c..7fd83ecd78 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -74,6 +74,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(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg) { + /* encode Initial UL RRC Message Transfer */ F1AP_F1AP_PDU_t *pdu = encode_initial_ul_rrc_message_transfer(msg); /* free F1AP message after encoding */ free_initial_ul_rrc_message_transfer(msg); @@ -84,7 +85,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_in return -1; } - /* encode */ + /* encode F1AP PDU */ uint8_t *buffer = NULL; uint32_t len = 0; if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { @@ -94,6 +95,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_in } ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + /* Send to ITTI */ f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } From c416c57f929aef337b72d332c97251d174a717e0 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 31 Jul 2024 17:19:36 +0200 Subject: [PATCH 36/73] Simplified F1AP gNB-CU Configuration Update message struct * removed optional IEs, whose encoding/decoding is not done --- openair2/COMMON/f1ap_messages_types.h | 14 ++------------ openair2/GNB_APP/gnb_app.c | 4 ---- openair2/GNB_APP/gnb_config.c | 1 - 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index f2fd001e4e..54d12f4e2a 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -213,18 +213,8 @@ typedef struct f1ap_setup_resp_s { } f1ap_setup_resp_t; typedef struct f1ap_gnb_cu_configuration_update_s { - /* Connexion id used between SCTP/F1AP */ - uint16_t cnx_id; - - /* SCTP association id */ - sctp_assoc_t assoc_id; - - /* Number of SCTP streams used for a mme association */ - uint16_t sctp_in_streams; - uint16_t sctp_out_streams; - - /// string holding gNB_CU_name - char *gNB_CU_name; + /// Transaction ID + uint64_t transaction_id; /// number of DU cells to activate uint16_t num_cells_to_activate; //0< num_cells_to_activate/mod <= 512; served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS]; diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 39946c95f1..64affd6c0a 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -236,10 +236,6 @@ void *gNB_app_task(void *args_p) case F1AP_GNB_CU_CONFIGURATION_UPDATE: AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n"); - - LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate); - cell_to_activate += F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate; gNB_app_handle_f1ap_gnb_cu_configuration_update(&F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p)); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 57e081b0e9..923a60f2eb 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -2367,7 +2367,6 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up ret++; mac->f1_config.setup_resp = malloc(sizeof(*mac->f1_config.setup_resp)); AssertFatal(mac->f1_config.setup_resp != NULL, "out of memory\n"); - mac->f1_config.setup_resp->gNB_CU_name = gnb_cu_cfg_update->gNB_CU_name; mac->f1_config.setup_resp->num_cells_to_activate = gnb_cu_cfg_update->num_cells_to_activate; mac->f1_config.setup_resp->cells_to_activate[0] = gnb_cu_cfg_update->cells_to_activate[0]; } else { From 8e3d6583a52162dafe86b3a5b839ffb172916cfe Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 9 Aug 2024 14:07:16 +0200 Subject: [PATCH 37/73] Add enc/dec library for F1AP gNB-CU Configuration Update (Interface Management) --- openair2/F1AP/lib/f1ap_interface_management.c | 140 +++++++++++++++++- openair2/F1AP/lib/f1ap_interface_management.h | 7 + 2 files changed, 145 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 667fba31be..f29383faee 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -980,8 +980,7 @@ f1ap_setup_failure_t cp_f1ap_setup_failure(const f1ap_setup_failure_t *msg) */ F1AP_F1AP_PDU_t *encode_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg) { - F1AP_F1AP_PDU_t *pdu = calloc(1, sizeof(*pdu)); - AssertFatal(pdu != NULL, "out of memory\n"); + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); /* Create */ /* 0. Message Type */ pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; @@ -1291,3 +1290,140 @@ f1ap_gnb_du_configuration_update_t cp_f1ap_du_configuration_update(const f1ap_gn } return cp; } + +/* ==================================== + * F1AP gNB-CU Configuration Update + * ==================================== */ + +/** + * @brief F1 gNB-CU Configuration Update encoding (9.2.1.10 of 3GPP TS 38.473) + */ +F1AP_F1AP_PDU_t *encode_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + /* Create + 0. Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, initMsg); + initMsg->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate; + initMsg->criticality = F1AP_Criticality_reject; + initMsg->value.present = F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate; + F1AP_GNBCUConfigurationUpdate_t *cfgUpdate = &pdu->choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate; + /* mandatory + c1. Transaction ID (integer value) */ + asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC1); + ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = F1AP_Criticality_reject; + ieC1->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = msg->transaction_id; + /* optional + c2. Cells_to_be_Activated_List (O) */ + for (int i = 0; i < msg->num_cells_to_activate; i++) { + asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC3); + ieC3->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; + ieC3->criticality = F1AP_Criticality_reject; + ieC3->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List; + asn1cSequenceAdd(ieC3->value.choice.Cells_to_be_Activated_List.list, + F1AP_Cells_to_be_Activated_List_ItemIEs_t, + cells_to_be_activated_ies); + encode_cells_to_activate(&msg->cells_to_activate[i], cells_to_be_activated_ies); + } + return pdu; +} + +/** + * @brief F1 gNB-CU Configuration Update decoding (9.2.1.10 of 3GPP TS 38.473) + */ +bool decode_f1ap_cu_configuration_update(const F1AP_F1AP_PDU_t *pdu, f1ap_gnb_cu_configuration_update_t *out) +{ + /* Check presence of message type */ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage); + AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL"); + _F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_gNBCUConfigurationUpdate); + _F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate); + /* Check presence of mandatory IEs */ + F1AP_GNBCUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate; + F1AP_GNBCUConfigurationUpdateIEs_t *ie; + F1AP_LIB_FIND_IE(F1AP_GNBCUConfigurationUpdateIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + _F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID); + AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1"); + out->transaction_id = ie->value.choice.TransactionID; + break; + case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: { + /* Cells to be Activated List (O) */ + _F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List); + /* Cells to be Activated List Item (count >= 1) */ + F1AP_Cells_to_be_Activated_List_t *Cells_to_be_Activated_List = &ie->value.choice.Cells_to_be_Activated_List; + out->num_cells_to_activate = Cells_to_be_Activated_List->list.count; + AssertError(out->num_cells_to_activate > 0, return false, "At least 1 cell to activate must be present"); + for (int i = 0; i < out->num_cells_to_activate; i++) { + if (!decode_cells_to_activate(&out->cells_to_activate[i], + (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)Cells_to_be_Activated_List->list.array[i])) + return false; + } + break; + } + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id); + break; + } + } + return true; +} + +void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg) +{ + for (int i = 0; i < msg->num_cells_to_activate; i++) + for (int j = 0; j < msg->cells_to_activate[j].num_SI; j++) + free(msg->cells_to_activate[i].SI_msg[j].SI_container); +} + +/** + * @brief F1 gNB-CU Configuration Update check + */ +bool eq_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *a, const f1ap_gnb_cu_configuration_update_t *b) +{ + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + /* to activate */ + _F1_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate); + for (int i = 0; i < a->num_cells_to_activate; i++) { + _F1_EQ_CHECK_LONG(a->cells_to_activate[i].nr_cellid, b->cells_to_activate[i].nr_cellid); + _F1_EQ_CHECK_INT(a->cells_to_activate[i].nrpci, b->cells_to_activate[i].nrpci); + if (!eq_f1ap_plmn(&a->cells_to_activate[i].plmn, &b->cells_to_activate[i].plmn)) + return false; + _F1_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI); + for (int s = 0; s < a->cells_to_activate[i].num_SI; s++) { + _F1_EQ_CHECK_INT(*a->cells_to_activate[i].SI_msg[s].SI_container, *a->cells_to_activate[i].SI_msg[s].SI_container); + _F1_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_container_length, a->cells_to_activate[i].SI_msg[s].SI_container_length); + _F1_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_type, a->cells_to_activate[i].SI_msg[s].SI_type); + } + } + return true; +} + +/** + * @brief F1 gNB-CU Configuration Update deep copy + */ +f1ap_gnb_cu_configuration_update_t cp_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg) +{ + f1ap_gnb_cu_configuration_update_t cp = {0}; + /* transaction_id */ + cp.transaction_id = msg->transaction_id; + cp.num_cells_to_activate = msg->num_cells_to_activate; + for (int i = 0; i < cp.num_cells_to_activate; i++) { + cp.cells_to_activate[i] = msg->cells_to_activate[i]; + for (int s = 0; s < cp.cells_to_activate[i].num_SI; s++) { + cp.cells_to_activate[i].SI_msg[s] = msg->cells_to_activate[i].SI_msg[s]; + f1ap_sib_msg_t *SI_msg = &cp.cells_to_activate[i].SI_msg[s]; + SI_msg->SI_container = calloc_or_fail(SI_msg->SI_container_length, sizeof(*SI_msg->SI_container)); + for (int j = 0; j < SI_msg->SI_container_length; j++) + SI_msg->SI_container[j] = msg->cells_to_activate[i].SI_msg[s].SI_container[j]; + } + } + return cp; +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index aa7991488b..563524c26a 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -53,4 +53,11 @@ bool eq_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *a f1ap_gnb_du_configuration_update_t cp_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg); void free_f1ap_du_configuration_update(const f1ap_gnb_du_configuration_update_t *msg); +/* F1 gNB-CU Configuration Update */ +struct F1AP_F1AP_PDU *encode_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg); +bool decode_f1ap_cu_configuration_update(const struct F1AP_F1AP_PDU *pdu, f1ap_gnb_cu_configuration_update_t *out); +bool eq_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *a, const f1ap_gnb_cu_configuration_update_t *b); +f1ap_gnb_cu_configuration_update_t cp_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg); +void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg); + #endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ From 3626366228e134671fa0edea3f5e40efdef937b4 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 29 May 2024 15:49:33 +0200 Subject: [PATCH 38/73] Add test for F1 gNB-CU Configuration Update enc/dec lib --- openair2/F1AP/tests/f1ap_lib_test.c | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 6ccc814cfc..912ef52ff4 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -431,6 +431,43 @@ static void test_f1ap_du_configuration_update(void) free_f1ap_du_configuration_update(&orig); } +/** + * @brief Test F1 gNB-CU Configuration Update + */ +static void test_f1ap_cu_configuration_update(void) +{ + /* create message */ + f1ap_gnb_cu_configuration_update_t orig = {.transaction_id = 2, + .num_cells_to_activate = 1, + .cells_to_activate = {{.nr_cellid = 123456789, + .nrpci = 100, + .plmn = {.mcc = 001, .mnc = 01, .mnc_digit_length = 2}, + .num_SI = 1, + .SI_msg = {{ + .SI_type = 7, + .SI_container_length = 10, + .SI_container = malloc(sizeof(uint8_t) * 10), + }}}}}; + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_cu_configuration_update(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_gnb_cu_configuration_update_t decoded = {0}; + bool ret = decode_f1ap_cu_configuration_update(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_setup_request(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_f1ap_cu_configuration_update(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_setup_request(): decoded message doesn't match\n"); + free_f1ap_cu_configuration_update(&decoded); + + f1ap_gnb_cu_configuration_update_t cp = cp_f1ap_cu_configuration_update(&orig); + ret = eq_f1ap_cu_configuration_update(&orig, &cp); + AssertFatal(ret, "eq_f1ap_setup_request(): copied message doesn't match\n"); + free_f1ap_cu_configuration_update(&cp); + free_f1ap_cu_configuration_update(&orig); +} + int main() { test_initial_ul_rrc_message_transfer(); @@ -440,5 +477,6 @@ int main() test_f1ap_setup_response(); test_f1ap_setup_failure(); test_f1ap_du_configuration_update(); + test_f1ap_cu_configuration_update(); return 0; } From 80a05271d6f820edd7993f1f549fbb326a8e3d99 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2024 23:54:13 +0200 Subject: [PATCH 39/73] Use F1AP gNB-CU Configuration Update lib in stack --- openair2/F1AP/f1ap_cu_interface_management.c | 102 ++----------- openair2/F1AP/f1ap_du_interface_management.c | 149 ++----------------- openair2/GNB_APP/gnb_app.c | 4 + openair2/GNB_APP/gnb_config.c | 3 + 4 files changed, 33 insertions(+), 225 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index e6064c1502..df4bb2ecf1 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -189,99 +189,27 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE( return 0; } -/* - 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) +/** + * @brief F1 gNB-CU Configuration Update message encoding and transfer + */ +int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *msg) { - F1AP_F1AP_PDU_t pdu= {0}; + /* complete F1AP message */ + msg->transaction_id = F1AP_get_next_transaction_identifier(0, 0); // note: has to be done in the caller uint8_t *buffer; uint32_t len; - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, initMsg); - initMsg->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate; - initMsg->criticality = F1AP_Criticality_reject; - initMsg->value.present = F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate; - F1AP_GNBCUConfigurationUpdate_t *cfgUpdate = &pdu.choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate; - /* mandatory */ - /* c1. Transaction ID (integer value) */ - asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC1); - ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID; - ieC1->criticality = F1AP_Criticality_reject; - ieC1->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID; - ieC1->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0); - - // mandatory - // c2. Cells_to_be_Activated_List - if (f1ap_gnb_cu_configuration_update->num_cells_to_activate > 0) { - asn1cSequenceAdd(cfgUpdate->protocolIEs.list, F1AP_GNBCUConfigurationUpdateIEs_t, ieC3); - ieC3->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; - ieC3->criticality = F1AP_Criticality_reject; - ieC3->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List; - - for (int i=0; inum_cells_to_activate; i++) { - asn1cSequenceAdd(ieC3->value.choice.Cells_to_be_Activated_List.list,F1AP_Cells_to_be_Activated_List_ItemIEs_t, - cells_to_be_activated_ies); - cells_to_be_activated_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; - cells_to_be_activated_ies->criticality = F1AP_Criticality_reject; - cells_to_be_activated_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; - // 2.1 cells to be Activated list item - F1AP_Cells_to_be_Activated_List_Item_t *cells_to_be_activated_list_item= - &cells_to_be_activated_ies->value.choice.Cells_to_be_Activated_List_Item; - // - nRCGI - addnRCGI(cells_to_be_activated_list_item->nRCGI, f1ap_gnb_cu_configuration_update->cells_to_activate+i); - // optional - // -nRPCI - asn1cCalloc(cells_to_be_activated_list_item->nRPCI, tmp); - *tmp = f1ap_gnb_cu_configuration_update->cells_to_activate[i].nrpci; // int 0..1007 - // optional - // 3.1.2 gNB-CUSystem Information - F1AP_ProtocolExtensionContainer_10696P112_t *p = calloc(1,sizeof(*p)); - cells_to_be_activated_list_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *) p; - //F1AP_ProtocolExtensionContainer_154P112_t - asn1cSequenceAdd(p->list, F1AP_Cells_to_be_Activated_List_ItemExtIEs_t, cells_to_be_activated_itemExtIEs); - cells_to_be_activated_itemExtIEs->id = F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation; - cells_to_be_activated_itemExtIEs->criticality = F1AP_Criticality_reject; - cells_to_be_activated_itemExtIEs->extensionValue.present = F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation; - - if (f1ap_gnb_cu_configuration_update->cells_to_activate[i].num_SI > 0) { - F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = - &cells_to_be_activated_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; - //LOG_I(F1AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]); - //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++) - // printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]); - //printf("\n"); - - // for (int sIBtype=2;sIBtype<33;sIBtype++) { //21 ? 33 ? - for (int j = 0; j < sizeofArray(f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_msg); j++) { - f1ap_sib_msg_t *SI_msg = &f1ap_gnb_cu_configuration_update->cells_to_activate[i].SI_msg[j]; - if (SI_msg->SI_container != NULL) { - asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item); - sib_item->sIBtype = SI_msg->SI_type; - AssertFatal(sib_item->sIBtype < 6 || sib_item->sIBtype == 9, "Illegal SI type %ld\n", sib_item->sIBtype); - OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container, SI_msg->SI_container_length); - LOG_D(F1AP, - "f1ap_gnb_cu_configuration_update->SI_container_length[%d][sIBtype %ld] = %d \n", - i, - sib_item->sIBtype, - SI_msg->SI_container_length); - } - } - } - } - } - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode F1 gNB-CU CONFIGURATION UPDATE\n"); + /* Encode F1 gNB-CU Configuration Update message */ + F1AP_F1AP_PDU_t *pdu = encode_f1ap_cu_configuration_update(msg); + /* Free after encoding */ + free_f1ap_cu_configuration_update(msg); + /* Encode F1AP PDU */ + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_E(F1AP, "Failed to encode F1 gNB-CU Configuration Update\n"); return -1; } - LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-CU CONFIGURATION UPDATE : "); - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 6104757816..cb2843c5f9 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -225,148 +225,21 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_du_confi return 0; } +/** + * @brief F1 gNB-CU Configuration Update decoding and message transfer + */ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { LOG_D(F1AP, "DU_handle_gNB_CU_CONFIGURATION_UPDATE\n"); - AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_initiatingMessage, - "pdu->present != F1AP_F1AP_PDU_PR_initiatingMessage\n"); - AssertFatal(pdu->choice.initiatingMessage->procedureCode == F1AP_ProcedureCode_id_gNBCUConfigurationUpdate, - "pdu->choice.initiatingMessage->procedureCode != F1AP_ProcedureCode_id_gNBCUConfigurationUpdate\n"); - AssertFatal(pdu->choice.initiatingMessage->criticality == F1AP_Criticality_reject, - "pdu->choice.initiatingMessage->criticality != F1AP_Criticality_reject\n"); - AssertFatal(pdu->choice.initiatingMessage->value.present == F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate, - "pdu->choice.initiatingMessage->value.present != F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate\n"); - F1AP_GNBCUConfigurationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate; - F1AP_GNBCUConfigurationUpdateIEs_t *ie; - int TransactionId = -1; - int num_cells_to_activate = 0; - F1AP_Cells_to_be_Activated_List_Item_t *cell; + f1ap_gnb_cu_configuration_update_t in = {0}; + if (!decode_f1ap_cu_configuration_update(pdu, &in)) { + LOG_E(F1AP, "Failed to decode F1AP Setup Failure\n"); + free_f1ap_cu_configuration_update(&in); + return -1; + } MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE); - LOG_D(F1AP, "F1AP: gNB_CU_Configuration_Update: protocolIEs.list.count %d\n", - in->protocolIEs.list.count); - - for (int i=0; i < in->protocolIEs.list.count; i++) { - ie = in->protocolIEs.list.array[i]; - - switch (ie->id) { - case F1AP_ProtocolIE_ID_id_TransactionID: - AssertFatal(ie->criticality == F1AP_Criticality_reject, - "ie->criticality != F1AP_Criticality_reject\n"); - AssertFatal(ie->value.present == F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID, - "ie->value.present != F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID\n"); - TransactionId=ie->value.choice.TransactionID; - LOG_D(F1AP, "F1AP: GNB-CU-ConfigurationUpdate: TransactionId %d\n", - TransactionId); - break; - - case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: { - AssertFatal(ie->criticality == F1AP_Criticality_reject, - "ie->criticality != F1AP_Criticality_reject\n"); - AssertFatal(ie->value.present == F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List, - "ie->value.present != F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List\n"); - num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count; - LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate); - - for (int i=0; ivalue.choice.Cells_to_be_Activated_List.list.array[i]; - AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item, - "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item"); - AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject, - "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; - TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mcc, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mnc, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mnc_digit_length); - LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n", - cell->nRCGI.nRCellIdentity.buf[0], - cell->nRCGI.nRCellIdentity.buf[1], - cell->nRCGI.nRCellIdentity.buf[2], - cell->nRCGI.nRCellIdentity.buf[3], - cell->nRCGI.nRCellIdentity.buf[4]); - BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nr_cellid); - F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions; - - if (ext==NULL) - continue; - - for (int cnt=0; cntlist.count; cnt++) { - F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs=(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)ext->list.array[cnt]; - - switch (cells_to_be_activated_list_itemExtIEs->id) { - /* - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_NOTHING: - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailablePLMNList, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_ExtendedAvailablePLMN_List, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_IAB_Info_IAB_donor_CU, - case F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_AvailableSNPN_ID_List - */ - case F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation: { - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].nrpci = (cell->nRPCI != NULL) ? *cell->nRPCI : 0; - F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)&cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation; - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).cells_to_activate[i].num_SI = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; - AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n"); - LOG_D(F1AP, - "F1AP: Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n", - i, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mcc, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].plmn.mnc, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].nr_cellid, - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].num_SI); - - for (int si = 0; si < gNB_CUSystemInformation->sibtypetobeupdatedlist.list.count; si++) { - F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[si]; - size_t size = sib_item->sIBmessage.size; - f1ap_sib_msg_t *SI_msg = &F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).cells_to_activate[i].SI_msg[si]; - SI_msg->SI_container_length = size; - LOG_D(F1AP, "F1AP: SI_container_length[%d][%ld] %ld bytes\n", i, sib_item->sIBtype, size); - SI_msg->SI_container = malloc(SI_msg->SI_container_length); - memcpy((void *)SI_msg->SI_container, (void *)sib_item->sIBmessage.buf, size); - SI_msg->SI_type = sib_item->sIBtype; - } - - break; - } - - case F1AP_ProtocolIE_ID_id_AvailablePLMNList: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - case F1AP_ProtocolIE_ID_id_ExtendedAvailablePLMN_List: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - case F1AP_ProtocolIE_ID_id_IAB_Info_IAB_donor_CU: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - case F1AP_ProtocolIE_ID_id_AvailableSNPN_ID_List: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id_AvailablePLMNList not supported yet\n"); - break; - - default: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n",(int)cells_to_be_activated_list_itemExtIEs->id); - break; - } - } // for (cnt=... - } // for (cells_to_activate... - - break; - } // case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List - - default: - AssertFatal(1==0,"F1AP_ProtocolIE_ID_id %d unknown\n", (int)ie->id); - break; - } // switch ie - } // for IE - - AssertFatal(TransactionId!=-1,"TransactionId was not sent\n"); - LOG_D(F1AP,"F1AP: num_cells_to_activate %d\n",num_cells_to_activate); - F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p).num_cells_to_activate = num_cells_to_activate; + f1ap_gnb_cu_configuration_update_t *msg = &F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p); // RRC thread will free it + *msg = in; // copy F1 message to ITTI LOG_D(F1AP, "Sending F1AP_GNB_CU_CONFIGURATION_UPDATE ITTI message \n"); itti_send_msg_to_task(TASK_GNB_APP, GNB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); return 0; diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 64affd6c0a..caaf5d64e7 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -236,6 +236,10 @@ void *gNB_app_task(void *args_p) case F1AP_GNB_CU_CONFIGURATION_UPDATE: AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n"); + LOG_I(GNB_APP, + "Received %s: associated with %d cells to activate\n", + ITTI_MSG_NAME(msg_p), + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate); cell_to_activate += F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate; gNB_app_handle_f1ap_gnb_cu_configuration_update(&F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p)); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 923a60f2eb..06d4318e97 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -94,6 +94,7 @@ #ifdef ENABLE_AERIAL #include "nfapi/oai_integration/aerial/fapi_vnf_p5.h" #endif +#include "lib/f1ap_interface_management.h" extern uint16_t sf_ahead; @@ -2375,6 +2376,8 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up } } NR_SCHED_UNLOCK(&mac->sched_lock); + /* Free F1AP struct after use */ + free_f1ap_cu_configuration_update(gnb_cu_cfg_update); MessageDef *msg_ack_p = NULL; if (ret > 0) { // generate gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE From d2863d96935021468e93a31e5811716407f5a24c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 9 Aug 2024 14:16:57 +0200 Subject: [PATCH 40/73] Refactored f1ap_gnb_cu_configuration_update_acknowledge_t * add transaction_id * refactored remaining members --- openair2/COMMON/f1ap_messages_types.h | 36 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 54d12f4e2a..f159e63ca3 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -98,6 +98,11 @@ typedef struct f1ap_plmn_t { uint8_t mnc_digit_length; } f1ap_plmn_t; +typedef struct f1ap_cp_tnl_s { + in_addr_t tl_address; // currently only IPv4 supported + uint16_t port; +} f1ap_cp_tnl_t; + typedef enum f1ap_mode_t { F1AP_MODE_TDD = 0, F1AP_MODE_FDD = 1 } f1ap_mode_t; typedef struct f1ap_nr_frequency_info_t { @@ -229,22 +234,31 @@ typedef struct f1ap_setup_failure_s { } f1ap_setup_failure_t; typedef struct f1ap_gnb_cu_configuration_update_acknowledge_s { + uint64_t transaction_id; + // Cells Failed to be Activated List uint16_t num_cells_failed_to_be_activated; - f1ap_plmn_t plmn[F1AP_MAX_NB_CELLS]; - uint64_t nr_cellid[F1AP_MAX_NB_CELLS]; - uint16_t cause[F1AP_MAX_NB_CELLS]; + struct { + // NR CGI + f1ap_plmn_t plmn; + uint64_t nr_cellid; + uint16_t cause; + } cells_failed_to_be_activated[F1AP_MAX_NB_CELLS]; int have_criticality; - uint16_t criticality_diagnostics; + uint16_t criticality_diagnostics; + // gNB-CU TNL Association Setup List uint16_t noofTNLAssociations_to_setup; - uint16_t have_port[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; - in_addr_t tl_address[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; // currently only IPv4 supported + f1ap_cp_tnl_t tnlAssociations_to_setup[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; + // gNB-CU TNL Association Failed to Setup List uint16_t noofTNLAssociations_failed; - in_addr_t tl_address_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; // currently only IPv4 supported - uint16_t cause_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; + f1ap_cp_tnl_t tnlAssociations_failed[F1AP_MAX_NO_OF_TNL_ASSOCIATIONS]; + // Dedicated SI Delivery Needed UE List uint16_t noofDedicatedSIDeliveryNeededUEs; - uint32_t gNB_CU_ue_id[F1AP_MAX_NO_UE_ID]; - f1ap_plmn_t ue_plmn[F1AP_MAX_NO_UE_ID]; - uint64_t ue_nr_cellid[F1AP_MAX_NO_UE_ID]; + struct { + uint32_t gNB_CU_ue_id; + // NR CGI + f1ap_plmn_t ue_plmn; + uint64_t ue_nr_cellid; + } dedicatedSIDeliveryNeededUEs[F1AP_MAX_NO_UE_ID]; } f1ap_gnb_cu_configuration_update_acknowledge_t; typedef struct f1ap_gnb_cu_configuration_update_failure_s { From 3724e84fed064ec3542369653528395072035d3c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 9 Aug 2024 14:18:37 +0200 Subject: [PATCH 41/73] Add enc library for F1 gNB-CU Configuration Update Acknowledge (Interface Management) --- openair2/F1AP/lib/f1ap_interface_management.c | 190 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 3 + 2 files changed, 193 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index f29383faee..7dad7452f7 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -1427,3 +1427,193 @@ f1ap_gnb_cu_configuration_update_t cp_f1ap_cu_configuration_update(const f1ap_gn } return cp; } + +/* ==================================== + * F1AP gNB-CU Configuration Ack + * ==================================== */ + +/** + * @brief F1 gNB-CU Configuration Update Acknowledge message encoding (9.2.1.11 of 3GPP TS 38.473) + * gNB-DU → gNB-CU + */ +F1AP_F1AP_PDU_t *encode_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + /* Create */ + /* 0. pdu Type */ + pdu->present = F1AP_F1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, tmp); + tmp->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate; + tmp->criticality = F1AP_Criticality_reject; + tmp->value.present = F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge; + F1AP_GNBCUConfigurationUpdateAcknowledge_t *out = &tmp->value.choice.GNBCUConfigurationUpdateAcknowledge; + // Transaction ID (M) + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID; + ie1->value.choice.TransactionID = msg->transaction_id; + // Cells Failed to be Activated List (0..1) + if (msg->num_cells_failed_to_be_activated > 0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t, ie2); + ie2->id = F1AP_ProtocolIE_ID_id_Cells_Failed_to_be_Activated_List; + ie2->criticality = F1AP_Criticality_reject; + ie2->value.present = F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_Failed_to_be_Activated_List; + F1AP_Cells_Failed_to_be_Activated_List_t *failedCellsList = &ie2->value.choice.Cells_Failed_to_be_Activated_List; + for (int i = 0; i < msg->num_cells_failed_to_be_activated; i++) { + asn1cSequenceAdd(failedCellsList->list, F1AP_Cells_Failed_to_be_Activated_List_ItemIEs_t, failedCellIE); + failedCellIE->id = F1AP_ProtocolIE_ID_id_Cells_Failed_to_be_Activated_List_Item; + failedCellIE->criticality = F1AP_Criticality_reject; + failedCellIE->value.present = F1AP_Cells_Failed_to_be_Activated_List_ItemIEs__value_PR_Cells_Failed_to_be_Activated_List_Item; + F1AP_Cells_Failed_to_be_Activated_List_Item_t *p1 = &failedCellIE->value.choice.Cells_Failed_to_be_Activated_List_Item; + // Cause (M) + p1->cause.present = F1AP_Cause_PR_radioNetwork; + p1->cause.choice.radioNetwork = msg->cells_failed_to_be_activated[i].cause; + // NR CGI (M) + const f1ap_plmn_t *plmn = &msg->cells_failed_to_be_activated[i].plmn; + MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &(p1->nRCGI.pLMN_Identity)); + printf("plmn->mcc %d %d %d %ld \n", + p1->nRCGI.pLMN_Identity.buf[0], p1->nRCGI.pLMN_Identity.buf[1], p1->nRCGI.pLMN_Identity.buf[2], p1->nRCGI.pLMN_Identity.size); + NR_CELL_ID_TO_BIT_STRING(msg->cells_failed_to_be_activated[i].nr_cellid, &(p1->nRCGI.nRCellIdentity)); + } + } + return pdu; +} + +/** + * @brief F1 gNB-CU Configuration Update Acknowledge decoding (9.2.1.11 of 3GPP TS 38.473) + */ +bool decode_f1ap_cu_configuration_update_acknowledge(const F1AP_F1AP_PDU_t *pdu, + f1ap_gnb_cu_configuration_update_acknowledge_t *out) +{ + /* Message type */ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome); + AssertError(pdu->choice.successfulOutcome != NULL, return false, "pdu->choice.successfulOutcome is NULL"); + _F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_gNBCUConfigurationUpdate); + _F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, + F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge); + /* payload */ + F1AP_GNBCUConfigurationUpdateAcknowledge_t *in = &pdu->choice.successfulOutcome->value.choice.GNBCUConfigurationUpdateAcknowledge; + F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t *ie; + /* Check mandatory IEs */ + F1AP_LIB_FIND_IE(F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + _F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID); + AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1"); + out->transaction_id = ie->value.choice.TransactionID; + break; + case F1AP_ProtocolIE_ID_id_Cells_Failed_to_be_Activated_List: { + /* Decode Cells Failed to be Activated List */ + _F1_EQ_CHECK_INT(ie->value.present, + F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_Failed_to_be_Activated_List); + F1AP_Cells_Failed_to_be_Activated_List_t *cell_fail_list = &ie->value.choice.Cells_Failed_to_be_Activated_List; + out->num_cells_failed_to_be_activated = cell_fail_list->list.count; + for (int j = 0; j < out->num_cells_failed_to_be_activated; j++) { + const F1AP_Cells_Failed_to_be_Activated_List_ItemIEs_t *itemIE = + (F1AP_Cells_Failed_to_be_Activated_List_ItemIEs_t *)cell_fail_list->list.array[j]; + const F1AP_Cells_Failed_to_be_Activated_List_Item_t *item = &itemIE->value.choice.Cells_Failed_to_be_Activated_List_Item; + // NR CGI (M) + f1ap_plmn_t *plmn = &out->cells_failed_to_be_activated[j].plmn; + TBCD_TO_MCC_MNC(&(item->nRCGI.pLMN_Identity), plmn->mcc, plmn->mnc, plmn->mnc_digit_length); + BIT_STRING_TO_NR_CELL_IDENTITY(&item->nRCGI.nRCellIdentity, out->cells_failed_to_be_activated[j].nr_cellid); + // Cause (M) + switch (item->cause.present) { + case F1AP_Cause_PR_radioNetwork: + out->cells_failed_to_be_activated[j].cause = item->cause.choice.radioNetwork; + break; + case F1AP_Cause_PR_transport: + out->cells_failed_to_be_activated[j].cause = item->cause.choice.transport; + break; + case F1AP_Cause_PR_protocol: + out->cells_failed_to_be_activated[j].cause = item->cause.choice.protocol; + break; + case F1AP_Cause_PR_misc: + out->cells_failed_to_be_activated[j].cause = item->cause.choice.misc; + break; + default: + AssertError(1 == 0, return false, "Unknown cause type %d\n", item->cause.present); + break; + } + } + break; + } + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id); + break; + } + } + return true; +} + +/** + * @brief F1 gNB-CU Configuration Update Acknowledge check + */ +bool eq_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *a, + const f1ap_gnb_cu_configuration_update_acknowledge_t *b) +{ + // Transaction ID + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + // number of cells failed to be activated + _F1_EQ_CHECK_INT(a->num_cells_failed_to_be_activated, b->num_cells_failed_to_be_activated); + for (int i = 0; i < a->num_cells_failed_to_be_activated; i++) { + if (!eq_f1ap_plmn(&a->cells_failed_to_be_activated[i].plmn, &b->cells_failed_to_be_activated[i].plmn)) + return false; + _F1_EQ_CHECK_LONG(a->cells_failed_to_be_activated[i].nr_cellid, b->cells_failed_to_be_activated[i].nr_cellid); + _F1_EQ_CHECK_INT(a->cells_failed_to_be_activated[i].cause, b->cells_failed_to_be_activated[i].cause); + } + // TNL Associations to setup + _F1_EQ_CHECK_INT(a->noofTNLAssociations_to_setup, b->noofTNLAssociations_to_setup); + for (int i = 0; i < a->noofTNLAssociations_to_setup; i++) { + // Explicit comparison of TNL Association fields + _F1_EQ_CHECK_INT(a->tnlAssociations_to_setup[i].tl_address, b->tnlAssociations_to_setup[i].tl_address); + _F1_EQ_CHECK_INT(a->tnlAssociations_to_setup[i].port, b->tnlAssociations_to_setup[i].port); + } + // TNL Associations failed to setup + _F1_EQ_CHECK_INT(a->noofTNLAssociations_failed, b->noofTNLAssociations_failed); + for (int i = 0; i < a->noofTNLAssociations_failed; i++) { + // Explicit comparison of TNL Association fields + _F1_EQ_CHECK_INT(a->tnlAssociations_failed[i].tl_address, b->tnlAssociations_failed[i].tl_address); + _F1_EQ_CHECK_INT(a->tnlAssociations_failed[i].port, b->tnlAssociations_failed[i].port); + } + // Dedicated SI Delivery Needed UE List + _F1_EQ_CHECK_INT(a->noofDedicatedSIDeliveryNeededUEs, b->noofDedicatedSIDeliveryNeededUEs); + for (int i = 0; i < a->noofDedicatedSIDeliveryNeededUEs; i++) { + _F1_EQ_CHECK_INT(a->dedicatedSIDeliveryNeededUEs[i].gNB_CU_ue_id, b->dedicatedSIDeliveryNeededUEs[i].gNB_CU_ue_id); + if (!eq_f1ap_plmn(&a->dedicatedSIDeliveryNeededUEs[i].ue_plmn, &b->dedicatedSIDeliveryNeededUEs[i].ue_plmn)) + return false; + _F1_EQ_CHECK_LONG(a->dedicatedSIDeliveryNeededUEs[i].ue_nr_cellid, b->dedicatedSIDeliveryNeededUEs[i].ue_nr_cellid); + } + return true; +} + +/** + * @brief F1 gNB-CU Configuration Update Acknowledge deep copy + */ +f1ap_gnb_cu_configuration_update_acknowledge_t cp_f1ap_cu_configuration_update_acknowledge( + const f1ap_gnb_cu_configuration_update_acknowledge_t *msg) +{ + f1ap_gnb_cu_configuration_update_acknowledge_t cp = {0}; + // Transaction ID + cp.transaction_id = msg->transaction_id; + // number of cells failed to be activated + cp.num_cells_failed_to_be_activated = msg->num_cells_failed_to_be_activated; + for (int i = 0; i < cp.num_cells_failed_to_be_activated; i++) + cp.cells_failed_to_be_activated[i] = msg->cells_failed_to_be_activated[i]; + // TNL Associations to setup + cp.noofTNLAssociations_to_setup = msg->noofTNLAssociations_to_setup; + for (int i = 0; i < cp.noofTNLAssociations_to_setup; i++) + cp.tnlAssociations_to_setup[i] = msg->tnlAssociations_to_setup[i]; + // TNL Associations failed to setup + cp.noofTNLAssociations_failed = msg->noofTNLAssociations_failed; + for (int i = 0; i < cp.noofTNLAssociations_failed; i++) + cp.tnlAssociations_failed[i] = msg->tnlAssociations_failed[i]; + // Dedicated SI Delivery Needed UE List + cp.noofDedicatedSIDeliveryNeededUEs = msg->noofDedicatedSIDeliveryNeededUEs; + for (int i = 0; i < cp.noofDedicatedSIDeliveryNeededUEs; i++) + cp.dedicatedSIDeliveryNeededUEs[i] = msg->dedicatedSIDeliveryNeededUEs[i]; + return cp; +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index 563524c26a..b368b5576f 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -60,4 +60,7 @@ bool eq_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *a f1ap_gnb_cu_configuration_update_t cp_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg); void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *msg); +/* F1 gNB-CU Configuration Update Acknowledge */ +struct F1AP_F1AP_PDU *encode_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *msg); + #endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ From c936aabd9a517a7eaad94267d9bd8c894339a849 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 30 Aug 2024 00:29:44 +0200 Subject: [PATCH 42/73] Add test for CU Configuration Update Acknowledge lib --- openair2/F1AP/tests/f1ap_lib_test.c | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 912ef52ff4..878c7fad78 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -468,6 +468,40 @@ static void test_f1ap_cu_configuration_update(void) free_f1ap_cu_configuration_update(&orig); } +/** + * @brief Test F1 gNB-CU Configuration Update Acknowledge + */ +static void test_f1ap_cu_configuration_update_acknowledge(void) +{ + // Create the original message + f1ap_gnb_cu_configuration_update_acknowledge_t orig = { + .transaction_id = 2, + .num_cells_failed_to_be_activated = 1, + .cells_failed_to_be_activated = {{.nr_cellid = 123456789, + .plmn = {.mcc = 001, .mnc = 01, .mnc_digit_length = 2}, + .cause = F1AP_CAUSE_RADIO_NETWORK}} + }; + // F1AP Enc/dec + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_cu_configuration_update_acknowledge(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + // Decoding + f1ap_gnb_cu_configuration_update_acknowledge_t decoded = {0}; + bool ret = decode_f1ap_cu_configuration_update_acknowledge(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_cu_configuration_update_acknowledge(): could not decode message\n"); + f1ap_msg_free(f1dec); + // Equality check + ret = eq_f1ap_cu_configuration_update_acknowledge(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_cu_configuration_update_acknowledge(): decoded message doesn't match\n"); + // No free needed + // Deep copy + f1ap_gnb_cu_configuration_update_acknowledge_t cp = cp_f1ap_cu_configuration_update_acknowledge(&orig); + // Equality check + ret = eq_f1ap_cu_configuration_update_acknowledge(&orig, &cp); + AssertFatal(ret, "eq_f1ap_cu_configuration_update_acknowledge(): copied message doesn't match\n"); + // No free needed +} + int main() { test_initial_ul_rrc_message_transfer(); @@ -478,5 +512,6 @@ int main() test_f1ap_setup_failure(); test_f1ap_du_configuration_update(); test_f1ap_cu_configuration_update(); + test_f1ap_cu_configuration_update_acknowledge(); return 0; } From 3ce1f0e2c55a4fe20da693262fadfdbf5e0c8105 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 29 May 2024 21:38:59 +0200 Subject: [PATCH 43/73] Use F1 gNB-CU Configuration Update Acknowledge lib in stack --- openair2/F1AP/f1ap_cu_interface_management.c | 22 ++++++++- openair2/F1AP/f1ap_du_interface_management.c | 52 +++++--------------- openair2/GNB_APP/gnb_config.c | 1 + openair2/RRC/NR/rrc_gNB.c | 6 +++ 4 files changed, 40 insertions(+), 41 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index df4bb2ecf1..cd408c6720 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -214,11 +214,29 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_confi return 0; } +/** + * @brief gNB CU Configuration Update Acknowledge decoding (9.2.1.11 of 3GPP TS 38.473) + * and handling by CU + */ int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - LOG_I(F1AP,"Cell Configuration ok (assoc_id %d)\n",assoc_id); - return(0); + DevAssert(pdu != NULL); + if (stream != 0) + LOG_W(F1AP, "[SCTP %d] Received gNB CU Configuration Update Acknowledge on stream != 0 (%d)\n", assoc_id, stream); + // Decode + f1ap_gnb_cu_configuration_update_acknowledge_t msg = {0}; + if (!decode_f1ap_cu_configuration_update_acknowledge(pdu, &msg)) { + LOG_E(F1AP, "Failed to decode gNB CU Configuration Update Acknowledge\n"); + return -1; + } + // Allocate ITTI message and send to RRC + MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE); + message_p->ittiMsgHeader.originInstance = assoc_id; + f1ap_gnb_cu_configuration_update_acknowledge_t *ack = &F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(message_p); + *ack = msg; // copy decoded message to ITTI, the RRC thread will free it + itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); + return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index cb2843c5f9..391f9164eb 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -251,48 +251,22 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, GNBCUConfigurationUpdateFailure->cause); } -int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE( - sctp_assoc_t assoc_id, - f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) +/** + * @brief Encode and transfer F1 GNB CU Configuration Update Acknowledge message + */ +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_acknowledge_t *msg) { - AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0, - "%d cells failed to activate\n", - GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated); - AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_to_setup == 0, - "%d TNLAssociations to setup, handle this ...\n", - GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_to_setup); - AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_failed == 0, - "%d TNLAssociations failed\n", - GNBCUConfigurationUpdateAcknowledge->noofTNLAssociations_failed); - AssertFatal(GNBCUConfigurationUpdateAcknowledge->noofDedicatedSIDeliveryNeededUEs == 0, - "%d DedicatedSIDeliveryNeededUEs\n", - GNBCUConfigurationUpdateAcknowledge->noofDedicatedSIDeliveryNeededUEs); - F1AP_F1AP_PDU_t pdu= {0}; - uint8_t *buffer=NULL; - uint32_t len=0; - /* Create */ - /* 0. pdu Type */ - pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; - asn1cCalloc(pdu.choice.successfulOutcome, tmp); - tmp->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate; - tmp->criticality = F1AP_Criticality_reject; - tmp->value.present = F1AP_SuccessfulOutcome__value_PR_GNBCUConfigurationUpdateAcknowledge; - F1AP_GNBCUConfigurationUpdateAcknowledge_t *out = &tmp->value.choice.GNBCUConfigurationUpdateAcknowledge; - /* mandatory */ - /* c1. Transaction ID (integer value)*/ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_GNBCUConfigurationUpdateAcknowledgeIEs_t, ie); - ie->id = F1AP_ProtocolIE_ID_id_TransactionID; - ie->criticality = F1AP_Criticality_reject; - ie->value.present = F1AP_GNBCUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID; - ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0); - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode GNB-DU-Configuration-Update-Acknowledge\n"); + uint8_t *buffer = NULL; + uint32_t len = 0; + /* encode F1 message */ + F1AP_F1AP_PDU_t *pdu = encode_f1ap_cu_configuration_update_acknowledge(msg); + /* encode F1AP PDU */ + if (!pdu || f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode GNB-CU-Configuration-Update-Acknowledge\n"); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return -1; } - - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 06d4318e97..5e07d15f4c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -2387,6 +2387,7 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofTNLAssociations_to_setup =0; F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofTNLAssociations_failed = 0; F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).noofDedicatedSIDeliveryNeededUEs = 0; + F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_ack_p).transaction_id = F1AP_get_next_transaction_identifier(0, 0); itti_send_msg_to_task (TASK_DU_F1, INSTANCE_DEFAULT, msg_ack_p); } diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 53b158aac0..c1c78943e5 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2512,6 +2512,12 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_f1_du_configuration_update(&F1AP_GNB_DU_CONFIGURATION_UPDATE(msg_p), msg_p->ittiMsgHeader.originInstance); break; + case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: + AssertFatal(!NODE_IS_DU(RC.nrrrc[instance]->node_type), + "should not receive F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE in DU!\n"); + LOG_E(NR_RRC, "Handling of F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE not implemented\n"); + break; + /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n"); From b91e1b0a12e97b2b898e2987372149ad1dc687e4 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 29 May 2024 22:51:57 +0200 Subject: [PATCH 44/73] Add enc/dec lib for F1AP gNB-DU Configuration Update Acknowledge (Interface Management) --- openair2/F1AP/lib/f1ap_interface_management.c | 148 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 16 ++ 2 files changed, 164 insertions(+) diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 7dad7452f7..cb0b6ab8aa 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -1617,3 +1617,151 @@ f1ap_gnb_cu_configuration_update_acknowledge_t cp_f1ap_cu_configuration_update_a cp.dedicatedSIDeliveryNeededUEs[i] = msg->dedicatedSIDeliveryNeededUEs[i]; return cp; } + +/* ================================== + * F1AP gNB-DU Configuration Ack + * ================================== */ + +/** + * @brief F1 gNB-DU Configuration Update Acknowledge message encoding (9.2.1.8 of 3GPP TS 38.473) + */ +F1AP_F1AP_PDU_t *encode_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + /* Create */ + /* 0. Message */ + pdu->present = F1AP_F1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu->choice.successfulOutcome, succOut); + succOut->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate; + succOut->criticality = F1AP_Criticality_reject; + succOut->value.present = F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge; + F1AP_GNBDUConfigurationUpdateAcknowledge_t *ack = &succOut->value.choice.GNBDUConfigurationUpdateAcknowledge; + /* Mandatory */ + /* Transaction Id */ + asn1cSequenceAdd(ack->protocolIEs.list, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t, ie1); + ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie1->criticality = F1AP_Criticality_reject; + ie1->value.present = F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID; + ie1->value.choice.TransactionID = msg->transaction_id; + // Cells to be Activated List (O) + for (int i = 0; i < msg->num_cells_to_activate; i++) { + asn1cSequenceAdd(ack->protocolIEs.list, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_to_be_Activated_List; + asn1cSequenceAdd(ie3->value.choice.Cells_to_be_Activated_List.list, + F1AP_Cells_to_be_Activated_List_ItemIEs_t, + cells_to_be_activated_ies); + encode_cells_to_activate(&msg->cells_to_activate[i], cells_to_be_activated_ies); + } + return pdu; +} + +/** + * @brief F1 gNB-DU Configuration Update Acknowledge decoding + */ +bool decode_f1ap_du_configuration_update_acknowledge(const F1AP_F1AP_PDU_t *pdu, + f1ap_gnb_du_configuration_update_acknowledge_t *out) +{ + /* message type */ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_successfulOutcome); + AssertError(pdu->choice.successfulOutcome != NULL, return false, "pdu->choice.successfulOutcome is NULL"); + _F1_EQ_CHECK_LONG(pdu->choice.successfulOutcome->procedureCode, F1AP_ProcedureCode_id_gNBDUConfigurationUpdate); + _F1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, + F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge); + F1AP_GNBDUConfigurationUpdateAcknowledge_t *in = &pdu->choice.successfulOutcome->value.choice.GNBDUConfigurationUpdateAcknowledge; + F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t *ie; + /* Check mandatory IEs */ + F1AP_LIB_FIND_IE(F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + _F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID); + AssertError(ie->value.choice.TransactionID != -1, return false, "ie->value.choice.TransactionID is -1"); + out->transaction_id = ie->value.choice.TransactionID; + break; + case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: { + /* Decode Cells Failed to be Activated List */ + _F1_EQ_CHECK_INT(ie->value.present, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_Cells_to_be_Activated_List); + F1AP_Cells_to_be_Activated_List_t *list = &ie->value.choice.Cells_to_be_Activated_List; + out->num_cells_to_activate = list->list.count; + for (int j = 0; j < out->num_cells_to_activate; j++) { + const F1AP_Cells_to_be_Activated_List_ItemIEs_t *itemIE = + (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)list->list.array[j]; + decode_cells_to_activate(&out->cells_to_activate[0], itemIE); + } + break; + } + default: + AssertError(1 == 0, return false, "F1AP_ProtocolIE_ID_id %ld unknown\n", ie->id); + break; + } + } + return true; +} + +/** + * @brief F1 gNB-DU Configuration Update Acknowledge equality check + */ +bool eq_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *a, + const f1ap_gnb_du_configuration_update_acknowledge_t *b) +{ + // Transaction ID + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + // number of cells to activate + _F1_EQ_CHECK_INT(a->num_cells_to_activate, b->num_cells_to_activate); + // loop over cells to activate + for (int i = 0; i < a->num_cells_to_activate; i++) { + _F1_EQ_CHECK_LONG(a->cells_to_activate[i].nr_cellid, b->cells_to_activate[i].nr_cellid); + _F1_EQ_CHECK_INT(a->cells_to_activate[i].nrpci, b->cells_to_activate[i].nrpci); + if (!eq_f1ap_plmn(&a->cells_to_activate[i].plmn, &b->cells_to_activate[i].plmn)) + return false; + _F1_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI); + for (int s = 0; s < a->cells_to_activate[i].num_SI; s++) { + _F1_EQ_CHECK_INT(*a->cells_to_activate[i].SI_msg[s].SI_container, *b->cells_to_activate[i].SI_msg[s].SI_container); + _F1_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_container_length, + b->cells_to_activate[i].SI_msg[s].SI_container_length); + _F1_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_type, b->cells_to_activate[i].SI_msg[s].SI_type); + } + } + return true; +} + +/** + * @brief F1 gNB-DU Configuration Update Acknowledge deep copy + */ +f1ap_gnb_du_configuration_update_acknowledge_t cp_f1ap_du_configuration_update_acknowledge( + const f1ap_gnb_du_configuration_update_acknowledge_t *msg) +{ + f1ap_gnb_du_configuration_update_acknowledge_t cp = {0}; + // Transaction ID + cp.transaction_id = msg->transaction_id; + // number of cells to activate + cp.num_cells_to_activate = msg->num_cells_to_activate; + // Loop through cells to activate + for (int i = 0; i < cp.num_cells_to_activate; i++) { + cp.cells_to_activate[i] = msg->cells_to_activate[i]; + for (int s = 0; s < cp.cells_to_activate[i].num_SI; s++) { + cp.cells_to_activate[i].SI_msg[s].SI_container = calloc_or_fail(1, sizeof(*cp.cells_to_activate[i].SI_msg[s].SI_container)); + *cp.cells_to_activate[i].SI_msg[s].SI_container = *msg->cells_to_activate[i].SI_msg[s].SI_container; + } + } + return cp; +} + +/** + * @brief gNB-DU Configuration Update Acknowledge memory management + */ +void free_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *msg) +{ + // SI_container + for (int i = 0; i < msg->num_cells_to_activate; i++) { + for (int j = 0; j < msg->cells_to_activate[i].num_SI; j++) { + if (msg->cells_to_activate[i].SI_msg[j].SI_container) { + free(msg->cells_to_activate[i].SI_msg[j].SI_container); + } + } + } +} diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index b368b5576f..bdceee9a61 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -62,5 +62,21 @@ void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t /* F1 gNB-CU Configuration Update Acknowledge */ struct F1AP_F1AP_PDU *encode_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *msg); +bool decode_f1ap_cu_configuration_update_acknowledge(const struct F1AP_F1AP_PDU *pdu, + f1ap_gnb_cu_configuration_update_acknowledge_t *out); +bool eq_f1ap_cu_configuration_update_acknowledge(const f1ap_gnb_cu_configuration_update_acknowledge_t *a, + const f1ap_gnb_cu_configuration_update_acknowledge_t *b); +f1ap_gnb_cu_configuration_update_acknowledge_t cp_f1ap_cu_configuration_update_acknowledge( + const f1ap_gnb_cu_configuration_update_acknowledge_t *msg); + +/* F1 gNB-DU Configuration Update Acknowledge */ +struct F1AP_F1AP_PDU *encode_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *msg); +bool decode_f1ap_du_configuration_update_acknowledge(const struct F1AP_F1AP_PDU *pdu, + f1ap_gnb_du_configuration_update_acknowledge_t *out); +bool eq_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *a, + const f1ap_gnb_du_configuration_update_acknowledge_t *b); +f1ap_gnb_du_configuration_update_acknowledge_t cp_f1ap_du_configuration_update_acknowledge( + const f1ap_gnb_du_configuration_update_acknowledge_t *msg); +void free_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *msg); #endif /* F1AP_INTERFACE_MANAGEMENT_H_ */ From b8ee622f1c2b532c44e6fd0fc56f884f000ed534 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 30 Aug 2024 00:29:19 +0200 Subject: [PATCH 45/73] Add test for F1 DU Configuration Update Acknowledge lib --- openair2/F1AP/tests/f1ap_lib_test.c | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 878c7fad78..969efc5afa 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -431,6 +431,52 @@ static void test_f1ap_du_configuration_update(void) free_f1ap_du_configuration_update(&orig); } +/** + * @brief Test F1 gNB-DU Configuration Update Acknowledge + */ +static void test_f1ap_du_configuration_update_acknowledge(void) +{ + // Create message + f1ap_gnb_du_configuration_update_acknowledge_t orig = { + .transaction_id = 5, + .num_cells_to_activate = 1, + .cells_to_activate = {{ + .nr_cellid = 987654321, + .nrpci = 50, + .plmn = {.mcc = 001, .mnc = 01, .mnc_digit_length = 2}, + .num_SI = 1, + .SI_msg = {{ + .SI_type = 7, + .SI_container_length = 10, + .SI_container = malloc(sizeof(uint8_t) * 10), + }}, + }}, + }; + for (int i = 0; i < orig.cells_to_activate[0].SI_msg[0].SI_container_length; i++) { + orig.cells_to_activate[0].SI_msg[0].SI_container[i] = i; + } + // ASN.1 enc/dec + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update_acknowledge(&orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + // Decoding + f1ap_gnb_du_configuration_update_acknowledge_t decoded = {0}; + bool ret = decode_f1ap_du_configuration_update_acknowledge(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_du_configuration_update_acknowledge(): could not decode message\n"); + f1ap_msg_free(f1dec); + // Equality check + ret = eq_f1ap_du_configuration_update_acknowledge(&orig, &decoded); + AssertFatal(ret, "eq_f1ap_du_configuration_update_acknowledge(): decoded message doesn't match\n"); + free_f1ap_du_configuration_update_acknowledge(&decoded); + // Deep copy + f1ap_gnb_du_configuration_update_acknowledge_t cp = cp_f1ap_du_configuration_update_acknowledge(&orig); + ret = eq_f1ap_du_configuration_update_acknowledge(&orig, &cp); + AssertFatal(ret, "eq_f1ap_du_configuration_update_acknowledge(): copied message doesn't match\n"); + // Free + free_f1ap_du_configuration_update_acknowledge(&cp); + free_f1ap_du_configuration_update_acknowledge(&orig); +} + /** * @brief Test F1 gNB-CU Configuration Update */ @@ -513,5 +559,6 @@ int main() test_f1ap_du_configuration_update(); test_f1ap_cu_configuration_update(); test_f1ap_cu_configuration_update_acknowledge(); + test_f1ap_du_configuration_update_acknowledge(); return 0; } From 3aa9f4c0becdd5fcabea331da213871cc7f8f6ff Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 29 May 2024 22:50:34 +0200 Subject: [PATCH 46/73] Use F1 gNB-DU Configuration Update Acknowledge lib in stack --- openair2/F1AP/f1ap_cu_interface_management.c | 38 +++++--------------- openair2/F1AP/f1ap_du_interface_management.c | 24 +++++++++++++ openair2/F1AP/f1ap_du_interface_management.h | 5 +++ openair2/F1AP/f1ap_handlers.c | 2 +- openair2/GNB_APP/gnb_app.c | 5 +++ 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index cd408c6720..aed1ae6d23 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -149,42 +149,20 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso return 0; } -int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE( - sctp_assoc_t assoc_id, - f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge) +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_du_configuration_update_acknowledge_t *msg) { - F1AP_F1AP_PDU_t pdu = {}; uint8_t *buffer; uint32_t len; - - /* Create */ - /* 0. Message */ - - pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; - asn1cCalloc(pdu.choice.successfulOutcome, succOut); - succOut->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate; - succOut->criticality = F1AP_Criticality_reject; - succOut->value.present = F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge; - F1AP_GNBDUConfigurationUpdateAcknowledge_t *ack = &succOut->value.choice.GNBDUConfigurationUpdateAcknowledge; - - /* Mandatory */ - /* Transaction Id */ - asn1cSequenceAdd(ack->protocolIEs.list, F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_TransactionID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID; - ie1->value.choice.TransactionID = GNBDUConfigurationUpdateAcknowledge->transaction_id; - - /* Todo add optional fields */ - /* encode */ - - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode F1 gNB-DU CONFIGURATION UPDATE\n"); + /* Encode F1 gNB-CU Configuration Update message */ + F1AP_F1AP_PDU_t *pdu = encode_f1ap_du_configuration_update_acknowledge(msg); + /* Encode F1AP PDU */ + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_E(F1AP, "Failed to encode F1 gNB-DU Configuration Update Acknowledge\n"); return -1; } - LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-DU CONFIGURATION UPDATE : "); - ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 391f9164eb..85e963ea6a 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -245,6 +245,30 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso return 0; } +/** + * @brief F1 gNB-DU Configuration Update Acknowledge decoding and message transfer + */ +int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + sctp_assoc_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) +{ + // Decoding + f1ap_gnb_du_configuration_update_acknowledge_t in = {0}; + if (!decode_f1ap_du_configuration_update_acknowledge(pdu, &in)) { + LOG_E(F1AP, "Failed to decode gNB-DU Configuration Update Acknowledge\n"); + free_f1ap_du_configuration_update_acknowledge(&in); + return -1; + } + // Allocate and send an ITTI message + MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE); + f1ap_gnb_du_configuration_update_acknowledge_t *msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg_p); + // Copy the decoded message to the ITTI message (RRC thread will free it) + *msg = in; // Copy the decoded message to the ITTI message (RRC thread will free it) + itti_send_msg_to_task(TASK_GNB_APP, GNB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + return 0; +} + 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", diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h index c8975a2361..bb5caf90df 100644 --- a/openair2/F1AP/f1ap_du_interface_management.h +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -64,4 +64,9 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge); +int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + sctp_assoc_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + #endif /* F1AP_DU_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index 544e763c49..6234dcd624 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -48,7 +48,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = { // {CU_handle_RESET, DU_handle_RESET_ACKNOWLEDGE, 0}, /* Reset */ {CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */ {0, 0, 0}, /* ErrorIndication */ - {CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */ + {CU_handle_gNB_DU_CONFIGURATION_UPDATE, DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE, 0}, /* gNBDUConfigurationUpdate */ {DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, 0}, /* gNBCUConfigurationUpdate */ {DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0}, /* UEContextSetup */ {DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0}, /* UEContextRelease */ diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index caaf5d64e7..0e7e25e2c0 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -247,6 +247,11 @@ void *gNB_app_task(void *args_p) AssertFatal(cell_to_activate == 1,"No cells to activate or cells > 1 %d\n",cell_to_activate); break; + + case F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE: + LOG_E(GNB_APP, "[gNB %ld] Handling of %s message not implemented yet\n", instance, msg_name); + break; + case NGAP_DEREGISTERED_GNB_IND: LOG_W(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name, NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf); From 5daad21ca61257ffbf4c97f4dd84644fba2c6dc6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 10 May 2024 11:50:18 +0200 Subject: [PATCH 47/73] Reworked F1AP documentation and added info about the library * moved F1AP related docs to a separate folder in docs --- doc/E1AP/E1-design.md | 2 +- doc/{ => F1AP}/F1-design.md | 0 doc/F1AP/F1AP-lib.md | 69 +++++++++++++++++++++++++++++++++++++ doc/README.md | 2 +- doc/UnitTests.md | 4 +++ 5 files changed, 75 insertions(+), 2 deletions(-) rename doc/{ => F1AP}/F1-design.md (100%) create mode 100644 doc/F1AP/F1AP-lib.md diff --git a/doc/E1AP/E1-design.md b/doc/E1AP/E1-design.md index 04d19bb514..4dd042f87d 100644 --- a/doc/E1AP/E1-design.md +++ b/doc/E1AP/E1-design.md @@ -79,7 +79,7 @@ More details about the E1AP procedures in OAI are available in this document: [E # 2. Running the E1 Split -The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](./../F1-design.md) for local deployment of the DU. +The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](./../F1AP/F1-design.md) for local deployment of the DU. ## 2.1 Configuration File diff --git a/doc/F1-design.md b/doc/F1AP/F1-design.md similarity index 100% rename from doc/F1-design.md rename to doc/F1AP/F1-design.md diff --git a/doc/F1AP/F1AP-lib.md b/doc/F1AP/F1AP-lib.md new file mode 100644 index 0000000000..46712914ed --- /dev/null +++ b/doc/F1AP/F1AP-lib.md @@ -0,0 +1,69 @@ + + + + + +
+ + + + + + F1AP Messages Encoding & Decoding Library +
+ +[[_TOC_]] + + +# Intro + +This library is for the encoding, decoding and testing of F1AP (F1 Application Protocol) messages. + +# Implementation Details + +The library includes the following components: + +1. **Common Functions**: + +This file [f1ap_lib_common.c](../../openair2/F1AP/lib/f1ap_lib_common.c) and its corresponding header contain utility functions and macros shared across different F1AP functions. + +2. **Message-Specific Modules**: + +Each F1AP message (e.g., DL RRC, UL RRC, etc.) has its corresponding modules and each module will include the encoder, decoder, equality check, and memory management functions specific to that message type. Specifically, the goal is to achieve the following: + +* **Encoder & Decoder**: Implement encoding and decoding functions for each F1AP message. These functions will convert F1AP messages coming from upper or lower layers into an F1AP PDU to be sent over F1 interface. +* **Equality Check (eq_X)**: `eq_X()` function that compares two messages for equality. This function is useful for testing purposes, ensuring that encoded and decoded messages match. +* **Deep Copy (cp_X)**: `cp_X()` function that performs a deep copy of a message. This function is beneficial when sending ITTI messages, as it avoids manual copying. +* **Memory Management (free_X)**: `free_X()` function to release memory associated with a message. Proper memory management helps prevent memory leaks. + +e.g. The following module contains functions that performs the encoding/decoding, equality check, deep copy and memory management for DL/UL RRC message transfer: + +* [f1ap_rrc_message_transfer.c](../../openair2/F1AP/lib/f1ap_rrc_message_transfer.c) + +# Testing + +The functions in the file [f1ap_lib_common.c](../../openair2/F1AP/tests/f1ap_lib_test.c) are used to test F1AP message encoding and decoding functionalities, according to the following steps: + +* call the encoder function for the message to be transferred into a F1AP PDU +* use `f1ap_encode_decode` to perform the following steps: + - Validates the input encoded PDU against constraints. + - Encodes the PDU using APER into a binary buffer. + - Decodes the binary buffer back into a PDU. + - Returns the decoded PDU. +* call the decoder function for the decoded F1AP PDU to obtain the decoded message +* call `eq_dl_rrc_message_transfer` to compare the original message with the decoded one +* call `cp_dl_rrc_message_transfer` to deep copy the original message, then compare the with the original one +* free all messages and PDUs + +A flowchart for a function testing F1AP messages, such as `test_f1ap_setup_request`, would look like this: + +```mermaid +flowchart TD + create[Create F1AP message]-->|f1ap_setup_req_t msg|enc[encode_f1ap_setup_request] + enc-->|F1AP_F1AP_PDU_t *f1enc|encdec[f1ap_encode_decode] + encdec-->|F1AP_F1AP_PDU_t *f1dec|dec[decode_f1ap_setup_request] + create-->|f1ap_setup_req_t msg|eq + dec-->|f1ap_setup_req_t decoded|eq[eq_f1ap_setup_request] + create-->|f1ap_setup_req_t msg|cp[cp_f1ap_setup_request] + cp-->|f1ap_setup_req_t cp|eq[eq_f1ap_setup_request] +``` diff --git a/doc/README.md b/doc/README.md index 70e8bf05be..7f57a24eb0 100644 --- a/doc/README.md +++ b/doc/README.md @@ -65,7 +65,7 @@ Legacy unmaintained files: - General software architecture notes: [SW_archi.md](./SW_archi.md) - [Information on E1](./E1AP/E1-design.md) -- [Information on F1](./F1-design.md) +- [Information on F1](./F1AP/F1-design.md) - [Information on how NR nFAPI works](./NR_NFAPI_archi.md) - [Flow graph of the L1 in gNB](SW-archi-graph.md) - [L1 threads in NR-UE](./nr-ue-design.md) diff --git a/doc/UnitTests.md b/doc/UnitTests.md index aa6b7b1123..76cfe7bee1 100644 --- a/doc/UnitTests.md +++ b/doc/UnitTests.md @@ -24,6 +24,10 @@ cmake .. -GNinja -DENABLE_TESTS=ON ninja tests ``` +The user can use either `ninja` or `make`. + +# Run unit tests + Then, you can run `ctest` to run all tests: ```bash From 7986a4de8e6382f5a3c5439eb1522d0b92b8a3c0 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Mon, 30 Sep 2024 20:34:09 +0200 Subject: [PATCH 48/73] Time domain samples scope for NR UE Add a new scope data source (ueTimeDomainSamples) which provides time domain samples for antenna 0 to the scope. Add graphical representation of the data in imscope. Removed C-define from ENABLE_IMSCOPE cmake option, the #define was unused and this way code does not have to be recompiled when imscope enable state changes. --- CMakeLists.txt | 2 +- executables/nr-ue.c | 2 ++ openair1/PHY/TOOLS/imscope/imscope.cpp | 10 ++++++++++ openair1/PHY/TOOLS/phy_scope_interface.h | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 627b87593d..fcae675910 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -293,7 +293,7 @@ set_property(CACHE KPM_VERSION PROPERTY STRINGS "KPM_V2_03" "KPM_V3_00") message(STATUS "Selected KPM Version: ${KPM_VERSION}") -add_boolean_option(ENABLE_IMSCOPE OFF "Enable phy scope based on imgui" ON) +add_boolean_option(ENABLE_IMSCOPE OFF "Enable phy scope based on imgui" OFF) ################################################## # ASN.1 grammar C code generation & dependencies # diff --git a/executables/nr-ue.c b/executables/nr-ue.c index a742ea2e9d..16fef82eea 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -37,6 +37,7 @@ #include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "RRC/NR/MESSAGES/asn1_msg.h" +#include "openair1/PHY/TOOLS/phy_scope_interface.h" /* * NR SLOT PROCESSING SEQUENCE @@ -958,6 +959,7 @@ void *UE_thread(void *arg) const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply; openair0_timestamp rx_timestamp; int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, &rx_timestamp, rxp, readBlockSize, fp->nb_antennas_rx); + UEscopeCopy(UE, ueTimeDomainSamples, rxp[0], sizeof(c16_t), 1, readBlockSize, 0); AssertFatal(readBlockSize == tmp, ""); if(slot_nr == (nb_slot_frame - 1)) { diff --git a/openair1/PHY/TOOLS/imscope/imscope.cpp b/openair1/PHY/TOOLS/imscope/imscope.cpp index 8205c85b9e..c216156777 100644 --- a/openair1/PHY/TOOLS/imscope/imscope.cpp +++ b/openair1/PHY/TOOLS/imscope/imscope.cpp @@ -480,6 +480,16 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t) pdsch_iq_hist->Draw(iq_data, t, new_data); ImGui::TreePop(); } + if (ImGui::TreeNode("Time domain samples")) { + static auto iq_data = new IQData(); + static auto time_domain_iq = new IQHist("Time domain samples"); + bool new_data = false; + if (time_domain_iq->ShouldReadData()) { + new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamples], t, time_domain_iq->GetEpsilon()); + } + time_domain_iq->Draw(iq_data, t, new_data); + ImGui::TreePop(); + } if (ImGui::TreeNode("Broadcast channel")) { ImGui::Text("RSRP %d", ue->measurements.ssb_rsrp_dBm[ue->frame_parms.ssb_index]); if (ImGui::TreeNode("IQ")) { diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h index 2f8378e7b7..2d648faa90 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.h +++ b/openair1/PHY/TOOLS/phy_scope_interface.h @@ -73,6 +73,7 @@ enum scopeDataType { MAX_SCOPE_TYPES, gNBPuschRxIq = MAX_SCOPE_TYPES, gNBPuschLlr, + ueTimeDomainSamples, EXTRA_SCOPE_TYPES }; From 43a9236963aea7e280fb405ba902eb66a97f924c Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 13 Sep 2024 13:50:01 +0200 Subject: [PATCH 49/73] Improve imscope's scatterplot - Reduce point size to 1 pixel - call ImPlot::PlotScatter as many times as needed --- openair1/PHY/TOOLS/imscope/imscope.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/TOOLS/imscope/imscope.cpp b/openair1/PHY/TOOLS/imscope/imscope.cpp index c216156777..bba22402a3 100644 --- a/openair1/PHY/TOOLS/imscope/imscope.cpp +++ b/openair1/PHY/TOOLS/imscope/imscope.cpp @@ -279,8 +279,17 @@ class IQHist { } } else if (plot_type == 1) { if (ImPlot::BeginPlot(label.c_str(), {(float)ImGui::GetWindowWidth() * 0.3f, (float)ImGui::GetWindowWidth() * 0.3f})) { - // Limit the amount of data plotted with scatterplot (issue with vertices/draw call) - ImPlot::PlotScatter(label.c_str(), iq_data->real.data(), iq_data->imag.data(), std::min(16000, iq_data->len)); + int points_drawn = 0; + while (points_drawn < iq_data->len) { + // Limit the amount of data plotted with PlotScatter call (issue with vertices/draw call) + int points_to_draw = std::min(iq_data->len - points_drawn, 16000); + ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle, 1, IMPLOT_AUTO_COL, 1); + ImPlot::PlotScatter(label.c_str(), + iq_data->real.data() + points_drawn, + iq_data->imag.data() + points_drawn, + points_to_draw); + points_drawn += points_to_draw; + } ImPlot::EndPlot(); } } else if (plot_type == 2) { From 80f90b55991d1e9c9e8b8f7c20265d24ddd34372 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 13 Sep 2024 14:03:18 +0200 Subject: [PATCH 50/73] Add time domain sample scope before sync Added new data sync for UE which displays time domain samples read from RF device before synchronization to PSS/SSS --- executables/nr-ue.c | 6 ++++-- openair1/PHY/TOOLS/imscope/imscope.cpp | 10 ++++++++++ openair1/PHY/TOOLS/phy_scope_interface.h | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 16fef82eea..d4c3b964fd 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -707,8 +707,10 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) + 4 * ((x * fp->samples_per_subframe) + fp->get_samples_slot_timestamp(slot, fp, 0)); } - int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, rxp, fp->get_samples_per_slot(slot, fp), fp->nb_antennas_rx); - AssertFatal(fp->get_samples_per_slot(slot, fp) == tmp, ""); + int read_block_size = fp->get_samples_per_slot(slot, fp); + int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, rxp, read_block_size, fp->nb_antennas_rx); + UEscopeCopy(UE, ueTimeDomainSamplesBeforeSync, rxp[0], sizeof(c16_t), 1, read_block_size, 0); + AssertFatal(read_block_size == tmp, ""); if (IS_SOFTMODEM_RFSIM) dummyWrite(UE, *timestamp, fp->get_samples_per_slot(slot, fp)); diff --git a/openair1/PHY/TOOLS/imscope/imscope.cpp b/openair1/PHY/TOOLS/imscope/imscope.cpp index bba22402a3..de555332bc 100644 --- a/openair1/PHY/TOOLS/imscope/imscope.cpp +++ b/openair1/PHY/TOOLS/imscope/imscope.cpp @@ -499,6 +499,16 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t) time_domain_iq->Draw(iq_data, t, new_data); ImGui::TreePop(); } + if (ImGui::TreeNode("Time domain samples - before sync")) { + static auto iq_data = new IQData(); + static auto time_domain_iq = new IQHist("Time domain samples - before sync"); + bool new_data = false; + if (time_domain_iq->ShouldReadData()) { + new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamplesBeforeSync], t, time_domain_iq->GetEpsilon()); + } + time_domain_iq->Draw(iq_data, t, new_data); + ImGui::TreePop(); + } if (ImGui::TreeNode("Broadcast channel")) { ImGui::Text("RSRP %d", ue->measurements.ssb_rsrp_dBm[ue->frame_parms.ssb_index]); if (ImGui::TreeNode("IQ")) { diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h index 2d648faa90..5602ed40de 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.h +++ b/openair1/PHY/TOOLS/phy_scope_interface.h @@ -74,6 +74,7 @@ enum scopeDataType { gNBPuschRxIq = MAX_SCOPE_TYPES, gNBPuschLlr, ueTimeDomainSamples, + ueTimeDomainSamplesBeforeSync, EXTRA_SCOPE_TYPES }; From b2c49fbc27493ee6f8dfc9604b5512a0ad3ba8b1 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Mon, 30 Sep 2024 20:41:08 +0200 Subject: [PATCH 51/73] Add time-domain scope to gNB imscope. --- executables/nr-ru.c | 1 + openair1/PHY/TOOLS/imscope/imscope.cpp | 11 +++++++++++ openair1/PHY/TOOLS/phy_scope_interface.h | 5 +++-- openair1/PHY/defs_RU.h | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 8a29e6ac2f..ee78346cf4 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -622,6 +622,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) rxp, samples_per_slot, ru->nb_rx); + gNBscopeCopy(ru, gNbTimeDomainSamples, rxp[0], sizeof(c16_t), 1, samples_per_slot, 0); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); diff --git a/openair1/PHY/TOOLS/imscope/imscope.cpp b/openair1/PHY/TOOLS/imscope/imscope.cpp index de555332bc..054fcdad79 100644 --- a/openair1/PHY/TOOLS/imscope/imscope.cpp +++ b/openair1/PHY/TOOLS/imscope/imscope.cpp @@ -581,6 +581,16 @@ void ShowGnbScope(PHY_VARS_gNB *gNB, float t) pusch_llr_plot->Draw(t, gNBPuschLlr, "PUSCH LLR"); ImGui::TreePop(); } + if (ImGui::TreeNode("Time domain samples")) { + static auto iq_data = new IQData(); + static auto time_domain_iq = new IQHist("Time domain samples"); + bool new_data = false; + if (time_domain_iq->ShouldReadData()) { + new_data = iq_data->TryCollect(&scope_array[gNbTimeDomainSamples], t, time_domain_iq->GetEpsilon()); + } + time_domain_iq->Draw(iq_data, t, new_data); + ImGui::TreePop(); + } } void *imscope_thread(void *data_void_ptr) @@ -751,6 +761,7 @@ extern "C" void imscope_autoinit(void *dataptr) scope->copyDataUnsafeWithOffset = copyDataUnsafeWithOffset; scope->unlockScopeData = unlockScopeData; scope_params->gNB->scopeData = scope; + scope_params->ru->scopeData = scope; } else { PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)dataptr; scopeData_t *scope = (scopeData_t *)calloc(1, sizeof(scopeData_t)); diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h index 5602ed40de..2fa97880b4 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.h +++ b/openair1/PHY/TOOLS/phy_scope_interface.h @@ -75,6 +75,7 @@ enum scopeDataType { gNBPuschLlr, ueTimeDomainSamples, ueTimeDomainSamplesBeforeSync, + gNbTimeDomainSamples, EXTRA_SCOPE_TYPES }; @@ -129,12 +130,12 @@ void copyData(void *, enum scopeDataType type, void *dataIn, int elementSz, int } #define gNBscopeCopyWithMetadata(gnb, type, ...) \ if (gnb->scopeData) { \ - ((scopeData_t *)gnb->scopeData)->copyData((scopeData_t *)gNB->scopeData, type, ##__VA_ARGS__); \ + ((scopeData_t *)gnb->scopeData)->copyData((scopeData_t *)gnb->scopeData, type, ##__VA_ARGS__); \ } #define gNBscopeCopy(gnb, type, ...) \ if (gnb->scopeData) { \ metadata mt = {.slot = -1, .frame = -1}; \ - ((scopeData_t *)gnb->scopeData)->copyData((scopeData_t *)gNB->scopeData, type, ##__VA_ARGS__, &mt); \ + ((scopeData_t *)gnb->scopeData)->copyData((scopeData_t *)gnb->scopeData, type, ##__VA_ARGS__, &mt); \ } #define GnbScopeUpdate(gnb, type, numElt) \ if (gnb->scopeData) \ diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 2f564eac6b..3b7b7f2ba0 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -661,7 +661,8 @@ typedef struct RU_t_s { /// number of cores for RU ThreadPool int num_tpcores; /// structure for analyzing high-level RT measurements - rt_ru_profiling_t rt_ru_profiling; + rt_ru_profiling_t rt_ru_profiling; + void* scopeData; } RU_t; From 53d31eb26e2f022da19e2f69ae391d150dced4cf Mon Sep 17 00:00:00 2001 From: Ghislain Bourgeois Date: Mon, 9 Sep 2024 18:14:53 -0400 Subject: [PATCH 52/73] Use getaddrinfo() when connecting to rfsimulator This commits uses getaddrinfo(3) when connecting as client to the rfsimulator. This enables name lookups, through DNS or a hosts file. This change makes it easier to use the simulator in a dynamic environment like Docker or Kubernetes by only targeting the name of the container or service. --- radio/rfsimulator/simulator.c | 60 ++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index c5197eaab8..776bbf73cc 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -38,6 +39,8 @@ #include #include #include +#include + #include #include #include @@ -577,27 +580,62 @@ static int startServer(openair0_device *device) { return 0; } -static int startClient(openair0_device *device) { +static int client_try_connect(const char *host, uint16_t port) +{ + int sock = -1; + int s; + struct addrinfo *result = NULL; + struct addrinfo *rp = NULL; + + char dport[6]; + snprintf(dport, sizeof(dport), "%d", port); + + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + }; + + s = getaddrinfo(host, dport, &hints, &result); + if (s != 0) { + LOG_I(HW, "getaddrinfo: %s\n", gai_strerror(s)); + return -1; + } + for (rp = result; rp != NULL; rp = rp->ai_next) { + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sock == -1) { + continue; + } + + if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) { + LOG_I(HW, "Connection to %s:%d established\n", host, port); + break; + } + + close(sock); + } + + freeaddrinfo(result); + + return sock; +} + +static int startClient(openair0_device *device) +{ rfsimulator_state_t *t = device->priv; t->role = SIMU_ROLE_CLIENT; int sock; - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - LOG_E(HW, "socket(SOCK_STREAM) failed, errno(%d)\n", errno); - return -1; - } - struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(t->port), .sin_addr = {.s_addr = INADDR_ANY}}; - addr.sin_addr.s_addr = inet_addr(t->ip); - bool connected=false; - while(!connected) { + while (true) { LOG_I(HW, "Trying to connect to %s:%d\n", t->ip, t->port); + sock = client_try_connect(t->ip, t->port); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + if (sock > 0) { LOG_I(HW, "Connection to %s:%d established\n", t->ip, t->port); - connected=true; + break; } LOG_I(HW, "connect() to %s:%d failed, errno(%d)\n", t->ip, t->port, errno); + fprintf(stderr, "Could not connect\n"); sleep(1); } From 320747e0b0a85e09cb21da2963e5d1fc4ef66544 Mon Sep 17 00:00:00 2001 From: Ghislain Bourgeois Date: Fri, 20 Sep 2024 15:22:10 -0400 Subject: [PATCH 53/73] Use getaddrinfo() and add IPv6 support in startServer This commit refactors startServer to use getaddrinfo() to prepare the socket creation. Doing so, it also adds support for IPv6 by using AF_UNSPEC as the address family. --- radio/rfsimulator/simulator.c | 63 +++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 776bbf73cc..02f05b1e25 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -547,30 +547,67 @@ static int rfsimu_vtime_cmd(char *buff, int debug, telnet_printfunc_t prnt, void return CMDSTATUS_FOUND; } -static int startServer(openair0_device *device) { - rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; +static int startServer(openair0_device *device) +{ + int sock = -1; + struct addrinfo *results = NULL; + struct addrinfo *rp= NULL; + + rfsimulator_state_t *t = (rfsimulator_state_t *)device->priv; t->role = SIMU_ROLE_SERVER; - t->listen_sock = socket(AF_INET, SOCK_STREAM, 0); - if (t->listen_sock < 0) { - LOG_E(HW, "socket(SOCK_STREAM) failed, errno(%d)\n", errno); + + char port[6]; + snprintf(port, sizeof(port), "%d", t->port); + + struct addrinfo hints = { + .ai_family = AF_INET6, + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_PASSIVE, + }; + + int s = getaddrinfo(NULL, port, &hints, &results); + if (s != 0) { + LOG_E(HW, "getaddrinfo: %s\n", gai_strerror(s)); + freeaddrinfo(results); return -1; } + int enable = 1; - if (setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) != 0) { - LOG_E(HW, "setsockopt(SO_REUSEADDR) failed, errno(%d)\n", errno); - return -1; + int disable = 0; + for (rp = results; rp != NULL; rp = rp->ai_next) { + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sock == -1) { + continue; + } + + if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &disable, sizeof(int)) != 0) { + continue; + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) != 0) { + continue; + } + + if (bind(sock, rp->ai_addr, rp->ai_addrlen) == 0) { + break; + } + + close(sock); } - struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(t->port), .sin_addr = {.s_addr = INADDR_ANY}}; - int rc = bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr)); - if (rc < 0) { - LOG_E(HW, "bind() failed, errno(%d)\n", errno); + + freeaddrinfo(results); + + if (sock <= 0) { + LOG_E(HW, "could not open a socket\n"); return -1; } + t->listen_sock = sock; + if (listen(t->listen_sock, 5) != 0) { LOG_E(HW, "listen() failed, errno(%d)\n", errno); return -1; } - struct epoll_event ev= {0}; + struct epoll_event ev = {0}; ev.events = EPOLLIN; ev.data.fd = t->listen_sock; if (epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != 0) { From 5811ab1dc84f56004747989a784947b9083ec76f Mon Sep 17 00:00:00 2001 From: Thomas Laurent Date: Wed, 2 Oct 2024 09:11:49 +0000 Subject: [PATCH 54/73] Apply 2 suggestion(s) to 2 file(s) Co-authored-by: Robert Schmidt --- executables/nr-ue.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 55a012106d..ef1c6ab29f 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -815,7 +815,7 @@ void *UE_thread(void *arg) } else { //warm up the RF board int64_t tmp; - for (int i=0; i< 50; i++) + for (int i = 0; i < 50; i++) readFrame(UE, &tmp, true); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index f61cb715dd..85b612c1a8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -202,7 +202,7 @@ void nr_scan_ssb(void *arg) /* process pss search on received buffer */ ssbInfo->syncRes.frame_id = frame_id; int nid2; - int freq_offset_pss=0; + int freq_offset_pss = 0; const int sync_pos = pss_synchro_nr((const c16_t **)rxdata, fp, pssTime, From 13757cfd28bc4f5baea057011cbf6614a1ecb474 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 8 Aug 2024 11:44:29 +0200 Subject: [PATCH 55/73] Cleanup of long-time commented out code in prepare_scc --- openair2/GNB_APP/gnb_config.c | 42 ----------------------------------- 1 file changed, 42 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index d1ed728f35..d6b2df978c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -101,11 +101,6 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { NR_FreqBandIndicatorNR_t *dl_frequencyBandList,*ul_frequencyBandList; struct NR_SCS_SpecificCarrier *dl_scs_SpecificCarrierList,*ul_scs_SpecificCarrierList; - // struct NR_RateMatchPattern *ratematchpattern; - // NR_RateMatchPatternId_t *ratematchpatternid; - // NR_TCI_StateId_t *TCI_StateId; - // struct NR_ControlResourceSet *bwp_dl_controlresourceset; - // NR_SearchSpace_t *bwp_dl_searchspace; scc->physCellId = CALLOC(1,sizeof(NR_PhysCellId_t)); scc->downlinkConfigCommon = CALLOC(1,sizeof(struct NR_DownlinkConfigCommon)); @@ -114,12 +109,9 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { scc->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommon)); scc->uplinkConfigCommon->frequencyInfoUL = CALLOC(1,sizeof(struct NR_FrequencyInfoUL)); scc->uplinkConfigCommon->initialUplinkBWP = CALLOC(1,sizeof(struct NR_BWP_UplinkCommon)); - //scc->supplementaryUplinkConfig = CALLOC(1,sizeof(struct NR_UplinkConfigCommon)); scc->n_TimingAdvanceOffset = CALLOC(1, sizeof(long)); scc->ssb_PositionsInBurst = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__ssb_PositionsInBurst)); scc->ssb_periodicityServingCell = CALLOC(1,sizeof(long)); - // scc->rateMatchPatternToAddModList = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__rateMatchPatternToAddModList)); - // scc->rateMatchPatternToReleaseList = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__rateMatchPatternToReleaseList)); scc->ssbSubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); scc->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); scc->tdd_UL_DL_ConfigurationCommon->pattern2 = CALLOC(1,sizeof(struct NR_TDD_UL_DL_Pattern)); @@ -131,7 +123,6 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { asn1cSeqAdd(&scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list,dl_frequencyBandList); asn1cSeqAdd(&scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list,dl_scs_SpecificCarrierList); - // scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix = CALLOC(1,sizeof(long)); scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PDCCH_ConfigCommon)); scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->present=NR_SetupRelease_PDCCH_ConfigCommon_PR_setup; scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon)); @@ -140,11 +131,6 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = NULL; - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->pagingSearchSpace = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace = CALLOC(1,sizeof(NR_SearchSpaceId_t)); scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PDSCH_ConfigCommon)); scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->present = NR_SetupRelease_PDSCH_ConfigCommon_PR_setup; scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDSCH_ConfigCommon)); @@ -155,22 +141,15 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { asn1cSeqAdd(&scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list,ul_frequencyBandList); scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = CALLOC(1,sizeof(NR_ARFCN_ValueNR_t)); - // scc->uplinkConfigCommon->frequencyInfoUL->additionalSpectrumEmission = CALLOC(1,sizeof(NR_AdditionalSpectrumEmission_t)); scc->uplinkConfigCommon->frequencyInfoUL->p_Max = CALLOC(1,sizeof(NR_P_Max_t)); - // scc->uplinkConfigCommon->frequencyInfoUL->frequencyShift7p5khz = CALLOC(1,sizeof(long)); - // scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix = CALLOC(1,sizeof(long)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_RACH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->present = NR_SetupRelease_RACH_ConfigCommon_PR_setup; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon)); - // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles = CALLOC(1,sizeof(long)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB)); - // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->groupBconfigured = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__groupBconfigured)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = CALLOC(1,sizeof(NR_RSRP_Range_t)); - // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); - // 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED. *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; @@ -189,30 +168,9 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon = CALLOC(1,sizeof(long)); scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId = CALLOC(1,sizeof(long)); - // scc->ssb_PositionsInBurst->choice.shortBitmap.buf = MALLOC(1); - // scc->ssb_PositionsInBurst->choice.mediumBitmap.buf = MALLOC(1); - // scc->ssb_PositionsInBurst->choice.longBitmap.buf = MALLOC(8); - - ul_scs_SpecificCarrierList = CALLOC(1,sizeof(struct NR_SCS_SpecificCarrier)); asn1cSeqAdd(&scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list,ul_scs_SpecificCarrierList); - //ratematchpattern = CALLOC(1,sizeof(struct NR_RateMatchPattern)); - //ratematchpattern->patternType.choice.bitmaps = CALLOC(1,sizeof(struct NR_RateMatchPattern__patternType__bitmaps)); - //ratematchpattern->patternType.choice.bitmaps->resourceBlocks.buf = MALLOC(35); - //ratematchpattern->patternType.choice.bitmaps->symbolsInResourceBlock.choice.oneSlot.buf = MALLOC(2); - //ratematchpattern->patternType.choice.bitmaps->symbolsInResourceBlock.choice.twoSlots.buf = MALLOC(4); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern = CALLOC(1,sizeof(struct NR_RateMatchPattern__patternType__bitmaps__periodicityAndPattern)); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n2.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n4.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n5.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n8.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n10.buf = MALLOC(2); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n20.buf = MALLOC(3); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n40.buf = MALLOC(5); - //ratematchpattern->subcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); - //ratematchpatternid = CALLOC(1,sizeof(NR_RateMatchPatternId_t)); - scc->ext2 = CALLOC(1, sizeof(*scc->ext2)); scc->ext2->ntn_Config_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17)); scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17)); From ee26e51015d3b59e382622348c241e7261ee38e4 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 25 Sep 2024 11:16:23 +0200 Subject: [PATCH 56/73] Use abort instead to exit in calloc_or_fail * abort generates a core dump --- common/utils/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/utils.h b/common/utils/utils.h index 082d1dd635..841cb2af9c 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -75,7 +75,7 @@ static inline void *calloc_or_fail(size_t nmemb, size_t size) if (ptr == NULL) { fprintf(stderr, "Failed to calloc() %zu elements of %zu bytes: out of memory", nmemb, size); - exit(EXIT_FAILURE); + abort(); } return ptr; From 56e510b2f29165be9fdb9bb57baf32785703ef0b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 25 Sep 2024 11:19:38 +0200 Subject: [PATCH 57/73] Use calloc_or_fail in gnb_config.c --- openair2/GNB_APP/gnb_config.c | 97 +++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index d6b2df978c..2195acefb1 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -431,90 +431,99 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) /* Function to allocate dedicated serving cell config strutures */ void prepare_scd(NR_ServingCellConfig_t *scd) { // Allocate downlink structures - scd->downlinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->downlinkBWP_ToAddModList)); - scd->uplinkConfig = CALLOC(1, sizeof(*scd->uplinkConfig)); - scd->uplinkConfig->uplinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->uplinkConfig->uplinkBWP_ToAddModList)); - scd->bwp_InactivityTimer = CALLOC(1, sizeof(*scd->bwp_InactivityTimer)); - scd->uplinkConfig->firstActiveUplinkBWP_Id = CALLOC(1, sizeof(*scd->uplinkConfig->firstActiveUplinkBWP_Id)); - scd->firstActiveDownlinkBWP_Id = CALLOC(1, sizeof(*scd->firstActiveDownlinkBWP_Id)); + scd->downlinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*scd->downlinkBWP_ToAddModList)); + scd->uplinkConfig = calloc_or_fail(1, sizeof(*scd->uplinkConfig)); + scd->uplinkConfig->uplinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*scd->uplinkConfig->uplinkBWP_ToAddModList)); + scd->bwp_InactivityTimer = calloc_or_fail(1, sizeof(*scd->bwp_InactivityTimer)); + scd->uplinkConfig->firstActiveUplinkBWP_Id = calloc_or_fail(1, sizeof(*scd->uplinkConfig->firstActiveUplinkBWP_Id)); + scd->firstActiveDownlinkBWP_Id = calloc_or_fail(1, sizeof(*scd->firstActiveDownlinkBWP_Id)); *scd->firstActiveDownlinkBWP_Id = 1; *scd->uplinkConfig->firstActiveUplinkBWP_Id = 1; - scd->defaultDownlinkBWP_Id = CALLOC(1, sizeof(*scd->defaultDownlinkBWP_Id)); + scd->defaultDownlinkBWP_Id = calloc_or_fail(1, sizeof(*scd->defaultDownlinkBWP_Id)); *scd->defaultDownlinkBWP_Id = 0; for (int j = 0; j < NR_MAX_NUM_BWP; j++) { // Downlink bandwidth part - NR_BWP_Downlink_t *bwp = calloc(1, sizeof(*bwp)); + NR_BWP_Downlink_t *bwp = calloc_or_fail(1, sizeof(*bwp)); bwp->bwp_Id = j+1; // Allocate downlink dedicated bandwidth part and PDSCH structures - bwp->bwp_Common = calloc(1, sizeof(*bwp->bwp_Common)); - bwp->bwp_Common->pdcch_ConfigCommon = calloc(1, sizeof(*bwp->bwp_Common->pdcch_ConfigCommon)); - bwp->bwp_Common->pdsch_ConfigCommon = calloc(1, sizeof(*bwp->bwp_Common->pdsch_ConfigCommon)); - bwp->bwp_Dedicated = calloc(1, sizeof(*bwp->bwp_Dedicated)); - bwp->bwp_Dedicated->pdsch_Config = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config)); - bwp->bwp_Dedicated->pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup; - bwp->bwp_Dedicated->pdsch_Config->choice.setup = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present = NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; + bwp->bwp_Common = calloc_or_fail(1, sizeof(*bwp->bwp_Common)); + bwp->bwp_Common->pdcch_ConfigCommon = calloc_or_fail(1, sizeof(*bwp->bwp_Common->pdcch_ConfigCommon)); + bwp->bwp_Common->pdsch_ConfigCommon = calloc_or_fail(1, sizeof(*bwp->bwp_Common->pdsch_ConfigCommon)); + bwp->bwp_Dedicated = calloc_or_fail(1, sizeof(*bwp->bwp_Dedicated)); + bwp->bwp_Dedicated->pdsch_Config = calloc_or_fail(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config)); + struct NR_SetupRelease_PDSCH_Config *pdsch_Config = bwp->bwp_Dedicated->pdsch_Config; + pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup; + pdsch_Config->choice.setup = calloc_or_fail(1, sizeof(*pdsch_Config->choice.setup)); + struct NR_PDSCH_Config *pc_setup = pdsch_Config->choice.setup; + pc_setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc_or_fail(1, sizeof(*pc_setup->dmrs_DownlinkForPDSCH_MappingTypeA)); + struct NR_SetupRelease_DMRS_DownlinkConfig *typeA = pc_setup->dmrs_DownlinkForPDSCH_MappingTypeA; + typeA->present = NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; // Allocate DL DMRS and PTRS configuration - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); - NR_DMRS_DownlinkConfig_t *NR_DMRS_DownlinkCfg = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; - NR_DMRS_DownlinkCfg->phaseTrackingRS=CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS)); + typeA->choice.setup = calloc_or_fail(1, sizeof(*typeA->choice.setup)); + NR_DMRS_DownlinkConfig_t *NR_DMRS_DownlinkCfg = typeA->choice.setup; + NR_DMRS_DownlinkCfg->phaseTrackingRS = calloc_or_fail(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS)); NR_DMRS_DownlinkCfg->phaseTrackingRS->present = NR_SetupRelease_PTRS_DownlinkConfig_PR_setup; - NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup)); + NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup = + calloc_or_fail(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup)); NR_PTRS_DownlinkConfig_t *NR_PTRS_DownlinkCfg = NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup; - NR_PTRS_DownlinkCfg->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->frequencyDensity)); - long *dl_rbs = CALLOC(2, sizeof(long)); + NR_PTRS_DownlinkCfg->frequencyDensity = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->frequencyDensity)); + long *dl_rbs = calloc_or_fail(2, sizeof(*dl_rbs)); for (int i=0;i<2;i++) { asn1cSeqAdd(&NR_PTRS_DownlinkCfg->frequencyDensity->list, &dl_rbs[i]); } - NR_PTRS_DownlinkCfg->timeDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->timeDensity)); - long *dl_mcs = CALLOC(3, sizeof(long)); + NR_PTRS_DownlinkCfg->timeDensity = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->timeDensity)); + long *dl_mcs = calloc_or_fail(3, sizeof(*dl_mcs)); for (int i=0;i<3;i++) { asn1cSeqAdd(&NR_PTRS_DownlinkCfg->timeDensity->list, &dl_mcs[i]); } - NR_PTRS_DownlinkCfg->epre_Ratio = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->epre_Ratio)); - NR_PTRS_DownlinkCfg->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->resourceElementOffset)); + NR_PTRS_DownlinkCfg->epre_Ratio = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->epre_Ratio)); + NR_PTRS_DownlinkCfg->resourceElementOffset = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->resourceElementOffset)); *NR_PTRS_DownlinkCfg->resourceElementOffset = 0; asn1cSeqAdd(&scd->downlinkBWP_ToAddModList->list,bwp); // Allocate uplink structures - NR_PUSCH_Config_t *pusch_Config = CALLOC(1, sizeof(*pusch_Config)); + NR_PUSCH_Config_t *pusch_Config = calloc_or_fail(1, sizeof(*pusch_Config)); // Allocate UL DMRS and PTRS structures - pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = CALLOC(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB)); + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = calloc_or_fail(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB)); pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup; - pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = CALLOC(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = + calloc_or_fail(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; - NR_DMRS_UplinkConfig->phaseTrackingRS = CALLOC(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS)); + NR_DMRS_UplinkConfig->phaseTrackingRS = calloc_or_fail(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS)); NR_DMRS_UplinkConfig->phaseTrackingRS->present = NR_SetupRelease_PTRS_UplinkConfig_PR_setup; - NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup)); + NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup = + calloc_or_fail(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup)); NR_PTRS_UplinkConfig_t *NR_PTRS_UplinkConfig = NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup; - NR_PTRS_UplinkConfig->transformPrecoderDisabled = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled)); - NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity)); - long *n_rbs = CALLOC(2, sizeof(long)); + NR_PTRS_UplinkConfig->transformPrecoderDisabled = calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled)); + NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity = + calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity)); + long *n_rbs = calloc_or_fail(2, sizeof(*n_rbs)); for (int i=0;i<2;i++) { asn1cSeqAdd(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, &n_rbs[i]); } - NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity)); - long *ptrs_mcs = CALLOC(3, sizeof(long)); + NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity = + calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity)); + long *ptrs_mcs = calloc_or_fail(3, sizeof(*ptrs_mcs)); for (int i = 0; i < 3; i++) { asn1cSeqAdd(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, &ptrs_mcs[i]); } - NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset)); + NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = + calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset)); *NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = 0; // UL bandwidth part - NR_BWP_Uplink_t *ubwp = CALLOC(1, sizeof(*ubwp)); + NR_BWP_Uplink_t *ubwp = calloc_or_fail(1, sizeof(*ubwp)); ubwp->bwp_Id = j+1; - ubwp->bwp_Common = CALLOC(1, sizeof(*ubwp->bwp_Common)); - ubwp->bwp_Dedicated = CALLOC(1, sizeof(*ubwp->bwp_Dedicated)); + ubwp->bwp_Common = calloc_or_fail(1, sizeof(*ubwp->bwp_Common)); + ubwp->bwp_Dedicated = calloc_or_fail(1, sizeof(*ubwp->bwp_Dedicated)); - ubwp->bwp_Dedicated->pusch_Config = CALLOC(1, sizeof(*ubwp->bwp_Dedicated->pusch_Config)); + ubwp->bwp_Dedicated->pusch_Config = calloc_or_fail(1, sizeof(*ubwp->bwp_Dedicated->pusch_Config)); ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config; @@ -930,7 +939,7 @@ void RCconfig_NR_L1(void) static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME) { - NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc)); + NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc)); uint64_t ssb_bitmap=0xff; prepare_scc(scc); paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc); @@ -2119,7 +2128,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; /* get global parameters, defined outside any section in the config file */ config_get(config_get_if(), GNBSParams, sizeofArray(GNBSParams), NULL); - NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t)); + NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc)); uint64_t ssb_bitmap=0xff; memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t)); prepare_scc(scc); From a32a8504c9fdca3a021652489798352c9f71aca0 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 25 Sep 2024 11:33:42 +0200 Subject: [PATCH 58/73] Use a macro to initialize NR_SetupRelease structs * introduced macro INIT_SETUP_RELEASE to optimize code in gnb_config.c --- openair2/GNB_APP/gnb_config.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 2195acefb1..2da9f67252 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -95,6 +95,16 @@ #include "nfapi/oai_integration/aerial/fapi_vnf_p5.h" #endif +/** + * @brief Helper define to allocate and initialize SetupRelease structures + */ +#define INIT_SETUP_RELEASE(type, element) \ + do { \ + element = calloc_or_fail(1, sizeof(*element)); \ + (element)->present = NR_SetupRelease_##type##_PR_setup; \ + (element)->choice.setup = CALLOC(1, sizeof(*((element)->choice.setup))); \ + } while (0) + extern uint16_t sf_ahead; void prepare_scc(NR_ServingCellConfigCommon_t *scc) { From 8d222bc474d59d5e60beea21acb61ca306ec0aac Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 25 Sep 2024 11:34:22 +0200 Subject: [PATCH 59/73] Refactoring of prepare_scc * improved readability * clang formatted --- openair2/GNB_APP/gnb_config.c | 141 +++++++++++++++++----------------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 2da9f67252..e0e9bc751e 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -107,90 +107,91 @@ extern uint16_t sf_ahead; -void prepare_scc(NR_ServingCellConfigCommon_t *scc) { +/** + * Allocate memory and initialize ServingCellConfigCommon struct members + */ +void prepare_scc(NR_ServingCellConfigCommon_t *scc) +{ + // NR_ServingCellConfigCommon + scc->physCellId = calloc_or_fail(1, sizeof(*scc->physCellId)); + scc->n_TimingAdvanceOffset = calloc_or_fail(1, sizeof(*scc->n_TimingAdvanceOffset)); + scc->ssb_PositionsInBurst = calloc_or_fail(1, sizeof(*scc->ssb_PositionsInBurst)); + scc->ssb_periodicityServingCell = calloc_or_fail(1, sizeof(*scc->ssb_periodicityServingCell)); + scc->ssbSubcarrierSpacing = calloc_or_fail(1, sizeof(*scc->ssbSubcarrierSpacing)); + scc->tdd_UL_DL_ConfigurationCommon = calloc_or_fail(1, sizeof(*scc->tdd_UL_DL_ConfigurationCommon)); + scc->tdd_UL_DL_ConfigurationCommon->pattern2 = calloc_or_fail(1, sizeof(*scc->tdd_UL_DL_ConfigurationCommon->pattern2)); + scc->downlinkConfigCommon = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon)); + scc->downlinkConfigCommon->frequencyInfoDL = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->frequencyInfoDL)); + scc->downlinkConfigCommon->initialDownlinkBWP = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->initialDownlinkBWP)); - NR_FreqBandIndicatorNR_t *dl_frequencyBandList,*ul_frequencyBandList; - struct NR_SCS_SpecificCarrier *dl_scs_SpecificCarrierList,*ul_scs_SpecificCarrierList; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + frequencyInfoDL->absoluteFrequencySSB = calloc_or_fail(1, sizeof(*frequencyInfoDL->absoluteFrequencySSB)); + NR_FreqBandIndicatorNR_t *dl_frequencyBandList = calloc_or_fail(1, sizeof(*dl_frequencyBandList)); + asn1cSeqAdd(&frequencyInfoDL->frequencyBandList.list, dl_frequencyBandList); + struct NR_SCS_SpecificCarrier *dl_scs_SpecificCarrierList = calloc_or_fail(1, sizeof(*dl_scs_SpecificCarrierList)); + asn1cSeqAdd(&frequencyInfoDL->scs_SpecificCarrierList.list, dl_scs_SpecificCarrierList); - scc->physCellId = CALLOC(1,sizeof(NR_PhysCellId_t)); - scc->downlinkConfigCommon = CALLOC(1,sizeof(struct NR_DownlinkConfigCommon)); - scc->downlinkConfigCommon->frequencyInfoDL = CALLOC(1,sizeof(struct NR_FrequencyInfoDL)); - scc->downlinkConfigCommon->initialDownlinkBWP = CALLOC(1,sizeof(struct NR_BWP_DownlinkCommon)); - scc->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommon)); - scc->uplinkConfigCommon->frequencyInfoUL = CALLOC(1,sizeof(struct NR_FrequencyInfoUL)); - scc->uplinkConfigCommon->initialUplinkBWP = CALLOC(1,sizeof(struct NR_BWP_UplinkCommon)); - scc->n_TimingAdvanceOffset = CALLOC(1, sizeof(long)); - scc->ssb_PositionsInBurst = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__ssb_PositionsInBurst)); - scc->ssb_periodicityServingCell = CALLOC(1,sizeof(long)); - scc->ssbSubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); - scc->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); - scc->tdd_UL_DL_ConfigurationCommon->pattern2 = CALLOC(1,sizeof(struct NR_TDD_UL_DL_Pattern)); - - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = CALLOC(1,sizeof(NR_ARFCN_ValueNR_t)); - - dl_frequencyBandList = CALLOC(1,sizeof(NR_FreqBandIndicatorNR_t)); - dl_scs_SpecificCarrierList = CALLOC(1,sizeof(struct NR_SCS_SpecificCarrier)); + INIT_SETUP_RELEASE(PDCCH_ConfigCommon, scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon); + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon; + struct NR_PDCCH_ConfigCommon *pdcchCCSetup = pdcch_ConfigCommon->choice.setup; + pdcchCCSetup->controlResourceSetZero = calloc_or_fail(1, sizeof(*pdcchCCSetup->controlResourceSetZero)); + pdcchCCSetup->searchSpaceZero = calloc_or_fail(1, sizeof(*pdcchCCSetup->searchSpaceZero)); + pdcchCCSetup->commonControlResourceSet = NULL; - asn1cSeqAdd(&scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list,dl_frequencyBandList); - asn1cSeqAdd(&scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list,dl_scs_SpecificCarrierList); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PDCCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->present=NR_SetupRelease_PDCCH_ConfigCommon_PR_setup; - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = CALLOC(1,sizeof(long)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero = CALLOC(1,sizeof(long)); + INIT_SETUP_RELEASE(PDSCH_ConfigCommon, scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon); + NR_SetupRelease_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon; + pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList = + calloc_or_fail(1, sizeof(*pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = NULL; + scc->uplinkConfigCommon = calloc_or_fail(1, sizeof(*scc->uplinkConfigCommon)); + scc->uplinkConfigCommon->frequencyInfoUL = calloc_or_fail(1, sizeof(*scc->uplinkConfigCommon->frequencyInfoUL)); + scc->uplinkConfigCommon->initialUplinkBWP = calloc_or_fail(1, sizeof(*scc->uplinkConfigCommon->initialUplinkBWP)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PDSCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->present = NR_SetupRelease_PDSCH_ConfigCommon_PR_setup; - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDSCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList = CALLOC(1,sizeof(struct NR_PDSCH_TimeDomainResourceAllocationList)); + NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; + NR_FreqBandIndicatorNR_t *ul_frequencyBandList = calloc_or_fail(1, sizeof(*ul_frequencyBandList)); + frequencyInfoUL->frequencyBandList = calloc_or_fail(1, sizeof(*frequencyInfoUL->frequencyBandList)); + asn1cSeqAdd(&frequencyInfoUL->frequencyBandList->list, ul_frequencyBandList); + frequencyInfoUL->absoluteFrequencyPointA = calloc_or_fail(1, sizeof(*frequencyInfoUL->absoluteFrequencyPointA)); + frequencyInfoUL->p_Max = calloc_or_fail(1, sizeof(*frequencyInfoUL->p_Max)); - ul_frequencyBandList = CALLOC(1,sizeof(NR_FreqBandIndicatorNR_t)); - scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList = CALLOC(1,sizeof(struct NR_MultiFrequencyBandListNR)); - asn1cSeqAdd(&scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list,ul_frequencyBandList); + struct NR_SCS_SpecificCarrier *ul_scs_SpecificCarrierList = calloc_or_fail(1, sizeof(*ul_scs_SpecificCarrierList)); + asn1cSeqAdd(&frequencyInfoUL->scs_SpecificCarrierList.list, ul_scs_SpecificCarrierList); - scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = CALLOC(1,sizeof(NR_ARFCN_ValueNR_t)); - scc->uplinkConfigCommon->frequencyInfoUL->p_Max = CALLOC(1,sizeof(NR_P_Max_t)); - - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_RACH_ConfigCommon_t)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->present = NR_SetupRelease_RACH_ConfigCommon_PR_setup; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = CALLOC(1,sizeof(NR_RSRP_Range_t)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); - *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon)); + INIT_SETUP_RELEASE(RACH_ConfigCommon, scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon); + NR_SetupRelease_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon; + struct NR_RACH_ConfigCommon *rachCCSetup = rach_ConfigCommon->choice.setup; + rachCCSetup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB = + calloc_or_fail(1, sizeof(*rachCCSetup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB)); + rachCCSetup->rsrp_ThresholdSSB = calloc_or_fail(1, sizeof(*rachCCSetup->rsrp_ThresholdSSB)); + rachCCSetup->msg1_SubcarrierSpacing = calloc_or_fail(1, sizeof(*rachCCSetup->msg1_SubcarrierSpacing)); + rachCCSetup->msg3_transformPrecoder = calloc_or_fail(1, sizeof(*rachCCSetup->msg3_transformPrecoder)); + *rachCCSetup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = NULL; - - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocationList)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant = CALLOC(1,sizeof(long)); - - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PUCCH_ConfigCommon)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->present= NR_SetupRelease_PUCCH_ConfigCommon_PR_setup; - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUCCH_ConfigCommon)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId = CALLOC(1,sizeof(long)); + INIT_SETUP_RELEASE(PUSCH_ConfigCommon, scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon); + NR_SetupRelease_PUSCH_ConfigCommon_t *pusch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; + struct NR_PUSCH_ConfigCommon *puschCCSetup = pusch_ConfigCommon->choice.setup; + puschCCSetup->groupHoppingEnabledTransformPrecoding = NULL; + puschCCSetup->pusch_TimeDomainAllocationList = calloc_or_fail(1, sizeof(*puschCCSetup->pusch_TimeDomainAllocationList)); + puschCCSetup->msg3_DeltaPreamble = calloc_or_fail(1, sizeof(*puschCCSetup->msg3_DeltaPreamble)); + puschCCSetup->p0_NominalWithGrant = calloc_or_fail(1, sizeof(*puschCCSetup->p0_NominalWithGrant)); - ul_scs_SpecificCarrierList = CALLOC(1,sizeof(struct NR_SCS_SpecificCarrier)); - asn1cSeqAdd(&scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list,ul_scs_SpecificCarrierList); + INIT_SETUP_RELEASE(PUCCH_ConfigCommon, scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon); + NR_SetupRelease_PUCCH_ConfigCommon_t *pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; + struct NR_PUCCH_ConfigCommon *pucchCCSetup = pucch_ConfigCommon->choice.setup; + pucchCCSetup->p0_nominal = calloc_or_fail(1, sizeof(*pucchCCSetup->p0_nominal)); + pucchCCSetup->pucch_ResourceCommon = calloc_or_fail(1, sizeof(*pucchCCSetup->pucch_ResourceCommon)); + pucchCCSetup->hoppingId = calloc_or_fail(1, sizeof(*pucchCCSetup->hoppingId)); - scc->ext2 = CALLOC(1, sizeof(*scc->ext2)); - scc->ext2->ntn_Config_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17)); - scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17)); + scc->ext2 = calloc_or_fail(1, sizeof(*scc->ext2)); + scc->ext2->ntn_Config_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17)); + scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17)); - scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17)); - scc->ext2->ntn_Config_r17->ta_Info_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17)); + scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17)); + scc->ext2->ntn_Config_r17->ta_Info_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17)); scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_positionVelocity_r17; scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 = - CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17)); + calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17)); } // Section 4.1 in 38.213 From 1438dfbd35e80530d5418ed0426bf3e6302d2063 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 20 Sep 2024 11:20:21 +0200 Subject: [PATCH 60/73] Refactored fill_scc_sim * clang formatted * code cleanup * improve readability --- openair2/GNB_APP/gnb_config.c | 209 +++++++++++++++++++--------------- 1 file changed, 119 insertions(+), 90 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index e0e9bc751e..3ad0762361 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -226,99 +226,128 @@ NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR get_ssb_len(NR_ServingCellCo return NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap; } +static struct NR_SCS_SpecificCarrier configure_scs_carrier(int mu, int N_RB) +{ + struct NR_SCS_SpecificCarrier scs_sc = {0}; + scs_sc.offsetToCarrier = 0; + scs_sc.subcarrierSpacing = mu; + scs_sc.carrierBandwidth = N_RB; + return scs_sc; +} + +static struct NR_PUSCH_TimeDomainResourceAllocation *add_PUSCH_TimeDomainResourceAllocation(int startSymbolAndLength) +{ + struct NR_PUSCH_TimeDomainResourceAllocation *pusch_alloc = calloc_or_fail(1, sizeof(*pusch_alloc)); + pusch_alloc->k2 = calloc_or_fail(1, sizeof(*pusch_alloc->k2)); + *pusch_alloc->k2 = 6; + pusch_alloc->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + pusch_alloc->startSymbolAndLength = startSymbolAndLength; + return pusch_alloc; +} + +/** + * Fill ServingCellConfigCommon struct members for unitary simulators + */ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N_RB_DL, int N_RB_UL, int mu_dl, int mu_ul) { - *scc->physCellId=0; \ - // *scc->n_TimingAdvanceOffset=NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0; - *scc->ssb_periodicityServingCell=NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20; - scc->dmrs_TypeA_Position=NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2; - *scc->ssbSubcarrierSpacing=mu_dl; - if (mu_dl == 0) { - *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=520432; - *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=38; - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=520000; - } else { - *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=641032; - *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=78; - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=640000; - } - scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; - scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_dl; - scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_DL; - scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth = - PRBalloc_to_locationandbandwidth(N_RB_DL, 0); - scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing=mu_dl;//NR_SubcarrierSpacing_kHz30; - *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=12; - *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero=0; - struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation0 = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t)); - timedomainresourceallocation0->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; - timedomainresourceallocation0->startSymbolAndLength=54; - asn1cSeqAdd(&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list, - timedomainresourceallocation0); - struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation1 = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t)); - timedomainresourceallocation1->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; - timedomainresourceallocation1->startSymbolAndLength=57; - asn1cSeqAdd(&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list, - timedomainresourceallocation1); - *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]=mu_ul?78:38; - *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA=-1; - scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; - scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=mu_ul; - scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_UL; - *scc->uplinkConfigCommon->frequencyInfoUL->p_Max=20; - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(N_RB_UL, 0); - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing=mu_ul;//NR_SubcarrierSpacing_kHz30; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex=98; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM=NR_RACH_ConfigGeneric__msg1_FDM_one; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart=0; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig=13; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower=-118; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleTransMax=NR_RACH_ConfigGeneric__preambleTransMax_n10; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.powerRampingStep=NR_RACH_ConfigGeneric__powerRampingStep_dB2; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow=NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present=NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one=NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB__one_n64; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer=NR_RACH_ConfigCommon__ra_ContentionResolutionTimer_sf64; - *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB=19; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present=NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139=0; - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig=NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet; - struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation0 = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation)); - pusch_timedomainresourceallocation0->k2 = CALLOC(1,sizeof(long)); - *pusch_timedomainresourceallocation0->k2=6; - pusch_timedomainresourceallocation0->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; - pusch_timedomainresourceallocation0->startSymbolAndLength=55; - asn1cSeqAdd(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation0); - struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation1 = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation)); - pusch_timedomainresourceallocation1->k2 = CALLOC(1,sizeof(long)); - *pusch_timedomainresourceallocation1->k2=6; - pusch_timedomainresourceallocation1->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; - pusch_timedomainresourceallocation1->startSymbolAndLength=38; - asn1cSeqAdd(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation1); - *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble=1; - *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant=-90; - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping=NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither; - *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId=40; - *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal=-90; - scc->ssb_PositionsInBurst->present=NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; - *ssb_bitmap=0xff; - scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing=mu_dl; - if (mu_dl == 0) - scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms10; - else - scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots=7; - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols=6; - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots=2; - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols=4; - scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity=321; + *scc->physCellId = 0; + *scc->ssb_periodicityServingCell = NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20; + scc->dmrs_TypeA_Position = NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2; + *scc->ssbSubcarrierSpacing = mu_dl; - scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots=-1; - scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols=-1; - scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots=-1; - scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols=-1; - scc->ss_PBCH_BlockPower=20; - *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=-1; + struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + if (mu_dl == 0) { + *frequencyInfoDL->absoluteFrequencySSB = 520432; + *frequencyInfoDL->frequencyBandList.list.array[0] = 38; + frequencyInfoDL->absoluteFrequencyPointA = 520000; + } else { + *frequencyInfoDL->absoluteFrequencySSB = 641032; + *frequencyInfoDL->frequencyBandList.list.array[0] = 78; + frequencyInfoDL->absoluteFrequencyPointA = 640000; + } + + *frequencyInfoDL->scs_SpecificCarrierList.list.array[0] = configure_scs_carrier(mu_dl, N_RB_DL); + struct NR_BWP_DownlinkCommon *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP; + + initialDownlinkBWP->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(N_RB_DL, 0); + initialDownlinkBWP->genericParameters.subcarrierSpacing = mu_dl; + *initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = 12; + *initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero = 0; + struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation0 = + calloc_or_fail(1, sizeof(*timedomainresourceallocation0)); + timedomainresourceallocation0->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + timedomainresourceallocation0->startSymbolAndLength = 54; + asn1cSeqAdd(&initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list, + timedomainresourceallocation0); + struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation1 = + calloc_or_fail(1, sizeof(*timedomainresourceallocation1)); + timedomainresourceallocation1->mappingType = NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + timedomainresourceallocation1->startSymbolAndLength = 57; + asn1cSeqAdd(&initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list, + timedomainresourceallocation1); + + struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; + *frequencyInfoUL->frequencyBandList->list.array[0] = mu_ul ? 78 : 38; + *frequencyInfoUL->absoluteFrequencyPointA = -1; + *frequencyInfoUL->scs_SpecificCarrierList.list.array[0] = configure_scs_carrier(mu_ul, N_RB_UL); + *frequencyInfoUL->p_Max = 20; + + struct NR_BWP_UplinkCommon *initialUplinkBWP = scc->uplinkConfigCommon->initialUplinkBWP; + initialUplinkBWP->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(N_RB_UL, 0); + initialUplinkBWP->genericParameters.subcarrierSpacing = mu_ul; + + struct NR_SetupRelease_RACH_ConfigCommon *rach_ConfigCommon = initialUplinkBWP->rach_ConfigCommon; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex = 98; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM = NR_RACH_ConfigGeneric__msg1_FDM_one; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart = 0; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig = 13; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower = -118; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleTransMax = NR_RACH_ConfigGeneric__preambleTransMax_n10; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.powerRampingStep = NR_RACH_ConfigGeneric__powerRampingStep_dB2; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow = NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20; + rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present = + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one; + rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one = + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB__one_n64; + rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer = NR_RACH_ConfigCommon__ra_ContentionResolutionTimer_sf64; + *rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = 19; + rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present = NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139; + rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139 = 0; + rach_ConfigCommon->choice.setup->restrictedSetConfig = NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet; + *rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = -1; + struct NR_SetupRelease_PUSCH_ConfigCommon *pusch_ConfigCommon = initialUplinkBWP->pusch_ConfigCommon; + + asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list, add_PUSCH_TimeDomainResourceAllocation(55)); + asn1cSeqAdd(&pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list, add_PUSCH_TimeDomainResourceAllocation(38)); + + *pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble = 1; + *pusch_ConfigCommon->choice.setup->p0_NominalWithGrant = -90; + struct NR_SetupRelease_PUCCH_ConfigCommon *pucch_ConfigCommon = initialUplinkBWP->pucch_ConfigCommon; + pucch_ConfigCommon->choice.setup->pucch_GroupHopping = NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither; + *pucch_ConfigCommon->choice.setup->hoppingId = 40; + *pucch_ConfigCommon->choice.setup->p0_nominal = -90; + scc->ssb_PositionsInBurst->present = NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; + *ssb_bitmap = 0xff; + + struct NR_TDD_UL_DL_ConfigCommon *tdd_UL_DL_ConfigurationCommon = scc->tdd_UL_DL_ConfigurationCommon; + tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = mu_dl; + + NR_TDD_UL_DL_Pattern_t *p1 = &tdd_UL_DL_ConfigurationCommon->pattern1; + p1->dl_UL_TransmissionPeriodicity = (mu_dl == 0) ? NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms10 + : NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; + p1->nrofDownlinkSlots = 7; + p1->nrofDownlinkSymbols = 6; + p1->nrofUplinkSlots = 2; + p1->nrofUplinkSymbols = 4; + + struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_ConfigurationCommon->pattern2; + p2->dl_UL_TransmissionPeriodicity = 321; + p2->nrofDownlinkSlots = -1; + p2->nrofDownlinkSymbols = -1; + p2->nrofUplinkSlots = -1; + p2->nrofUplinkSymbols = -1; + + scc->ss_PBCH_BlockPower = 20; } From 48bb594e302fe549653b8018561733c9267f4aa6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 25 Sep 2024 12:11:12 +0200 Subject: [PATCH 61/73] Cleanup gnb_config.c --- openair2/GNB_APP/gnb_config.c | 49 ----------------------------------- 1 file changed, 49 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 3ad0762361..c1e58f2b00 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -27,69 +27,22 @@ EMAIL : Lionel.Gauthier@eurecom.fr, navid.nikaein@eurecom.fr, kroempa@gmail.com */ -#include -#include - -#include "common/utils/LOG/log.h" -#include "common/utils/nr/nr_common.h" -#include "assertions.h" -#include "oai_asn1.h" #include "executables/softmodem-common.h" #include "gnb_config.h" -#include "gnb_paramdef.h" #include "enb_paramdef.h" #include "UTIL/OTG/otg.h" -#include "UTIL/OTG/otg_externs.h" -#include "intertask_interface.h" -#include "ngap_gNB.h" -#include "sctp_eNB_task.h" #include "sctp_default_values.h" -#include "F1AP_CauseRadioNetwork.h" #include "f1ap_common.h" -// #include "SystemInformationBlockType2.h" -// #include "LAYER2/MAC/extern.h" -// #include "LAYER2/MAC/proto.h" #include "PHY/INIT/nr_phy_init.h" #include "radio/ETHERNET/ethernet_lib.h" #include "nfapi_vnf.h" #include "nfapi_pnf.h" -#include "nr_pdcp/nr_pdcp_oai_api.h" - -//#include "L1_paramdef.h" #include "prs_nr_paramdef.h" #include "L1_nr_paramdef.h" #include "MACRLC_nr_paramdef.h" -#include "common/config/config_userapi.h" -//#include "RRC_config_tools.h" #include "gnb_paramdef.h" #include "NR_MAC_gNB/mac_proto.h" -#include - -#include "NR_asn_constant.h" -#include "executables/thread-common.h" -#include "NR_SCS-SpecificCarrier.h" -#include "NR_TDD-UL-DL-ConfigCommon.h" -#include "NR_FrequencyInfoUL.h" -#include "NR_RACH-ConfigGeneric.h" -#include "NR_RACH-ConfigCommon.h" -#include "NR_PUSCH-TimeDomainResourceAllocation.h" -#include "NR_PUSCH-ConfigCommon.h" -#include "NR_PUCCH-ConfigCommon.h" -#include "NR_PDSCH-TimeDomainResourceAllocation.h" -#include "NR_PDSCH-ConfigCommon.h" -#include "NR_RateMatchPattern.h" -#include "NR_RateMatchPatternLTE-CRS.h" -#include "NR_SearchSpace.h" -#include "NR_ControlResourceSet.h" -#include "NR_MeasurementTimingConfiguration.h" -#include "NR_EUTRA-MBSFN-SubframeConfig.h" -#include "uper_decoder.h" -#include "uper_encoder.h" -#include "common/utils/ds/seq_arr.h" - -#include "RRC/NR/MESSAGES/asn1_msg.h" #include "RRC/NR/nr_rrc_extern.h" -#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" #include "nfapi/oai_integration/vendor_ext.h" #ifdef ENABLE_AERIAL #include "nfapi/oai_integration/aerial/fapi_vnf_p5.h" @@ -105,8 +58,6 @@ (element)->choice.setup = CALLOC(1, sizeof(*((element)->choice.setup))); \ } while (0) -extern uint16_t sf_ahead; - /** * Allocate memory and initialize ServingCellConfigCommon struct members */ From 73b00e8c1c4cc932d0249e8480934212b016ca23 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 30 Sep 2024 14:07:42 +0100 Subject: [PATCH 62/73] Fix the ratio of PDSCH EPRE to DM-RS EPRE This fix gets DL 4-layer working with COTS UE --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index ce4109de2c..41746a6ba2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -72,6 +72,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB; const int dmrs_Type = rel15->dmrsConfigType; const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); + const int amp_dmrs = (int)((double)amp * sqrt(rel15->numDmrsCdmGrpsNoData)); // 3GPP TS 38.214 Section 4.1: Table 4.1-1 LOG_D(PHY,"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n", rel15->BWPStart,rel15->BWPSize,rel15->rbStart,rel15->rbSize); const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs; @@ -296,7 +297,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) /* Map DMRS Symbol */ if ((dmrs_symbol_map & (1 << l_symbol)) && (k == ((start_sc + get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type)) % (frame_parms->ofdm_symbol_size)))) { - txdataF_precoding[layer][l_symbol][k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp, 15); + txdataF_precoding[layer][l_symbol][k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp_dmrs, 15); #ifdef DEBUG_DLSCH_MAPPING printf("dmrs_idx %u\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", dmrs_idx, From 6344fce6e48875e6d330abae3db78dab957d4c9d Mon Sep 17 00:00:00 2001 From: Ghislain Bourgeois Date: Wed, 2 Oct 2024 10:34:27 -0400 Subject: [PATCH 63/73] Reinitialize sock to -1 after closing Prevents bug where a closed socket is returned. --- radio/rfsimulator/simulator.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 02f05b1e25..2b358cd5bb 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -593,6 +593,7 @@ static int startServer(openair0_device *device) } close(sock); + sock = -1; } freeaddrinfo(results); @@ -649,6 +650,7 @@ static int client_try_connect(const char *host, uint16_t port) } close(sock); + sock = -1; } freeaddrinfo(result); From 406227699bd642e0a11c9f4f82d08ff69d288642 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Fri, 27 Sep 2024 15:41:58 +0200 Subject: [PATCH 64/73] CI: rename AW2S configs/files used for 2x2 testing --- ci-scripts/ci_infra.yaml | 2 +- ...onf => gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf} | 0 ...w2s_asue.xml => container_sa_aw2s_asue_2x2.xml} | 14 +++++++------- .../docker-compose.yml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename ci-scripts/conf_files/{gnb.sa.band78.51prb.aw2s.ddsuu.conf => gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf} (100%) rename ci-scripts/xml_files/{container_sa_aw2s_asue.xml => container_sa_aw2s_asue_2x2.xml} (96%) rename ci-scripts/yaml_files/{sa_aw2s_gnb => sa_aw2s_2x2_gnb}/docker-compose.yml (84%) diff --git a/ci-scripts/ci_infra.yaml b/ci-scripts/ci_infra.yaml index 1bc26659c6..59b388e593 100644 --- a/ci-scripts/ci_infra.yaml +++ b/ci-scripts/ci_infra.yaml @@ -109,7 +109,7 @@ ltebox-nepes: Host: nepes NetworkScript: ip a show dev tun1 -amarisoft_ue: +amarisoft_ue_2x2: Host: amariue InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-00102-2x2.cfg & TermScript: /root/2023-10-27/libs/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2 diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf similarity index 100% rename from ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf rename to ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml similarity index 96% rename from ci-scripts/xml_files/container_sa_aw2s_asue.xml rename to ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml index 71789cca52..23fd07eac3 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml @@ -21,8 +21,8 @@ --> - TEST-5G-AW2S - 20 MHz TDD SA + TEST-5G-2x2-AW2S + 20 MHz TDD 2x2 SA tasks 010000 @@ -75,7 +75,7 @@ Deploy_Object Deploy gNB (TDD/Band78/20MHz/aw2s) in a container - ci-scripts/yaml_files/sa_aw2s_gnb + ci-scripts/yaml_files/sa_aw2s_2x2_gnb 0 0 @@ -83,7 +83,7 @@ Initialize_UE Initialize Amarisoft UE - amarisoft_ue + amarisoft_ue_2x2 @@ -237,7 +237,7 @@ Ping: 50pings in 10sec, multi-ue amarisoft_ue_16 -c 50 -i 0.2 %cn_ip% - 1 + 5 30 @@ -252,7 +252,7 @@ Terminate_UE true Terminate UE - amarisoft_ue + amarisoft_ue_2x2 @@ -265,7 +265,7 @@ Undeploy_Object true Undeploy gNB - ci-scripts/yaml_files/sa_aw2s_gnb + ci-scripts/yaml_files/sa_aw2s_2x2_gnb 0 0 diff --git a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml similarity index 84% rename from ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml rename to ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml index 03b9914404..d1f5ae2475 100644 --- a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml @@ -14,7 +14,7 @@ services: TZ: Europe/Paris USE_ADDITIONAL_OPTIONS: --sa volumes: - - ../../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf:/opt/oai-gnb-aw2s/etc/gnb.conf + - ../../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf:/opt/oai-gnb-aw2s/etc/gnb.conf healthcheck: test: /bin/bash -c "pgrep nr-softmodem" interval: 10s From 5e9c432b415d1972dc225687d02f8f5ec4bd2078 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Fri, 27 Sep 2024 15:53:34 +0200 Subject: [PATCH 65/73] CI: change frequency used by AW2S --- ...2s-multi-00102-2x2.cfg => aw2s-multi-00102-2x2-v2.cfg} | 5 +++-- ci-scripts/ci_infra.yaml | 2 +- .../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf | 8 ++++---- ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml | 8 ++++---- 4 files changed, 12 insertions(+), 11 deletions(-) rename ci-scripts/as_ue/{aw2s-multi-00102-2x2.cfg => aw2s-multi-00102-2x2-v2.cfg} (98%) diff --git a/ci-scripts/as_ue/aw2s-multi-00102-2x2.cfg b/ci-scripts/as_ue/aw2s-multi-00102-2x2-v2.cfg similarity index 98% rename from ci-scripts/as_ue/aw2s-multi-00102-2x2.cfg rename to ci-scripts/as_ue/aw2s-multi-00102-2x2-v2.cfg index 04d2bb9ffd..b70ffbb0af 100644 --- a/ci-scripts/as_ue/aw2s-multi-00102-2x2.cfg +++ b/ci-scripts/as_ue/aw2s-multi-00102-2x2-v2.cfg @@ -5,6 +5,7 @@ { #define N_ANTENNA_DL 2 #define N_ANTENNA_UL 2 +#define DL_ARFCN 631296 #define TDD 1 log_options: "all.level=warn,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1", @@ -25,8 +26,8 @@ allow dynamic UE creation from remote API */ rf_port: 0, bandwidth: 20, band: 78, - dl_nr_arfcn:630048, - ssb_nr_arfcn:630048, + dl_nr_arfcn: DL_ARFCN, + ssb_nr_arfcn: DL_ARFCN, subcarrier_spacing: 30, n_antenna_dl: N_ANTENNA_DL, n_antenna_ul: N_ANTENNA_UL, diff --git a/ci-scripts/ci_infra.yaml b/ci-scripts/ci_infra.yaml index 59b388e593..a6b7531455 100644 --- a/ci-scripts/ci_infra.yaml +++ b/ci-scripts/ci_infra.yaml @@ -111,7 +111,7 @@ ltebox-nepes: amarisoft_ue_2x2: Host: amariue - InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-00102-2x2.cfg & + InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-00102-2x2-v2.cfg & TermScript: /root/2023-10-27/libs/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2 amarisoft_ue_fhi72: Host: amariue diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf index 4cc3c2be2b..a32aec583a 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.2x2.conf @@ -34,11 +34,11 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL - # this is 3410.4 MHz => 301 REs from PointA 25 PRBs + 1 RE - absoluteFrequencySSB = 630048; + # this is 3469.44 MHz => 301 REs from PointA 25 PRBs + 1 RE + absoluteFrequencySSB = 631296; dl_frequencyBand = 78; - # this is 3410.4 - (51*12*30e-3/2) = 3401.22 MHz - dl_absoluteFrequencyPointA = 629436; + # this is 3469.44 - (51*12*30e-3/2) = 3460.26 MHz + dl_absoluteFrequencyPointA = 630684; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml index 23fd07eac3..5d43c89c3c 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml @@ -178,8 +178,8 @@ Iperf - iperf (DL/7Mbps/UDP)(30 sec)(multi-ue profile) - -u -b 70M -t 30 -R + iperf (DL/4Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 60M -t 30 -R amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 25 80 @@ -198,8 +198,8 @@ Iperf - iperf (UL/3.6Mbps/UDP)(30 sec)(multi-ue profile) - -u -b 36M -t 30 + iperf (UL/1.5Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 22.5M -t 30 amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 25 80 From 8584da1636e88f54cc1eba24abb99f5b34986cd9 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Fri, 27 Sep 2024 16:17:58 +0200 Subject: [PATCH 66/73] CI: add 1x1 AW2S test with multi UEs --- ci-scripts/as_ue/aw2s-multi-00102-20.cfg | 284 ++++++++++++++++++ ci-scripts/ci_infra.yaml | 4 + .../gnb.sa.band78.51prb.aw2s.ddsuu.conf | 272 +++++++++++++++++ .../xml_files/container_sa_aw2s_asue.xml | 283 +++++++++++++++++ .../yaml_files/sa_aw2s_gnb/docker-compose.yml | 22 ++ 5 files changed, 865 insertions(+) create mode 100644 ci-scripts/as_ue/aw2s-multi-00102-20.cfg create mode 100644 ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf create mode 100644 ci-scripts/xml_files/container_sa_aw2s_asue.xml create mode 100644 ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml diff --git a/ci-scripts/as_ue/aw2s-multi-00102-20.cfg b/ci-scripts/as_ue/aw2s-multi-00102-20.cfg new file mode 100644 index 0000000000..48901cf6f0 --- /dev/null +++ b/ci-scripts/as_ue/aw2s-multi-00102-20.cfg @@ -0,0 +1,284 @@ +/* UE simulator configuration file version 2021-06-17 + * LTE / 5G Non StandAlone + * Copyright (C) 2019-2021 Amarisoft + */ +{ +#define N_ANTENNA_DL 1 +#define N_ANTENNA_UL 1 +#define DL_ARFCN 631296 +#define TDD 1 + +log_options: "all.level=warn,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1", +log_filename: "/tmp/ue.log", + +/* Enable remote API and Web interface */ +com_addr: "0.0.0.0:9002", + +include "rf_driver_20/1chan.cfg", + +/* If true, allow the simulation of several UEs at the same time and +allow dynamic UE creation from remote API */ + + cell_groups: [{ + group_type: "nr", + multi_ue: true, + ldpc_max_its:8, + cells: [{ + rf_port: 0, + bandwidth: 20, + band: 78, + dl_nr_arfcn: DL_ARFCN, + ssb_nr_arfcn: DL_ARFCN, + subcarrier_spacing: 30, + n_antenna_dl: N_ANTENNA_DL, + n_antenna_ul: N_ANTENNA_UL, + rx_to_tx_latency:2, + global_timing_advance:-1, + }], + }], + + /* UE capabilities */ + /* USIM data */ + ue_list: [ + { + "ue_id" : 1, + "imsi": "001020000000001", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 2, + "imsi": "001020000000002", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 3, + "imsi": "001020000000003", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 4, + "imsi": "001020000000004", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 5, + "imsi": "001020000000005", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 6, + "imsi": "001020000000006", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 7, + "imsi": "001020000000007", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 8, + "imsi": "001020000000008", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 9, + "imsi": "001020000000009", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 10, + "imsi": "001020000000010", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 11, + "imsi": "001020000000011", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 12, + "imsi": "001020000000012", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 13, + "imsi": "001020000000013", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 14, + "imsi": "001020000000014", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 15, + "imsi": "001020000000015", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + { + "ue_id" : 16, + "imsi": "001020000000016", + "K": "fec86ba6eb707ed08905757b1bb44b8f", + "sim_algo":"milenage", + "op": "1006020f0a478bf6b699f15c062e42b3", + + as_release: 15, + ue_category: "nr", + apn:"oai", + attach_pdn_type:"ipv4", + default_nssai: [ { sst: 1, }, ], + default_pdu_session_snssai: { sst: 1, }, + tun_setup_script: "ue-ifup", + }, + ], +} diff --git a/ci-scripts/ci_infra.yaml b/ci-scripts/ci_infra.yaml index a6b7531455..65c7c464b6 100644 --- a/ci-scripts/ci_infra.yaml +++ b/ci-scripts/ci_infra.yaml @@ -109,6 +109,10 @@ ltebox-nepes: Host: nepes NetworkScript: ip a show dev tun1 +amarisoft_ue: + Host: amariue + InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue/aw2s-multi-00102-20.cfg & + TermScript: /root/2023-10-27/libs/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2 amarisoft_ue_2x2: Host: amariue InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-00102-2x2-v2.cfg & diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf new file mode 100644 index 0000000000..9ee7787eed --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf @@ -0,0 +1,272 @@ +Active_gNBs = ( "gNB-Eurecom-n78_20"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +#device :{ +# name = "aw2sori_transpro"; +#} + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + gNB_name = "gNB-Eurecom-n78_20"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 0x1; + plmn_list = ({ mcc = 001; mnc = 02; mnc_length = 2; snssaiList = ({ sst =0x1; }) }); + + nr_cellid = 12345678L + + ////////// Physical parameters: + pdsch_AntennaPorts_XP = 1; + pusch_AntennaPorts = 1; + do_CSIRS = 1; + do_SRS = 0; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3469.44 MHz => 301 REs from PointA 25 PRBs + 1 RE + absoluteFrequencySSB = 631296; + dl_frequencyBand = 78; + # this is 3469.44 - (51*12*30e-3/2) = 3460.26 MHz + dl_absoluteFrequencyPointA = 630684; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 51; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13750; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; # this means shift of 14, so Coreset is in PRBs 1..48, SSB starts at PRB 15 + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 51; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13750; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 100; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 15; + preambleReceivedTargetPower = -104; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-96; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -96; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 5; + nrofDownlinkSlots = 2; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "172.21.6.100"; }); + + NETWORK_INTERFACES : + { + + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.124/20"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.124/20"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 50; + pusch_dtx_threshold = 10; + } +); + +RUs = ( + { + local_if_name = "ens7f3"; + remote_address = "192.168.80.239"; + local_address = "192.168.80.24"; + local_portc = 50000; + remote_portc = 55444; + local_portd = 52001; + remote_portd = 52183; + local_rf = "no" + tr_preference = "udp_ecpri_if5" + nb_tx = 1 + nb_rx = 1 + att_tx = 18 + att_rx = 0; + num_tp_cores = 4; + rxfh_core_id = 9; + txfh_core_id = 10; + tp_cores = [11,12,13,14]; + nr_flag = 1; + eNB_instances = [0]; + bands = [78]; + sl_ahead = 5; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + } +); + + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea2", "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "yes"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + f1ap_log_level ="debug"; + f1ap_log_verbosity ="medium"; + ngap_log_level ="debug"; + ngap_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml new file mode 100644 index 0000000000..f023da8402 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -0,0 +1,283 @@ + + + TEST-5G-AW2S + 20 MHz TDD SA + tasks + 1 + + 110000 + 101000 + 100813 + 120000 + 102000 + 102001 + 102002 + 102003 + 102004 + 102005 + 102006 + 102007 + 102008 + 102009 + 102010 + 102011 + 102012 + 102013 + 102014 + 102015 + 100100 + 100010 + 100020 + 100030 + 100040 + 102016 + 100200 + 103000 + 104000 + 100002 + 130000 + 444444 + + + + + Pull_Cluster_Image + Pull Images from Cluster + oaicicd-ran + oai-gnb-aw2s + + + + Initialize_UE + Initialize Amarisoft UE + amarisoft_ue + + + + Create_Workspace + Creating new Workspace + 0 + 0 + + + + Deploy_Object + Deploy gNB (TDD/Band78/20MHz/aw2s) in a container + ci-scripts/yaml_files/sa_aw2s_gnb + 0 + 0 + + + + Attach_UE + Attach UE + amarisoft_ue_1 + + + + Attach_UE + Attach UE + amarisoft_ue_2 + + + + Attach_UE + Attach UE + amarisoft_ue_3 + + + + Attach_UE + Attach UE + amarisoft_ue_4 + + + + Attach_UE + Attach UE + amarisoft_ue_5 + + + + Attach_UE + Attach UE + amarisoft_ue_6 + + + + Attach_UE + Attach UE + amarisoft_ue_7 + + + + Attach_UE + Attach UE + amarisoft_ue_8 + + + + Attach_UE + Attach UE + amarisoft_ue_9 + + + + Attach_UE + Attach UE + amarisoft_ue_10 + + + + Attach_UE + Attach UE + amarisoft_ue_11 + + + + Attach_UE + Attach UE + amarisoft_ue_12 + + + + Attach_UE + Attach UE + amarisoft_ue_13 + + + + Attach_UE + Attach UE + amarisoft_ue_14 + + + + Attach_UE + Attach UE + amarisoft_ue_15 + + + + Iperf + iperf (DL/3Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 45M -t 30 -R + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 25 + 80 + balanced + oc-cn5g + + + + Iperf + iperf (DL/TCP)(30 sec)(multi-ue profile) + -t 30 -R + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 2 + oc-cn5g + + + + Iperf + iperf (UL/1Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 15M -t 30 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 25 + 80 + balanced + oc-cn5g + + + + Iperf + iperf (UL/TCP)(30 sec)(multi-ue profile) + -t 30 + oc-cn5g + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 1 + oc-cn5g + + + + Ping + Ping: 50 pings in 10sec, multi-ue + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + -c 50 -i 0.2 %cn_ip% + 5 + 25 + + + + Attach_UE + Attach UE + amarisoft_ue_16 + + + + Ping + Ping: 50pings in 10sec, multi-ue + amarisoft_ue_16 + -c 50 -i 0.2 %cn_ip% + 5 + 30 + + + + Detach_UE + true + Detach UE + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 amarisoft_ue_16 + + + + Terminate_UE + true + Terminate UE + amarisoft_ue + + + + IdleSleep + Sleep + 5 + + + + Undeploy_Object + true + Undeploy gNB + ci-scripts/yaml_files/sa_aw2s_gnb + 0 + 0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + 0 + + + diff --git a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml new file mode 100644 index 0000000000..03b9914404 --- /dev/null +++ b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml @@ -0,0 +1,22 @@ +services: + oai-gnb: + image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-aw2s:${TAG:-develop} + network_mode: "host" + container_name: oai-gnb-aw2s + cap_drop: + - ALL + cap_add: + - SYS_NICE + - IPC_LOCK + ulimits: + core: -1 # for core dumps + environment: + TZ: Europe/Paris + USE_ADDITIONAL_OPTIONS: --sa + volumes: + - ../../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf:/opt/oai-gnb-aw2s/etc/gnb.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 From 8e6234a2f569ca68fa14fc1f87fa4a9ed43b7700 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Mon, 30 Sep 2024 11:49:38 +0200 Subject: [PATCH 67/73] Enable gNB configuration through YAML file --- .../gnb.sa.band78.106prb.rfsim.yaml | 208 ++++++++++++++++++ .../5g_rfsimulator/docker-compose.yaml | 2 +- docker/Dockerfile.gNB.aerial.ubuntu22 | 10 +- ...rfile.gNB.aerial.ubuntu22.sanitize-address | 6 +- docker/Dockerfile.gNB.aw2s.rhel9 | 9 +- docker/Dockerfile.gNB.aw2s.rocky | 3 +- docker/Dockerfile.gNB.aw2s.ubuntu22 | 6 +- docker/Dockerfile.gNB.fhi72.rhel9 | 9 +- docker/Dockerfile.gNB.fhi72.rocky | 3 +- docker/Dockerfile.gNB.fhi72.ubuntu22 | 6 +- docker/Dockerfile.gNB.rhel9 | 9 +- docker/Dockerfile.gNB.rocky | 3 +- docker/Dockerfile.gNB.ubuntu22 | 6 +- docker/scripts/gnb_entrypoint.sh | 24 +- 14 files changed, 278 insertions(+), 26 deletions(-) create mode 100644 ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml new file mode 100644 index 0000000000..acd9f271d3 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml @@ -0,0 +1,208 @@ +Active_gNBs: + - gnb-rfsim +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity: none +gNBs: + ##### Identification parameters: + - gNB_ID: 0xe00 + gNB_name: gnb-rfsim + tracking_area_code: 1 + plmn_list: + - mcc: 208 + mnc: 99 + mnc_length: 2 + snssaiList: + - sst: 1 + sd: 0xffffff + nr_cellid: 12345678 + ##### Physical parameters: + min_rxtxtime: 6 + servingCellConfigCommon: + #spCellConfigCommon + - physCellId: 0 + # downlinkConfigCommon + #frequencyInfoDL + # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 + absoluteFrequencySSB: 621312 + # this is 3300.60 MHz + dl_absoluteFrequencyPointA: 620040 + #scs-SpecificCarrierList + dl_offstToCarrier: 0 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing: 1 + dl_carrierBandwidth: 106 + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=106 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth: 28875 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing: 1 + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero: 11 + initialDLBWPsearchSpaceZero: 0 + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand: 78 + #scs-SpecificCarrierList + ul_offstToCarrier: 0 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing: 1 + ul_carrierBandwidth: 106 + pMax: 20 + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth: 28875 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing: 1 + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex: 98 + #prach_msg1_FDM + #0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM: 0 + prach_msg1_FrequencyStart: 0 + zeroCorrelationZoneConfig: 12 + preambleReceivedTargetPower: -104 + #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax: 6 + #powerRampingStep + # 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep: 1 + #ra_ReponseWindow + #1,2,4,8,10,20,40,80 + ra_ResponseWindow: 5 + #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR + #1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR: 3 + #oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB: 15 + #ra_ContentionResolutionTimer + #(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer: 7 + rsrp_ThresholdSSB: 19 + #prach-RootSequenceIndex_PR + #1 = 839, 2 = 139 + prach_RootSequenceIndex_PR: 2 + prach_RootSequenceIndex: 1 + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + msg1_SubcarrierSpacing: 1 + # restrictedSetConfig + # 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig: 0 + msg3_DeltaPreamble: 1 + p0_NominalWithGrant: -90 + + # pucch-ConfigCommon setup : + # pucchGroupHopping + # 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping: 0 + hoppingId: 40 + p0_nominal: -90 + ssb_PositionsInBurst_Bitmap: 1 + # ssb_periodicityServingCell + # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell: 2 + + # dmrs_TypeA_position + # 0 = pos2, 1 = pos3 + dmrs_TypeA_Position: 0 + + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing: 1 + + #tdd-UL-DL-ConfigurationCommon + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing: 1 + + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity: 6 + nrofDownlinkSlots: 7 + nrofDownlinkSymbols: 6 + nrofUplinkSlots: 2 + nrofUplinkSymbols: 4 + ssPBCH_BlockPower: -25 + SCTP: + SCTP_INSTREAMS: 2 + SCTP_OUTSTREAMS: 2 + + ##### AMF parameters: + amf_ip_address: + - ipv4: 192.168.71.132 + + NETWORK_INTERFACES: + GNB_IPV4_ADDRESS_FOR_NG_AMF: 192.168.71.140 + GNB_IPV4_ADDRESS_FOR_NGU: 192.168.71.140 + GNB_PORT_FOR_S1U: 2152 # Spec 2152 + + +MACRLCs: + - num_cc: 1 + tr_s_preference: local_L1 + tr_n_preference: local_RRC + pusch_TargetSNRx10: 200 + pucch_TargetSNRx10: 200 + +L1s: + - num_cc: 1 + tr_n_preference: local_mac + prach_dtx_threshold: 200 + # pucch0_dtx_threshold = 150; + +RUs: + - local_rf: yes + nb_tx: 1 + nb_rx: 1 + att_tx: 0 + att_rx: 0 + bands: [78] + max_pdschReferenceSignalPower: -27 + max_rxgain: 75 + eNB_instances: [0] + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights: [0x00007fff, 0x0000] + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sf_extension: 0 + sdr_addrs: serial=XXXXXXX + +rfsimulator: + serveraddr: server + +security: + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms: [nea0] + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms: [nia2, nia0] + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + 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: info + pdcp_log_level: info + rrc_log_level: info + ngap_log_level: debug + f1ap_log_level: debug diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml index 4e7001638f..448bf45dc4 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml @@ -94,7 +94,7 @@ services: public_net: ipv4_address: 192.168.71.140 volumes: - - ../../conf_files/gnb.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf + - ../../conf_files/gnb.sa.band78.106prb.rfsim.yaml:/opt/oai-gnb/etc/gnb.yaml healthcheck: test: /bin/bash -c "pgrep nr-softmodem" interval: 10s diff --git a/docker/Dockerfile.gNB.aerial.ubuntu22 b/docker/Dockerfile.gNB.aerial.ubuntu22 index dcfe005caa..7440dfc9e8 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu22 +++ b/docker/Dockerfile.gNB.aerial.ubuntu22 @@ -78,7 +78,8 @@ RUN apt-get update && \ iputils-ping \ gdb \ moreutils \ - libusb-1.0-0 && \ + libusb-1.0-0 \ + libyaml-cpp-dev && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-gnb/bin @@ -86,7 +87,10 @@ COPY --from=ran-build \ /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./ COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh -COPY --from=ran-build /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so /usr/local/lib/ +COPY --from=ran-build \ + /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ + /usr/local/lib/ #copy files from nvIPC COPY --from=ran-build \ @@ -107,4 +111,4 @@ RUN ldconfig && \ WORKDIR /opt/oai-gnb COPY --from=ran-build /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address b/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address index 62c7de33d6..4d613718b4 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address +++ b/docker/Dockerfile.gNB.aerial.ubuntu22.sanitize-address @@ -78,7 +78,8 @@ RUN apt-get update && \ iputils-ping \ gdb \ moreutils \ - libusb-1.0-0 && \ + libusb-1.0-0 \ + libyaml-cpp-dev && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-gnb/bin @@ -92,6 +93,7 @@ COPY --from=ran-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ #copy files from nvIPC @@ -113,4 +115,4 @@ RUN ldconfig && \ WORKDIR /opt/oai-gnb COPY --from=ran-build /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.rhel9 b/docker/Dockerfile.gNB.aw2s.rhel9 index 0cb4def5fd..65eafac37b 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel9 +++ b/docker/Dockerfile.gNB.aw2s.rhel9 @@ -41,6 +41,9 @@ RUN /bin/sh oaienv && \ FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-gnb-aw2s ENV TZ=Europe/Paris +# Install EPEL for RHEL9 +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + RUN dnf update -y && \ dnf install -y \ procps-ng \ @@ -50,7 +53,8 @@ RUN dnf update -y && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -69,6 +73,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -98,4 +103,4 @@ WORKDIR /opt/oai-gnb-aw2s COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem", "-O", "/opt/oai-gnb-aw2s/etc/gnb.conf"] +CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.rocky b/docker/Dockerfile.gNB.aw2s.rocky index bdd1eb4e38..1c0adfccd8 100644 --- a/docker/Dockerfile.gNB.aw2s.rocky +++ b/docker/Dockerfile.gNB.aw2s.rocky @@ -70,6 +70,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -96,4 +97,4 @@ WORKDIR /opt/oai-gnb-aw2s COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem", "-O", "/opt/oai-gnb-aw2s/etc/gnb.conf"] +CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu22 b/docker/Dockerfile.gNB.aw2s.ubuntu22 index 1d81423c26..11893171db 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu22 +++ b/docker/Dockerfile.gNB.aw2s.ubuntu22 @@ -55,7 +55,8 @@ RUN apt-get update && \ openssl \ net-tools \ iproute2 \ - iputils-ping && \ + iputils-ping \ + libyaml-cpp-dev && \ rm -rf /var/lib/apt/lists/* COPY ./libori.so /usr/local/lib/ @@ -73,6 +74,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ @@ -95,4 +97,4 @@ WORKDIR /opt/oai-gnb-aw2s COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem", "-O", "/opt/oai-gnb-aw2s/etc/gnb.conf"] +CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.rhel9 b/docker/Dockerfile.gNB.fhi72.rhel9 index 0d629ac8a1..5f68599873 100644 --- a/docker/Dockerfile.gNB.fhi72.rhel9 +++ b/docker/Dockerfile.gNB.fhi72.rhel9 @@ -33,6 +33,9 @@ FROM ran-build-fhi72:latest AS gnb-build FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-gnb-fhi72 ENV TZ=Europe/Paris +# Install EPEL for RHEL9 +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + # Copy the entitlements COPY ./etc-pki-entitlement /etc/pki/entitlement @@ -55,7 +58,8 @@ RUN rm -f /etc/rhsm-host && \ python3 \ python3-pip \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -78,6 +82,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ ## Libxran library @@ -122,4 +127,4 @@ RUN ldconfig && \ WORKDIR /opt/oai-gnb COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.rocky b/docker/Dockerfile.gNB.fhi72.rocky index a98c0b1948..3fdc2f97af 100644 --- a/docker/Dockerfile.gNB.fhi72.rocky +++ b/docker/Dockerfile.gNB.fhi72.rocky @@ -70,6 +70,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ ## Libxran library @@ -114,4 +115,4 @@ RUN ldconfig && \ WORKDIR /opt/oai-gnb COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.ubuntu22 b/docker/Dockerfile.gNB.fhi72.ubuntu22 index 31f2392af7..069055d63b 100644 --- a/docker/Dockerfile.gNB.fhi72.ubuntu22 +++ b/docker/Dockerfile.gNB.fhi72.ubuntu22 @@ -58,7 +58,8 @@ RUN apt-get update && \ libnuma-dev \ python3 \ python3-six \ - python3-requests &&\ + python3-requests \ + libyaml-cpp-dev && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ libasan5 \ @@ -80,6 +81,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ ## Libxran library @@ -110,4 +112,4 @@ RUN ldconfig && \ WORKDIR /opt/oai-gnb COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.rhel9 b/docker/Dockerfile.gNB.rhel9 index 625590efad..894d1f6aa7 100644 --- a/docker/Dockerfile.gNB.rhel9 +++ b/docker/Dockerfile.gNB.rhel9 @@ -34,6 +34,9 @@ FROM ran-build:latest AS gnb-build FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-gnb ENV TZ=Europe/Paris +# Install EPEL for RHEL9 +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + RUN dnf update -y && \ dnf install -y \ procps-ng \ @@ -46,7 +49,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -67,6 +71,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -125,4 +130,4 @@ WORKDIR /opt/oai-gnb COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.rocky b/docker/Dockerfile.gNB.rocky index c1665e5a86..5c17c78e57 100644 --- a/docker/Dockerfile.gNB.rocky +++ b/docker/Dockerfile.gNB.rocky @@ -68,6 +68,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -123,4 +124,4 @@ WORKDIR /opt/oai-gnb COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.ubuntu22 b/docker/Dockerfile.gNB.ubuntu22 index 6213ed0ca3..8d154eeb13 100644 --- a/docker/Dockerfile.gNB.ubuntu22 +++ b/docker/Dockerfile.gNB.ubuntu22 @@ -63,7 +63,8 @@ RUN apt-get update && \ python3 \ python3-six \ python3-requests \ - libusb-1.0-0 && \ + libusb-1.0-0 \ + libyaml-cpp-dev && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ #libasan5 \ # see below @@ -93,6 +94,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ # Now we are copying from builder-image the UHD files. @@ -128,4 +130,4 @@ WORKDIR /opt/oai-gnb COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] -CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index 9253d4a3e1..7139bff0ec 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -9,14 +9,29 @@ echo "==================================" echo "/proc/sys/kernel/core_pattern=$(cat /proc/sys/kernel/core_pattern)" if [ ! -f $CONFIGFILE ]; then - echo "No configuration file found: please mount at $CONFIGFILE" - exit 255 + echo "No configuration file $CONFIGFILE found: attempting to find YAML config" + YAML_CONFIGFILE=$PREFIX/etc/gnb.yaml + if [ ! -f $YAML_CONFIGFILE ]; then + echo "No configuration file $YAML_CONFIGFILE found. Please mount either at $CONFIGFILE or $YAML_CONFIGFILE" + exit 255 + fi + CONFIGFILE=$YAML_CONFIGFILE fi echo "==================================" echo "== Configuration file:" cat $CONFIGFILE +new_args=() + +while [[ $# -gt 0 ]]; do + new_args+=("$1") + shift +done + +new_args+=("-O") +new_args+=("$CONFIGFILE") + # Load the USRP binaries echo "==================================" echo "== Load USRP binaries" @@ -35,7 +50,6 @@ echo "==================================" echo "== Starting gNB soft modem" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}" - new_args=() while [[ $# -gt 0 ]]; do new_args+=("$1") shift @@ -46,6 +60,6 @@ if [[ -v USE_ADDITIONAL_OPTIONS ]]; then echo "${new_args[@]}" exec "${new_args[@]}" else - echo "$@" - exec "$@" + echo "${new_args[@]}" + exec "${new_args[@]}" fi From 0daabdeb8754674558a86b1f11c3b427d12d899f Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Mon, 7 Oct 2024 09:15:44 +0200 Subject: [PATCH 68/73] Update the aw2s entrypoint to support new yaml config and updated images --- docker/scripts/gnb-aw2s_entrypoint.sh | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/docker/scripts/gnb-aw2s_entrypoint.sh b/docker/scripts/gnb-aw2s_entrypoint.sh index 7085800d13..7df325d78b 100755 --- a/docker/scripts/gnb-aw2s_entrypoint.sh +++ b/docker/scripts/gnb-aw2s_entrypoint.sh @@ -9,14 +9,29 @@ echo "==================================" echo "/proc/sys/kernel/core_pattern=$(cat /proc/sys/kernel/core_pattern)" if [ ! -f $CONFIGFILE ]; then - echo "No configuration file found: please mount at $CONFIGFILE" - exit 255 + echo "No configuration file $CONFIGFILE found: attempting to find YAML config" + YAML_CONFIGFILE=$PREFIX/etc/gnb.yaml + if [ ! -f $YAML_CONFIGFILE ]; then + echo "No configuration file $YAML_CONFIGFILE found. Please mount either at $CONFIGFILE or $YAML_CONFIGFILE" + exit 255 + fi + CONFIGFILE=$YAML_CONFIGFILE fi echo "==================================" echo "== Configuration file:" cat $CONFIGFILE +new_args=() + +while [[ $# -gt 0 ]]; do + new_args+=("$1") + shift +done + +new_args+=("-O") +new_args+=("$CONFIGFILE") + # enable printing of stack traces on assert export OAI_GDBSTACKS=1 @@ -24,7 +39,6 @@ echo "==================================" echo "== Starting gNB soft modem with AW2S" if [[ -v USE_ADDITIONAL_OPTIONS ]]; then echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}" - new_args=() while [[ $# -gt 0 ]]; do new_args+=("$1") shift @@ -35,6 +49,6 @@ if [[ -v USE_ADDITIONAL_OPTIONS ]]; then echo "${new_args[@]}" exec "${new_args[@]}" else - echo "$@" - exec "$@" + echo "${new_args[@]}" + exec "${new_args[@]}" fi From f77f428767bb91e3052a5d97496697cd0225e8b6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 7 Aug 2024 10:08:28 +0200 Subject: [PATCH 69/73] Small optimization L2 to wireshark the code creates a sink to read all traced packets and drop it. but this works only if we send to a local address and if there is not another sink (like if we trace both UE and gNB in the same machine). this sink's purpose is only to prevent to get automatic packets back from the kernel saying "no listener". So, instead of killing the trace when we can't create the sink (as done previously), we now just let the trace in operation. --- openair2/UTIL/OPT/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 465baa7301..a4994421c2 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -254,7 +254,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) { LOG_E(OPT, "Failed to bind socket to (%s:%u): %s\n", inet_ntoa(opt_listener.address.sin_addr), ntohs(opt_listener.address.sin_port), strerror(errno)); - opt_type = OPT_NONE; + // we log anyway as planned because other OAI process may have created the sink close(opt_listener.sd); opt_listener.sd = -1; return -1; From 8f46b07b22bce29cdca7408d5056944bb5e8b13d Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 4 Sep 2024 18:20:49 +0200 Subject: [PATCH 70/73] Lacking RRC check: avoid SEGV if the received packet is not what we believe --- openair2/RRC/NR_UE/rrc_UE.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index fdff0bc421..ed8c47ae5f 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -551,14 +551,16 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, } int get_sib = 0; - if (get_softmodem_params()->sa && - bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && - rrc->nrRrcState != RRC_STATE_DETACH_NR) { + if (get_softmodem_params()->sa && bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib + && bcch_message->message.choice.mib->cellBarred == NR_MIB__cellBarred_notBarred && rrc->nrRrcState != RRC_STATE_DETACH_NR) { NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); } - nr_rrc_mac_config_req_mib(rrc->ue_id, 0, bcch_message->message.choice.mib, get_sib); + if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) + nr_rrc_mac_config_req_mib(rrc->ue_id, 0, bcch_message->message.choice.mib, get_sib); + else + LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n"); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message); return; } From a648afd4c69f06e1013d4ff0a4b9314172e5963c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 7 Oct 2024 14:14:10 +0200 Subject: [PATCH 71/73] RFsim Client: Improve logs - Remove double "Connection ... established" (already printed in caller) - Remove useless, there is already the logging module - Print getaddrinfo() error as LOG_E (error) --- radio/rfsimulator/simulator.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 2b358cd5bb..3c19b492c8 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -635,7 +635,7 @@ static int client_try_connect(const char *host, uint16_t port) s = getaddrinfo(host, dport, &hints, &result); if (s != 0) { - LOG_I(HW, "getaddrinfo: %s\n", gai_strerror(s)); + LOG_E(HW, "getaddrinfo: %s\n", gai_strerror(s)); return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { @@ -645,7 +645,6 @@ static int client_try_connect(const char *host, uint16_t port) } if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) { - LOG_I(HW, "Connection to %s:%d established\n", host, port); break; } @@ -674,7 +673,6 @@ static int startClient(openair0_device *device) } LOG_I(HW, "connect() to %s:%d failed, errno(%d)\n", t->ip, t->port, errno); - fprintf(stderr, "Could not connect\n"); sleep(1); } From ac7c02d8e59ab49e3299d0bff81bd2308200437f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 7 Oct 2024 14:11:33 +0200 Subject: [PATCH 72/73] CI 5G E1 RFsim test: Use DNS name for RFsim --- ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml index 8c937ed76c..c5d4d3aa61 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml @@ -289,7 +289,7 @@ services: USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time -r 106 --numerology 1 -C 3619200000 --uicc0.imsi 208990100001100 - --rfsimulator.serveraddr 192.168.78.2 + --rfsimulator.serveraddr oai-du depends_on: - oai-du networks: From d6f0ff37c2903f0c78627b10259150a160eb6f49 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 7 Oct 2024 14:12:52 +0200 Subject: [PATCH 73/73] RFsim: doc serveraddr: mention IPv4v6 and DNS --- radio/rfsimulator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md index ba63ae4ec0..c86724fa0d 100644 --- a/radio/rfsimulator/README.md +++ b/radio/rfsimulator/README.md @@ -71,7 +71,7 @@ The RF simulator is using the configuration module, and its parameters are defin | CL option | usage | default | |:--------------------- |:-------------------------------------------------------------------------------|----: | -|`--rfsimulator.serveraddr `| ip address to connect to, or `server` to behave as a tcp server | 127.0.0.1 | +|`--rfsimulator.serveraddr `| IPv4v6 address or DNS name to connect to, or `server` to behave as a IPv4v6 TCP server | 127.0.0.1 | |`--rfsimulator.serverport `| port number to connect to or to listen on (eNB, which behaves as a tcp server) | 4043 | |`--rfsimulator.options` | list of comma separated run-time options, two are supported: `chanmod`, `saviq`| all options disabled | |`--rfsimulator.options saviq` | store IQs to a file for future replay | disabled |