From 0282e64a3bc659faa3ca556a6161e88c2703f473 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 22 Jan 2026 18:51:27 +0530 Subject: [PATCH] Add TRP Information Response NRPPA message encoding procedures Supported TRP Information Response Types: - PCI NR - NG RAN CGI - NR ARFCN - GEOGRAPHICAL COORDINATES --- openair2/COMMON/nrppa_messages_def.h | 1 + openair2/COMMON/nrppa_messages_types.h | 181 ++++++++++ openair3/NRPPA/CMakeLists.txt | 1 + openair3/NRPPA/nrppa_gNB.c | 3 + openair3/NRPPA/nrppa_gNB_encoder.c | 135 ++++++++ openair3/NRPPA/nrppa_gNB_encoder.h | 27 ++ .../nrppa_gNB_location_information_transfer.c | 322 ++++++++++++++++++ .../nrppa_gNB_location_information_transfer.h | 4 + openair3/NRPPA/nrppa_gNB_ue_context.c | 11 + openair3/NRPPA/nrppa_gNB_ue_context.h | 1 + openair3/NRPPA/nrppa_includes.h | 7 + tests/nr-cu-nrppa/nr-cu-nrppa.c | 108 ++++++ 12 files changed, 801 insertions(+) create mode 100644 openair3/NRPPA/nrppa_gNB_encoder.c create mode 100644 openair3/NRPPA/nrppa_gNB_encoder.h diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index ae17d73742..ecca67ba33 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -23,3 +23,4 @@ // LMF -> CU MESSAGE_DEF(NRPPA_TRP_INFORMATION_REQ, MESSAGE_PRIORITY_MED, nrppa_trp_information_req_t, nrppa_trp_information_req) +MESSAGE_DEF(NRPPA_TRP_INFORMATION_RESP, MESSAGE_PRIORITY_MED, nrppa_trp_information_resp_t, nrppa_trp_information_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index 55563a59ab..f461909a35 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -25,6 +25,7 @@ // Defines to access message fields. #define NRPPA_TRP_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_req +#define NRPPA_TRP_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_resp /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -54,6 +55,179 @@ typedef struct nrppa_trp_list_s { uint32_t trp_list_length; } nrppa_trp_list_t; +typedef struct nrppa_access_point_position_s { + long latitude_sign; + long latitude; + long longitude; + long direction_of_altitude; + long altitude; + long uncertainty_semi_major; + long uncertainty_semi_minor; + long orientation_of_major_axis; + long uncertainty_altitude; + long confidence; +} nrppa_access_point_position_t; + +typedef struct nrppa_ngran_high_accuracy_access_point_position_s { + long latitude; + long longitude; + long altitude; + long uncertainty_semi_major; + long uncertainty_semi_minor; + long orientation_of_major_axis; + long horizontal_confidence; + long uncertainty_altitude; + long vertical_confidence; +} nrppa_ngran_high_accuracy_access_point_position_t; + +typedef union nrppa_trp_position_direct_accuracy_c { + nrppa_access_point_position_t trp_position; + nrppa_ngran_high_accuracy_access_point_position_t trp_HAposition; +} nrppa_trp_position_direct_accuracy_u; + +typedef enum nrppa_trp_position_direct_accuracy_e { + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_NOTHING, + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION, + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION +} nrppa_trp_position_direct_accuracy_pr; + +typedef struct nrppa_trp_position_direct_accuracy_s { + nrppa_trp_position_direct_accuracy_pr present; + nrppa_trp_position_direct_accuracy_u choice; +} nrppa_trp_position_direct_accuracy_t; + +typedef struct nrppa_trp_position_direct_s { + nrppa_trp_position_direct_accuracy_t accuracy; +} nrppa_trp_position_direct_t; + +typedef enum nrppa_reference_point_e { + NRPPA_REFERENCE_POINT_PR_NOTHING, + NRPPA_REFERENCE_POINT_PR_COORDINATEID, + NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE, + NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA +} nrppa_reference_point_pr; + +typedef union nrppa_reference_point_c { + long coordinate_id; + nrppa_access_point_position_t reference_point_coordinate; + nrppa_ngran_high_accuracy_access_point_position_t reference_point_coordinateHA; +} nrppa_reference_point_u; + +typedef struct nrppa_reference_point_s { + nrppa_reference_point_pr present; + nrppa_reference_point_u choice; +} nrppa_reference_point_t; + +typedef struct nrppa_location_uncertainty_s { + long horizontal_uncertainty; + long horizontal_confidence; + long vertical_uncertainty; + long vertical_confidence; +} nrppa_location_uncertainty_t; + +typedef struct nrppa_relative_geodetic_location_s { + long milli_arc_second_units; + long height_units; + long delta_latitude; + long delta_longitude; + long delta_height; + nrppa_location_uncertainty_t location_uncertainty; +} nrppa_relative_geodetic_location_t; + +typedef struct nrppa_relative_cartesian_location_s { + long xyz_unit; + long xvalue; + long yvalue; + long zvalue; + nrppa_location_uncertainty_t location_uncertainty; +} nrppa_relative_cartesian_location_t; + +typedef union nrppa_trp_reference_point_type_c { + nrppa_relative_geodetic_location_t trp_position_relative_geodetic; + nrppa_relative_cartesian_location_t trp_position_relative_cartesian; +} nrppa_trp_reference_point_type_u; + +typedef enum nrppa_trp_reference_point_type_e { + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_NOTHING, + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC, + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN +} nrppa_trp_reference_point_type_pr; + +typedef struct nrppa_trp_reference_point_type_t { + nrppa_trp_reference_point_type_pr present; + nrppa_trp_reference_point_type_u choice; +} nrppa_trp_reference_point_type_t; + +typedef struct nrppa_trp_position_referenced_t { + nrppa_reference_point_t reference_point; + nrppa_trp_reference_point_type_t reference_point_type; +} nrppa_trp_position_referenced_t; + +typedef union nrppa_trp_position_definition_type_c { + nrppa_trp_position_direct_t direct; + nrppa_trp_position_referenced_t referenced; +} nrppa_trp_position_definition_type_u; + +typedef enum nrppa_trp_position_definition_type_e { + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING, + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT, + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED +} nrppa_trp_position_definition_type_pr; + +typedef struct nrppa_trp_position_definition_type_s { + nrppa_trp_position_definition_type_u choice; + nrppa_trp_position_definition_type_pr present; +} nrppa_trp_position_definition_type_t; + +typedef struct nrppa_geographical_coordinates_s { + nrppa_trp_position_definition_type_t trp_position_definition_type; +} nrppa_geographical_coordinates_t; + +typedef struct nrppa_ng_ran_cgi_s { + plmn_id_t plmn; + uint64_t nr_cellid; +} nrppa_ng_ran_cgi_t; + +typedef union nrppa_trp_information_type_response_item_c { + uint16_t pci_nr; + nrppa_ng_ran_cgi_t ng_ran_cgi; + uint32_t nr_arfcn; + nrppa_geographical_coordinates_t geographical_coordinates; +} nrppa_trp_information_type_response_item_u; + +typedef enum nrppa_trp_information_type_response_item_e { + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES +} nrppa_trp_information_type_response_item_pr; + +typedef struct nrppa_trp_information_type_response_item_s { + nrppa_trp_information_type_response_item_pr present; + nrppa_trp_information_type_response_item_u choice; +} nrppa_trp_information_type_response_item_t; + +typedef struct nrppa_trp_information_type_response_list_s { + nrppa_trp_information_type_response_item_t *trp_information_type_response_item; + uint8_t trp_information_type_response_item_length; +} nrppa_trp_information_type_response_list_t; + +typedef struct nrppa_trp_information_s { + uint32_t trp_id; + nrppa_trp_information_type_response_list_t trp_information_type_response_list; +} nrppa_trp_information_t; + +// IE 9.3.1.176 (TS 38.473 V16.21.0) +typedef struct nrppa_trp_information_list_s { + nrppa_trp_information_t *trp_information_item; + uint32_t trp_information_item_length; +} nrppa_trp_information_list_t; + typedef struct nrppa_trp_information_req_s { // IE 9.2.4 (mandatory) uint16_t transaction_id; @@ -64,4 +238,11 @@ typedef struct nrppa_trp_information_req_s { nrppa_trp_information_type_list_t trp_information_type_list; } nrppa_trp_information_req_t; +typedef struct nrppa_trp_information_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // mandatory + nrppa_trp_information_list_t trp_information_list; +} nrppa_trp_information_resp_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/CMakeLists.txt b/openair3/NRPPA/CMakeLists.txt index 28ad4c8618..7ec77db3b5 100644 --- a/openair3/NRPPA/CMakeLists.txt +++ b/openair3/NRPPA/CMakeLists.txt @@ -7,6 +7,7 @@ add_library(nrppa nrppa_gNB_decoder.c nrppa_gNB_ue_context.c nrppa_gNB_location_information_transfer.c + nrppa_gNB_encoder.c ) target_link_libraries(nrppa PUBLIC asn1_nrppa) diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c index d7f067de98..bb00cecd54 100644 --- a/openair3/NRPPA/nrppa_gNB.c +++ b/openair3/NRPPA/nrppa_gNB.c @@ -57,6 +57,9 @@ void *nrppa_gNB_process_itti_msg(void *notUsed) case NGAP_DOWNLINKNONUEASSOCIATEDNRPPA: nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance, &NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(received_msg)); break; + case NRPPA_TRP_INFORMATION_RESP: + nrppa_gNB_trp_information_response(instance, received_msg); + break; default: LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NRPPA/nrppa_gNB_encoder.c b/openair3/NRPPA/nrppa_gNB_encoder.c new file mode 100644 index 0000000000..9ac0c4ecb0 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_encoder.c @@ -0,0 +1,135 @@ +/* + * 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 +#include +#include "nrppa_common.h" +#include "nrppa_gNB_encoder.h" + +static inline int nrppa_gNB_encode_initiating(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_positioningInformationUpdate, + NRPPA_ProcedureCode_id_positioningDeactivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement, + NRPPA_ProcedureCode_id_MeasurementReport, + NRPPA_ProcedureCode_id_MeasurementFailureIndication, + NRPPA_ProcedureCode_id_MeasurementAbort, + NRPPA_ProcedureCode_id_MeasurementUpdate}; + + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.initiatingMessage->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_E(NRPPA, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int nrppa_gNB_encode_successfull_outcome(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement}; + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.successfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_E(NRPPA, "Unknown procedure ID (%ld) for successfull outcome message\n", pdu->choice.successfulOutcome->procedureCode); + return -1; + } + // xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int nrppa_gNB_encode_unsuccessfull_outcome(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement}; + + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.unsuccessfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_W(NRPPA, "Unknown procedure ID (%ld) for unsuccessfull outcome message\n", pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +int nrppa_gNB_encode_pdu(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + int ret = -1; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + // xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, (void *)pdu); + + switch (pdu->present) { + case NRPPA_NRPPA_PDU_PR_initiatingMessage: + ret = nrppa_gNB_encode_initiating(pdu, buffer, len); + break; + + case NRPPA_NRPPA_PDU_PR_successfulOutcome: + ret = nrppa_gNB_encode_successfull_outcome(pdu, buffer, len); + break; + + case NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome: + ret = nrppa_gNB_encode_unsuccessfull_outcome(pdu, buffer, len); + break; + + default: + LOG_E(NRPPA, "Unknown message outcome (%d) or not implemented", (int)pdu->present); + return -1; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, pdu); + return ret; +} diff --git a/openair3/NRPPA/nrppa_gNB_encoder.h b/openair3/NRPPA/nrppa_gNB_encoder.h new file mode 100644 index 0000000000..dee34a2060 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_encoder.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 NRPPA_GNB_ENCODER_H_ +#define NRPPA_GNB_ENCODER_H_ + +int nrppa_gNB_encode_pdu(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) __attribute__((warn_unused_result)); + +#endif /* NRPPA_GNB_ENCODER_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index 6a617ea02b..bc1af664cd 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -24,6 +24,8 @@ #include "nrppa_gNB_location_information_transfer.h" #include "nrppa_gNB_ue_context.h" #include "nrppa_messages_types.h" +#include "nrppa_gNB_encoder.h" +#include "openair3/UTILS/conversions.h" void free_trp_information_request(nrppa_trp_information_req_t *msg) { @@ -32,6 +34,235 @@ void free_trp_information_request(nrppa_trp_information_req_t *msg) } } +static NRPPA_TRPPositionDirect_t encode_trp_position_direct(nrppa_trp_position_direct_t *in) +{ + NRPPA_TRPPositionDirect_t out = {0}; + + switch (in->accuracy.present) { + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_NOTHING: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_NOTHING; + break; + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_tRPPosition; + asn1cCalloc(out.accuracy.choice.tRPPosition, out_pos); + nrppa_access_point_position_t *in_pos = &in->accuracy.choice.trp_position; + + out_pos->latitudeSign = in_pos->latitude_sign; + out_pos->latitude = in_pos->latitude; + out_pos->longitude = in_pos->longitude; + out_pos->directionOfAltitude = in_pos->direction_of_altitude; + out_pos->altitude = in_pos->altitude; + out_pos->uncertaintySemi_major = in_pos->uncertainty_semi_major; + out_pos->uncertaintySemi_minor = in_pos->uncertainty_semi_minor; + out_pos->orientationOfMajorAxis = in_pos->orientation_of_major_axis; + out_pos->uncertaintyAltitude = in_pos->uncertainty_altitude; + out_pos->confidence = in_pos->confidence; + break; + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_tRPHAposition; + asn1cCalloc(out.accuracy.choice.tRPHAposition, out_ha_pos); + nrppa_ngran_high_accuracy_access_point_position_t *in_ha_pos = &in->accuracy.choice.trp_HAposition; + out_ha_pos->latitude = in_ha_pos->latitude; + out_ha_pos->longitude = in_ha_pos->longitude; + out_ha_pos->altitude = in_ha_pos->altitude; + out_ha_pos->uncertaintySemi_major = in_ha_pos->uncertainty_semi_major; + out_ha_pos->uncertaintySemi_minor = in_ha_pos->uncertainty_semi_minor; + out_ha_pos->orientationOfMajorAxis = in_ha_pos->orientation_of_major_axis; + out_ha_pos->horizontalConfidence = in_ha_pos->horizontal_confidence; + out_ha_pos->uncertaintyAltitude = in_ha_pos->uncertainty_altitude; + out_ha_pos->verticalConfidence = in_ha_pos->vertical_confidence; + break; + default: + AssertFatal(false, "illegal direct accuracy entry\n"); + break; + } + return out; +} + +static NRPPA_TRPPositionReferenced_t encode_trp_position_referenced(nrppa_trp_position_referenced_t *in) +{ + NRPPA_TRPPositionReferenced_t out = {0}; + NRPPA_ReferencePoint_t *out_ref_point = &out.referencePoint; + nrppa_reference_point_t *in_ref_point = &in->reference_point; + switch (in_ref_point->present) { + case NRPPA_REFERENCE_POINT_PR_NOTHING: + out_ref_point->present = NRPPA_ReferencePoint_PR_NOTHING; + break; + case NRPPA_REFERENCE_POINT_PR_COORDINATEID: + out_ref_point->present = NRPPA_ReferencePoint_PR_relativeCoordinateID; + out_ref_point->choice.relativeCoordinateID = in_ref_point->choice.coordinate_id; + break; + case NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE: + out_ref_point->present = NRPPA_ReferencePoint_PR_referencePointCoordinate; + asn1cCalloc(out_ref_point->choice.referencePointCoordinate, out_ref_coord); + nrppa_access_point_position_t *in_ref_coord = &in_ref_point->choice.reference_point_coordinate; + out_ref_coord->latitudeSign = in_ref_coord->latitude_sign; + out_ref_coord->latitude = in_ref_coord->latitude; + out_ref_coord->longitude = in_ref_coord->longitude; + out_ref_coord->directionOfAltitude = in_ref_coord->direction_of_altitude; + out_ref_coord->altitude = in_ref_coord->altitude; + out_ref_coord->uncertaintySemi_major = in_ref_coord->uncertainty_semi_major; + out_ref_coord->uncertaintySemi_minor = in_ref_coord->uncertainty_semi_minor; + out_ref_coord->orientationOfMajorAxis = in_ref_coord->orientation_of_major_axis; + out_ref_coord->uncertaintyAltitude = in_ref_coord->uncertainty_altitude; + out_ref_coord->confidence = in_ref_coord->confidence; + break; + case NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA: + out_ref_point->present = NRPPA_ReferencePoint_PR_referencePointCoordinateHA; + asn1cCalloc(out_ref_point->choice.referencePointCoordinateHA, out_ref_coord_ha); + nrppa_ngran_high_accuracy_access_point_position_t *in_ref_coord_ha = &in_ref_point->choice.reference_point_coordinateHA; + out_ref_coord_ha->latitude = in_ref_coord_ha->latitude; + out_ref_coord_ha->longitude = in_ref_coord_ha->longitude; + out_ref_coord_ha->altitude = in_ref_coord_ha->altitude; + out_ref_coord_ha->uncertaintySemi_major = in_ref_coord_ha->uncertainty_semi_major; + out_ref_coord_ha->uncertaintySemi_minor = in_ref_coord_ha->uncertainty_semi_minor; + out_ref_coord_ha->orientationOfMajorAxis = in_ref_coord_ha->orientation_of_major_axis; + out_ref_coord_ha->horizontalConfidence = in_ref_coord_ha->horizontal_confidence; + out_ref_coord_ha->uncertaintyAltitude = in_ref_coord_ha->uncertainty_altitude; + out_ref_coord_ha->verticalConfidence = in_ref_coord_ha->vertical_confidence; + break; + default: + AssertFatal(false, "illegal reference point entry\n"); + break; + } + + NRPPA_TRPReferencePointType_t *out_ref_point_type = &out.referencePointType; + nrppa_trp_reference_point_type_t *in_ref_point_type = &in->reference_point_type; + switch (in_ref_point_type->present) { + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_NOTHING: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_NOTHING; + break; + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_tRPPositionRelativeGeodetic; + asn1cCalloc(out_ref_point_type->choice.tRPPositionRelativeGeodetic, out_geodetic); + nrppa_relative_geodetic_location_t *in_geodetic = &in_ref_point_type->choice.trp_position_relative_geodetic; + out_geodetic->milli_Arc_SecondUnits = in_geodetic->milli_arc_second_units; + out_geodetic->heightUnits = in_geodetic->height_units; + out_geodetic->deltaLatitude = in_geodetic->delta_latitude; + out_geodetic->deltaLongitude = in_geodetic->delta_longitude; + out_geodetic->deltaHeight = in_geodetic->delta_height; + NRPPA_LocationUncertainty_t *out_loc_uncertainty_g = &out_geodetic->locationUncertainty; + nrppa_location_uncertainty_t *in_loc_uncertainty_g = &in_geodetic->location_uncertainty; + out_loc_uncertainty_g->horizontalUncertainty = in_loc_uncertainty_g->horizontal_uncertainty; + out_loc_uncertainty_g->horizontalConfidence = in_loc_uncertainty_g->horizontal_confidence; + out_loc_uncertainty_g->verticalUncertainty = in_loc_uncertainty_g->vertical_uncertainty; + out_loc_uncertainty_g->verticalConfidence = in_loc_uncertainty_g->vertical_confidence; + break; + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_tRPPositionRelativeCartesian; + asn1cCalloc(out_ref_point_type->choice.tRPPositionRelativeCartesian, out_cartesian); + nrppa_relative_cartesian_location_t *in_cartesian = &in_ref_point_type->choice.trp_position_relative_cartesian; + + out_cartesian->xYZunit = in_cartesian->xyz_unit; + out_cartesian->xvalue = in_cartesian->xvalue; + out_cartesian->yvalue = in_cartesian->yvalue; + out_cartesian->zvalue = in_cartesian->zvalue; + NRPPA_LocationUncertainty_t *out_loc_uncertainty_c = &out_cartesian->locationUncertainty; + nrppa_location_uncertainty_t *in_loc_uncertainty_c = &in_cartesian->location_uncertainty; + out_loc_uncertainty_c->horizontalUncertainty = in_loc_uncertainty_c->horizontal_uncertainty; + out_loc_uncertainty_c->horizontalConfidence = in_loc_uncertainty_c->horizontal_confidence; + out_loc_uncertainty_c->verticalUncertainty = in_loc_uncertainty_c->vertical_uncertainty; + out_loc_uncertainty_c->verticalConfidence = in_loc_uncertainty_c->vertical_confidence; + break; + default: + AssertFatal(false, "illegal trp reference point type entry\n"); + break; + } + return out; +} + +static NRPPA_GeographicalCoordinates_t encode_geographical_coordinates_nrppa(nrppa_geographical_coordinates_t *in) +{ + NRPPA_GeographicalCoordinates_t out = {0}; + NRPPA_TRPPositionDefinitionType_t *out_type = &out.tRPPositionDefinitionType; + nrppa_trp_position_definition_type_t *in_type = &in->trp_position_definition_type; + switch (in_type->present) { + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_NOTHING; + break; + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_direct; + asn1cCalloc(out_type->choice.direct, direct); + *direct = encode_trp_position_direct(&in_type->choice.direct); + break; + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_referenced; + asn1cCalloc(out_type->choice.referenced, referenced); + *referenced = encode_trp_position_referenced(&in_type->choice.referenced); + break; + default: + AssertFatal(false, "illegal Geographical Coordinates entry\n"); + break; + } + return out; +} + +NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in) +{ + NRPPA_TRPInformationItem_t out = {0}; + switch (in->present) { + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING: + out.present = NRPPA_TRPInformationItem_PR_NOTHING; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR: + out.present = NRPPA_TRPInformationItem_PR_pCI_NR; + out.choice.pCI_NR = in->choice.pci_nr; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI: + out.present = NRPPA_TRPInformationItem_PR_nG_RAN_CGI; + asn1cCalloc(out.choice.nG_RAN_CGI, nG_RAN_CGI); + MCC_MNC_TO_PLMNID(in->choice.ng_ran_cgi.plmn.mcc, + in->choice.ng_ran_cgi.plmn.mnc, + in->choice.ng_ran_cgi.plmn.mnc_digit_length, + &(nG_RAN_CGI->pLMN_Identity)); + nG_RAN_CGI->nG_RANcell.present = NRPPA_NG_RANCell_PR_nR_CellID; + NR_CELL_ID_TO_BIT_STRING(in->choice.ng_ran_cgi.nr_cellid, &(nG_RAN_CGI->nG_RANcell.choice.nR_CellID)); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN: + out.present = NRPPA_TRPInformationItem_PR_aRFCN; + out.choice.aRFCN = in->choice.nr_arfcn; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION: + out.present = NRPPA_TRPInformationItem_PR_pRSConfiguration; + AssertFatal(false, "TRP information type response item PRS configuration unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION: + out.present = NRPPA_TRPInformationItem_PR_sSBinformation; + AssertFatal(false, "TRP information type response item SSB Information unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME: + out.present = NRPPA_TRPInformationItem_PR_sFNInitialisationTime; + AssertFatal(false, "TRP information type response item SFN Initialization Time unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION: + out.present = NRPPA_TRPInformationItem_PR_spatialDirectionInformation; + AssertFatal(false, "TRP information type response item Spatial Direction Information unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES: + out.present = NRPPA_TRPInformationItem_PR_geographicalCoordinates; + asn1cCalloc(out.choice.geographicalCoordinates, nrppa_geo_coord); + nrppa_geographical_coordinates_t *geo_coord = &in->choice.geographical_coordinates; + *nrppa_geo_coord = encode_geographical_coordinates_nrppa(geo_coord); + break; + default: + AssertFatal(false, "received illegal trp information type response item %d\n", in->present); + break; + } + return out; +} + +void free_trp_information_response(nrppa_trp_information_resp_t *msg) +{ + nrppa_trp_information_list_t *trp_information_list = &msg->trp_information_list; + uint32_t trp_info_item_length = trp_information_list->trp_information_item_length; + for (int i = 0; i < trp_info_item_length; i++) { + nrppa_trp_information_t *trp_information_item = &trp_information_list->trp_information_item[i]; + nrppa_trp_information_type_response_list_t *trp_info_type_resp_list = &trp_information_item->trp_information_type_response_list; + free(trp_info_type_resp_list->trp_information_type_response_item); + } + free(msg->trp_information_list.trp_information_item); +} + int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) { LOG_I(NRPPA, "Processing Received TRP Information Request \n"); @@ -93,3 +324,94 @@ int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); return 0; } + +int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_trp_information_resp_t *resp = &NRPPA_TRP_INFORMATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id != 0 && ue_info->amf_ue_ngap_id != 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_trp_information_response(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, "Received TRP Information Response info from RRC with transaction_id = %u\n", ue_info->transaction_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_tRPInformationExchange; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_TRPInformationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_TRPInformationResponse_t *out = &head->value.choice.TRPInformationResponse; + + // IE TRP Information List : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_TRPInformationResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_TRPInformationList; + ie->criticality = NRPPA_Criticality_ignore; + ie->value.present = NRPPA_TRPInformationResponse_IEs__value_PR_TRPInformationList; + + uint32_t trp_info_item_len = resp->trp_information_list.trp_information_item_length; + for (int i = 0; i < trp_info_item_len; i++) { + // TRPInformationItem (M) + asn1cSequenceAdd(ie->value.choice.TRPInformationList.list, TRPInformationList__Member, trpinfolist_member); + nrppa_trp_information_t *nrppa_tRPInformation = &resp->trp_information_list.trp_information_item[i]; + + trpinfolist_member->tRP_ID = nrppa_tRPInformation->trp_id; + + NRPPA_TRPInformation_t *trp_info = &trpinfolist_member->tRPInformation; + + nrppa_trp_information_type_response_list_t *nrppa_tRPInformationTypeResponseList = + &nrppa_tRPInformation->trp_information_type_response_list; + uint8_t trp_info_type_resp_item_len = nrppa_tRPInformationTypeResponseList->trp_information_type_response_item_length; + + for (int j = 0; j < trp_info_type_resp_item_len; j++) { + asn1cSequenceAdd(trp_info->list, NRPPA_TRPInformationItem_t, trp_info_item); + nrppa_trp_information_type_response_item_t *resp_item = + &nrppa_tRPInformationTypeResponseList->trp_information_type_response_item[j]; + *trp_info_item = encode_trp_info_type_response_item_nrppa(resp_item); + } + } + } + + free_trp_information_response(resp); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa TRP Information Response\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKNONUEASSOCIATEDNRPPA); + ngap_uplink_non_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKNONUEASSOCIATEDNRPPA(msg); + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPa PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index 5295505b22..2f9ec72cd0 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -24,5 +24,9 @@ int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); void free_trp_information_request(nrppa_trp_information_req_t *msg); +int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p); +void free_trp_information_request(nrppa_trp_information_req_t *msg); +NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in); +void free_trp_information_response(nrppa_trp_information_resp_t *msg); #endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.c b/openair3/NRPPA/nrppa_gNB_ue_context.c index 1a1a0e7c0e..b5da194205 100644 --- a/openair3/NRPPA/nrppa_gNB_ue_context.c +++ b/openair3/NRPPA/nrppa_gNB_ue_context.c @@ -83,3 +83,14 @@ struct nrppa_gNB_ue_context_s *nrppa_detach_ue_context(uint16_t transaction_id) RB_REMOVE(nrppa_ue_map, &nrppa_ue_head, tmp); return tmp; } + +void nrppa_free_ue_context(nrppa_gNB_ue_context_t *ue_info) +{ + if (!ue_info) + return; + + if (ue_info->routing_id.buf) { + free(ue_info->routing_id.buf); + } + free(ue_info); +} diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.h b/openair3/NRPPA/nrppa_gNB_ue_context.h index 1aaeabe359..fc976c611d 100644 --- a/openair3/NRPPA/nrppa_gNB_ue_context.h +++ b/openair3/NRPPA/nrppa_gNB_ue_context.h @@ -39,5 +39,6 @@ typedef struct nrppa_gNB_ue_context_s { void nrppa_store_ue_context(const nrppa_gnb_ue_info_t *info, const uint16_t transaction_id); nrppa_gNB_ue_context_t *nrppa_get_ue_context(uint16_t transaction_id); nrppa_gNB_ue_context_t *nrppa_detach_ue_context(uint16_t transaction_id); +void nrppa_free_ue_context(nrppa_gNB_ue_context_t *ue_info); #endif /* NRPPA_GNB_UE_CONTEXT_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 8239033926..63bb3fe248 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -35,5 +35,12 @@ #include "NRPPA_ProtocolIE-Single-Container.h" #include "NRPPA_asn_constant.h" #include "NRPPA_TRPInformationRequest.h" +#include "NRPPA_TRPInformationItem.h" +#include "NRPPA_TRPPositionDirect.h" +#include "NRPPA_NG-RANAccessPointPosition.h" +#include "NRPPA_NGRANHighAccuracyAccessPointPosition.h" +#include "NRPPA_TRPPositionReferenced.h" +#include "NRPPA_RelativeGeodeticLocation.h" +#include "NRPPA_RelativeCartesianLocation.h" #endif /* NRPPA_INCLUDE_H_ */ diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index 893ee63e8c..7d3d023f18 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -64,6 +64,111 @@ ngran_node_t get_node_type() configmodule_interface_t *uniqCfg = NULL; +static nrppa_trp_information_resp_t fill_trp_resp(uint8_t transaction_id) +{ + positioning_config_t positioning_config = RCconfig_nr_positioning(); + dump_positioning_config(&positioning_config); + nrppa_trp_information_resp_t resp = {0}; + resp.transaction_id = transaction_id; + + nrppa_trp_information_list_t *list = &resp.trp_information_list; + uint32_t trp_info_item_len = positioning_config.num_trp; + list->trp_information_item_length = trp_info_item_len; + list->trp_information_item = calloc_or_fail(trp_info_item_len, sizeof(*list->trp_information_item)); + + uint8_t resp_item_len = 3; + for (int i = 0; i < trp_info_item_len; i++) { + nrppa_trp_information_t *tRPInformation = &list->trp_information_item[i]; + tRPInformation->trp_id = positioning_config.trps[i].id; + nrppa_trp_information_type_response_list_t *resp_list = &tRPInformation->trp_information_type_response_list; + resp_list->trp_information_type_response_item_length = resp_item_len; + nrppa_trp_information_type_response_item_t *resp_item = calloc_or_fail(resp_item_len, sizeof(*resp_item)); + resp_list->trp_information_type_response_item = resp_item; + + // nrPCI + resp_item[0].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR; + resp_item[0].choice.pci_nr = 123 + i; + + // nG_RAN_CGI + resp_item[1].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI; + resp_item[1].choice.ng_ran_cgi.plmn.mcc = 001; + resp_item[1].choice.ng_ran_cgi.plmn.mnc = 01; + resp_item[1].choice.ng_ran_cgi.plmn.mnc_digit_length = 2; + resp_item[1].choice.ng_ran_cgi.nr_cellid = gnb_id << 8; // HACK: Made to work with lmf + + // geographicalCoordinates + resp_item[2].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES; + nrppa_geographical_coordinates_t *geographicalCoordinates = &resp_item[2].choice.geographical_coordinates; + nrppa_trp_position_definition_type_t *tRPPositionDefinitionType = &geographicalCoordinates->trp_position_definition_type; + // referenced + tRPPositionDefinitionType->present = NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED; + nrppa_trp_position_referenced_t *referenced = &tRPPositionDefinitionType->choice.referenced; + // coordinate ID + referenced->reference_point.present = NRPPA_REFERENCE_POINT_PR_COORDINATEID; + referenced->reference_point.choice.coordinate_id = 2; + nrppa_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type; + // relative cartesian + referencePointType->present = NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN; + nrppa_relative_cartesian_location_t *trp_pos_cart = &referencePointType->choice.trp_position_relative_cartesian; + // 0 = millimeter + trp_pos_cart->xyz_unit = positioning_config.trps[i].unit; + + // random reference cartesian coordinates in millimeter + trp_pos_cart->xvalue = positioning_config.trps[i].x_axis; + trp_pos_cart->yvalue = positioning_config.trps[i].y_axis; + trp_pos_cart->zvalue = positioning_config.trps[i].z_axis; + // testing random values for uncertainity and confidence + trp_pos_cart->location_uncertainty.horizontal_uncertainty = i + 1; + trp_pos_cart->location_uncertainty.horizontal_confidence = i + 2; + trp_pos_cart->location_uncertainty.vertical_uncertainty = i + 3; + trp_pos_cart->location_uncertainty.vertical_confidence = i + 4; + } + return resp; +} + +void *rrc_gnb_task(void *args_p) +{ + MessageDef *msg_p; + MessageDef *msg_p_resp; + instance_t instance; + int result; + + itti_mark_task_ready(TASK_RRC_GNB); + LOG_I(NR_RRC, "Entering main loop of NR_RRC message task\n"); + + while (1) { + // Wait for a message + itti_receive_msg(TASK_RRC_GNB, &msg_p); + const char *msg_name_p = ITTI_MSG_NAME(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); + LOG_D(NR_RRC, + "RRC GNB Task Received %s for instance %ld from task %s\n", + ITTI_MSG_NAME(msg_p), + ITTI_MSG_DESTINATION_INSTANCE(msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p)); + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); + itti_exit_task(); + break; + case NRPPA_TRP_INFORMATION_REQ: + nrppa_trp_information_req_t *trp_req = &NRPPA_TRP_INFORMATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_TRP_INFORMATION_REQ transaction_id %d\n", trp_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_TRP_INFORMATION_RESP); + NRPPA_TRP_INFORMATION_RESP(msg_p_resp) = fill_trp_resp(trp_req->transaction_id); + LOG_I(NR_RRC, "Sending NRPPA_TRP_INFORMATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + break; + default: + LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + msg_p = NULL; + } +} + int main(int argc, char **argv) { // load the config file @@ -87,6 +192,9 @@ int main(int argc, char **argv) rc = itti_create_task(TASK_NRPPA, nrppa_gNB_task, NULL); AssertFatal(rc >= 0, "Create task for NRPPA failed\n"); + rc = itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL); + AssertFatal(rc >= 0, "Create task for RRC failed\n"); + MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); RCconfig_NR_NG(msg_p, 0);