From cbc85dd448d57455b47a906ff9f564e0ebf7a097 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 29 Jan 2026 23:23:52 +0530 Subject: [PATCH] Add Measurement Response NRPPA message encoding procedures --- openair2/COMMON/nrppa_messages_def.h | 1 + openair2/COMMON/nrppa_messages_types.h | 128 +++++++++ openair3/NRPPA/nrppa_gNB.c | 4 + ...ppa_gNB_measurement_information_transfer.c | 269 ++++++++++++++++++ ...ppa_gNB_measurement_information_transfer.h | 3 + openair3/NRPPA/nrppa_includes.h | 5 + tests/nr-cu-nrppa/nr-cu-nrppa.c | 86 ++++++ 7 files changed, 496 insertions(+) diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index a68362b18c..aa40adce44 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -41,3 +41,4 @@ MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_RESP, nrppa_positioning_activation_resp_t, nrppa_positioning_activation_resp) MESSAGE_DEF(NRPPA_MEASUREMENT_REQ, MESSAGE_PRIORITY_MED, nrppa_measurement_req_t, nrppa_measurement_req) +MESSAGE_DEF(NRPPA_MEASUREMENT_RESP, MESSAGE_PRIORITY_MED, nrppa_measurement_resp_t, nrppa_measurement_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index dd42af6354..881362231d 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -31,6 +31,7 @@ #define NRPPA_POSITIONING_ACTIVATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_req #define NRPPA_POSITIONING_ACTIVATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_resp #define NRPPA_MEASUREMENT_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_req +#define NRPPA_MEASUREMENT_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_resp /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -635,6 +636,122 @@ typedef struct nrppa_pos_measurement_quantities_s { uint32_t measurement_quantities_length; } nrppa_measurement_quantities_t; +typedef struct nrppa_lcs_to_gcs_translationaoa_c { + uint16_t alpha; + uint16_t beta; + uint16_t gamma; +} nrppa_lcs_to_gcs_translationaoa_t; + +typedef struct nrppa_ul_aoa_s { + uint16_t azimuth_aoa; + uint16_t *zenith_aoa; + nrppa_lcs_to_gcs_translationaoa_t *lcs_to_gcs_translation_aoa; +} nrppa_ul_aoa_t; + +typedef union nrppa_relative_path_delay_c { + uint32_t k0; + uint32_t k1; + uint32_t k2; + uint32_t k3; + uint32_t k4; + uint32_t k5; +} nrppa_relative_path_delay_u, nrppa_ul_rtoa_measurement_u, nrppa_gnb_rx_tx_time_diff_u; + +typedef enum nrppa_gnb_rx_tx_time_diff_meas_e { + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_NOTHING, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K0, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K1, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K2, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K4, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K5 +} nrppa_gnb_rx_tx_time_diff_pr; + +typedef struct nrppa_gnb_rx_tx_time_diff_s { + nrppa_gnb_rx_tx_time_diff_pr present; + nrppa_gnb_rx_tx_time_diff_u choice; +} nrppa_gnb_rx_tx_time_diff_t; + +typedef enum nrppa_ul_rtoa_measurement_e { + NRPPA_ULRTOAMEAS_PR_NOTHING, + NRPPA_ULRTOAMEAS_PR_K0, + NRPPA_ULRTOAMEAS_PR_K1, + NRPPA_ULRTOAMEAS_PR_K2, + NRPPA_ULRTOAMEAS_PR_K3, + NRPPA_ULRTOAMEAS_PR_K4, + NRPPA_ULRTOAMEAS_PR_K5 +} nrppa_ul_rtoa_measurement_pr; + +typedef struct nrppa_ul_rtoa_measurement_s { + nrppa_ul_rtoa_measurement_pr present; + nrppa_ul_rtoa_measurement_u choice; +} nrppa_ul_rtoa_measurement_t; + +typedef union nrppa_measured_results_value_c { + nrppa_ul_aoa_t ul_angle_of_arrival; + uint8_t ul_srs_rsrp; + nrppa_ul_rtoa_measurement_t ul_rtoa; + nrppa_gnb_rx_tx_time_diff_t gnb_rx_tx_time_diff; +} nrppa_measured_results_value_u; + +typedef enum nrppa_measured_results_value_e { + NRPPA_MEASURED_RESULTS_VALUE_PR_NOTHING, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA, + NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF +} nrppa_measured_results_value_pr; + +typedef struct nrppa_measured_results_value_s { + nrppa_measured_results_value_pr present; + nrppa_measured_results_value_u choice; +} nrppa_measured_results_value_t; + +typedef union nrppa_time_stamp_slot_index_c { + uint8_t scs_15; + uint8_t scs_30; + uint8_t scs_60; + uint8_t scs_120; +} nrppa_time_stamp_slot_index_u; + +typedef enum nrppa_time_stamp_slot_index_e { + NRPPA_TIME_STAMP_SLOT_INDEX_PR_NOTHING, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120 +} nrppa_time_stamp_slot_index_pr; + +typedef struct nrppa_time_stamp_slot_index_s { + nrppa_time_stamp_slot_index_pr present; + nrppa_time_stamp_slot_index_u choice; +} nrppa_time_stamp_slot_index_t; + +typedef struct nrppa_time_stamp_s { + uint16_t system_frame_number; + nrppa_time_stamp_slot_index_t slot_index; +} nrppa_time_stamp_t; + +typedef struct nrppa_measurement_result_item_s { + nrppa_measured_results_value_t measured_results_value; + nrppa_time_stamp_t time_stamp; +} nrppa_measurement_result_item_t; + +typedef struct nrppa_measurement_result_s { + nrppa_measurement_result_item_t *measurement_result_item; + uint32_t measurement_result_item_length; +} nrppa_measurement_result_t; + +typedef struct nrppa_measurement_response_item_s { + nrppa_measurement_result_t measurement_result; + uint32_t trp_id; +} nrppa_measurement_response_item_t; + +typedef struct nrppa_measurement_response_list_s { + nrppa_measurement_response_item_t *measurement_response_item; + uint32_t measurement_response_list_length; +} nrppa_measurement_response_list_t; + typedef struct nrppa_trp_information_req_s { // IE 9.2.4 (mandatory) uint16_t transaction_id; @@ -693,4 +810,15 @@ typedef struct nrppa_measurement_req_s { nrppa_srs_configuration_t *srs_configuration; } nrppa_measurement_req_t; +typedef struct nrppa_measurement_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + uint32_t lmf_measurement_id; + // (mandatory) + uint32_t ran_measurement_id; + // (optional) + nrppa_measurement_response_list_t *measurement_response_list; +} nrppa_measurement_resp_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c index 0da07e018e..a561c026fd 100644 --- a/openair3/NRPPA/nrppa_gNB.c +++ b/openair3/NRPPA/nrppa_gNB.c @@ -31,6 +31,7 @@ #include "nrppa_common.h" #include "nrppa_gNB_handlers.h" #include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_measurement_information_transfer.h" void nrppa_gNB_init(void) { @@ -66,6 +67,9 @@ void *nrppa_gNB_process_itti_msg(void *notUsed) case NRPPA_POSITIONING_ACTIVATION_RESP: nrppa_gNB_positioning_activation_response(instance, received_msg); break; + case NRPPA_MEASUREMENT_RESP: + nrppa_gNB_measurement_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_measurement_information_transfer.c b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c index 02db797d81..afeacae4c7 100644 --- a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c @@ -714,6 +714,180 @@ void free_measurement_request(nrppa_measurement_req_t *msg) } } +static NRPPA_TrpMeasurementResult_t encode_measurement_results(nrppa_measurement_result_t *in_result) +{ + NRPPA_TrpMeasurementResult_t out_result = {0}; + for (int i = 0; i < in_result->measurement_result_item_length; i++) { + asn1cSequenceAdd(out_result.list, NRPPA_TrpMeasurementResultItem_t, out_item); + nrppa_measurement_result_item_t *in_item = &in_result->measurement_result_item[i]; + NRPPA_TrpMeasuredResultsValue_t *out_meas_res_val = &out_item->measuredResultsValue; + nrppa_measured_results_value_t *in_meas_res_val = &in_item->measured_results_value; + switch (in_meas_res_val->present) { + case NRPPA_MEASURED_RESULTS_VALUE_PR_NOTHING: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_NOTHING; + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_AngleOfArrival; + asn1cCalloc(out_meas_res_val->choice.uL_AngleOfArrival, out_ul_aoa); + nrppa_ul_aoa_t *in_ul_aoa = &in_meas_res_val->choice.ul_angle_of_arrival; + out_ul_aoa->azimuthAoA = in_ul_aoa->azimuth_aoa; + if (in_ul_aoa->zenith_aoa) { + asn1cCalloc(out_ul_aoa->zenithAoA, out_z_aoa); + *out_z_aoa = *in_ul_aoa->zenith_aoa; + } + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_SRS_RSRP; + out_meas_res_val->choice.uL_SRS_RSRP = in_meas_res_val->choice.ul_srs_rsrp; + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_RTOA; + asn1cCalloc(out_meas_res_val->choice.uL_RTOA, out_ul_rtoa); + nrppa_ul_rtoa_measurement_t *in_ul_rtoa = &in_meas_res_val->choice.ul_rtoa; + switch (in_ul_rtoa->present) { + case NRPPA_ULRTOAMEAS_PR_NOTHING: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_NOTHING; + break; + case NRPPA_ULRTOAMEAS_PR_K0: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k0; + out_ul_rtoa->uLRTOAmeas.choice.k0 = in_ul_rtoa->choice.k0; + break; + case NRPPA_ULRTOAMEAS_PR_K1: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k1; + out_ul_rtoa->uLRTOAmeas.choice.k1 = in_ul_rtoa->choice.k1; + break; + case NRPPA_ULRTOAMEAS_PR_K2: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k2; + out_ul_rtoa->uLRTOAmeas.choice.k2 = in_ul_rtoa->choice.k2; + break; + case NRPPA_ULRTOAMEAS_PR_K3: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k3; + out_ul_rtoa->uLRTOAmeas.choice.k3 = in_ul_rtoa->choice.k3; + break; + case NRPPA_ULRTOAMEAS_PR_K4: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k4; + out_ul_rtoa->uLRTOAmeas.choice.k4 = in_ul_rtoa->choice.k4; + break; + case NRPPA_ULRTOAMEAS_PR_K5: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k5; + out_ul_rtoa->uLRTOAmeas.choice.k5 = in_ul_rtoa->choice.k5; + break; + default: + AssertFatal(false, "illegal ul rtoa measure type\n"); + break; + } + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_gNB_RxTxTimeDiff; + asn1cCalloc(out_meas_res_val->choice.gNB_RxTxTimeDiff, out_rxtx_time_diff); + nrppa_gnb_rx_tx_time_diff_t *in_rxtx_time_diff = &in_meas_res_val->choice.gnb_rx_tx_time_diff; + switch (in_rxtx_time_diff->present) { + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_NOTHING: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_NOTHING; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K0: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k0; + out_rxtx_time_diff->rxTxTimeDiff.choice.k0 = in_rxtx_time_diff->choice.k0; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K1: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k1; + out_rxtx_time_diff->rxTxTimeDiff.choice.k1 = in_rxtx_time_diff->choice.k1; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K2: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k2; + out_rxtx_time_diff->rxTxTimeDiff.choice.k2 = in_rxtx_time_diff->choice.k2; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k3; + out_rxtx_time_diff->rxTxTimeDiff.choice.k3 = in_rxtx_time_diff->choice.k3; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K4: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k4; + out_rxtx_time_diff->rxTxTimeDiff.choice.k4 = in_rxtx_time_diff->choice.k4; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K5: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k5; + out_rxtx_time_diff->rxTxTimeDiff.choice.k5 = in_rxtx_time_diff->choice.k5; + break; + default: + AssertFatal(false, "illegal ul rtoa measure type\n"); + break; + } + break; + default: + AssertFatal(false, "illegal measured results type\n"); + break; + } + + NRPPA_TimeStamp_t *out_time_stamp = &out_item->timeStamp; + nrppa_time_stamp_t *in_time_stamp = &in_item->time_stamp; + out_time_stamp->systemFrameNumber = in_time_stamp->system_frame_number; + switch (in_time_stamp->slot_index.present) { + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_NOTHING: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_NOTHING; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_15; + out_time_stamp->slotIndex.choice.sCS_15 = in_time_stamp->slot_index.choice.scs_15; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_30; + out_time_stamp->slotIndex.choice.sCS_30 = in_time_stamp->slot_index.choice.scs_30; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_60; + out_time_stamp->slotIndex.choice.sCS_60 = in_time_stamp->slot_index.choice.scs_60; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_120; + out_time_stamp->slotIndex.choice.sCS_120 = in_time_stamp->slot_index.choice.scs_120; + break; + default: + AssertFatal(false, "illegal slot index\n"); + break; + } + } + return out_result; +} + +NRPPA_TRP_MeasurementResponseList_t encode_trp_measurement_reponse_list(nrppa_measurement_response_list_t *in_list) +{ + NRPPA_TRP_MeasurementResponseList_t out_list = {0}; + for (int i = 0; i < in_list->measurement_response_list_length; i++) { + asn1cSequenceAdd(out_list.list, NRPPA_TRP_MeasurementResponseItem_t, out_item); + nrppa_measurement_response_item_t *in_item = &in_list->measurement_response_item[i]; + out_item->tRP_ID = in_item->trp_id; + out_item->measurementResult = encode_measurement_results(&in_item->measurement_result); + } + + return out_list; +} + +void free_measurement_resp(nrppa_measurement_resp_t *msg) +{ + if (msg->measurement_response_list) { + nrppa_measurement_response_list_t *list = msg->measurement_response_list; + uint32_t meas_resp_list_len = list->measurement_response_list_length; + for (int i = 0; i < meas_resp_list_len; i++) { + nrppa_measurement_response_item_t *meas_response_item = &list->measurement_response_item[i]; + nrppa_measurement_result_t *MeasurementResult = &meas_response_item->measurement_result; + uint32_t meas_result_length = MeasurementResult->measurement_result_item_length; + for (int j = 0; j < meas_result_length; j++) { + nrppa_measurement_result_item_t *item = &MeasurementResult->measurement_result_item[j]; + nrppa_measured_results_value_t *measuredResultsValue = &item->measured_results_value; + if (measuredResultsValue->present == NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL) { + if (measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa) { + free(measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa); + } + } + } + free(MeasurementResult->measurement_result_item); + } + free(msg->measurement_response_list->measurement_response_item); + free(msg->measurement_response_list); + } +} + int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) { DevAssert(pdu != NULL); @@ -872,3 +1046,98 @@ int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, co ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); return 0; } + +int nrppa_gNB_measurement_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_measurement_resp_t *resp = &NRPPA_MEASUREMENT_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_measurement_resp(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received measurement response info from RRC with transaction_id %u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_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_Measurement; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_MeasurementResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_MeasurementResponse_t *out = &head->value.choice.MeasurementResponse; + + // IE LMF Measurement ID : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_LMF_Measurement_ID; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_Measurement_ID; + ie->value.choice.Measurement_ID = resp->lmf_measurement_id; + } + + // IE RAN Measurement ID : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_RAN_Measurement_ID; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_Measurement_ID_1; + ie->value.choice.Measurement_ID_1 = resp->ran_measurement_id; + } + + // IE TRP Measurement Response List : mandatory + { + if (resp->measurement_response_list) { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_TRP_MeasurementResponseList; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_TRP_MeasurementResponseList; + ie->value.choice.TRP_MeasurementResponseList = encode_trp_measurement_reponse_list(resp->measurement_response_list); + } + } + + free_measurement_resp(resp); + + LOG_I(NRPPA, "Calling encoder for Measurement Response \n"); + + 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 Measurement Response\n"); + nrppa_free_ue_context(ue_info); + 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_measurement_information_transfer.h b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h index f154fc1ce8..da03403f4d 100644 --- a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h @@ -25,5 +25,8 @@ int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); void decode_srs_carrier_list(nrppa_srs_carrier_list_t *out_list, const NRPPA_SRSCarrier_List_t *in_list); void free_measurement_request(nrppa_measurement_req_t *msg); +int nrppa_gNB_measurement_response(instance_t instance, MessageDef *msg_p); +NRPPA_TRP_MeasurementResponseList_t encode_trp_measurement_reponse_list(nrppa_measurement_response_list_t *in_list); +void free_measurement_resp(nrppa_measurement_resp_t *msg); #endif /* NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 64c642587c..98e447d379 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -74,5 +74,10 @@ #include "NRPPA_TRP-MeasurementRequestItem.h" #include "NRPPA_TRPMeasurementQuantities-Item.h" #include "NRPPA_TRPMeasurementQuantitiesList-Item.h" +#include "NRPPA_TRP-MeasurementResponseList.h" +#include "NRPPA_TRP-MeasurementResponseItem.h" +#include "NRPPA_TrpMeasurementResultItem.h" +#include "NRPPA_UL-RTOAMeasurement.h" +#include "NRPPA_GNB-RxTxTimeDiff.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 0edd0842f4..de784a3a16 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -32,6 +32,7 @@ #include "openair3/NAS/NR_UE/nr_nas_msg.h" #include "executables/nr-uesoftmodem.h" #include "openair3/NRPPA/nrppa_gNB_location_information_transfer.c" +#include "openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h" RAN_CONTEXT_t RC; THREAD_STRUCT thread_struct; @@ -432,6 +433,82 @@ static nrppa_positioning_information_resp_t fill_position_information_resp(uint1 return resp; } +static nrppa_measurement_resp_t fill_measurement_response(uint16_t transaction_id, uint32_t lmf_measurement_id) +{ + positioning_config_t positioning_config = RCconfig_nr_positioning(); + nrppa_measurement_resp_t resp = {0}; + resp.transaction_id = transaction_id; + resp.lmf_measurement_id = lmf_measurement_id; + resp.ran_measurement_id = 1; + resp.measurement_response_list = calloc_or_fail(1, sizeof(*resp.measurement_response_list)); + uint32_t meas_response_list_len = positioning_config.num_trp; + resp.measurement_response_list->measurement_response_list_length = meas_response_list_len; + resp.measurement_response_list->measurement_response_item = + calloc_or_fail(meas_response_list_len, sizeof(*resp.measurement_response_list->measurement_response_item)); + for (int i = 0; i < meas_response_list_len; i++) { + nrppa_measurement_response_item_t *meas_response_item = &resp.measurement_response_list->measurement_response_item[i]; + meas_response_item->trp_id = positioning_config.trps[i].id; + + nrppa_measurement_result_t *MeasurementResult = &meas_response_item->measurement_result; + uint32_t meas_result_length = 4; + MeasurementResult->measurement_result_item_length = meas_result_length; + MeasurementResult->measurement_result_item = + calloc_or_fail(meas_result_length, sizeof(*MeasurementResult->measurement_result_item)); + + // Angle of arrival + nrppa_measurement_result_item_t *measurement_result_item = &MeasurementResult->measurement_result_item[0]; + nrppa_measured_results_value_t *measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL; + nrppa_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival; + uL_AngleOfArrival->azimuth_aoa = 700 + i; + uL_AngleOfArrival->zenith_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->zenith_aoa)); + *uL_AngleOfArrival->zenith_aoa = 450 + i; + + nrppa_time_stamp_t *timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 100; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30; + timeStamp->slot_index.choice.scs_30 = 15; + + // UL SRS RSRP + measurement_result_item = &MeasurementResult->measurement_result_item[1]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP; + measuredResultsValue->choice.ul_srs_rsrp = 100 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 101; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15; + timeStamp->slot_index.choice.scs_15 = 8; + + // UL RToA + measurement_result_item = &MeasurementResult->measurement_result_item[2]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA; + nrppa_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa; + uL_RTOA->present = NRPPA_ULRTOAMEAS_PR_K1; + uL_RTOA->choice.k1 = 98500 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 102; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60; + timeStamp->slot_index.choice.scs_60 = 31; + + // gNB RX-TX Time Diff + measurement_result_item = &MeasurementResult->measurement_result_item[3]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF; + nrppa_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff; + gNB_RxTxTimeDiff->present = NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3; + gNB_RxTxTimeDiff->choice.k3 = 98412 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 103; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120; + timeStamp->slot_index.choice.scs_120 = 70; + } + return resp; +} + // Initializing UE NAS Context with simulated SIM data nr_ue_nas_t *simulated_ue_nas = NULL; void init_ue_nas_context(void) @@ -589,6 +666,15 @@ void *rrc_gnb_task(void *args_p) itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); free_positioning_activation_request(req); break; + case NRPPA_MEASUREMENT_REQ: + nrppa_measurement_req_t *m_req = &NRPPA_MEASUREMENT_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_MEASUREMENT_REQ transaction_id %d\n", m_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_MEASUREMENT_RESP); + NRPPA_MEASUREMENT_RESP(msg_p_resp) = fill_measurement_response(m_req->transaction_id, m_req->lmf_measurement_id); + LOG_I(NR_RRC, "Sending NRPPA_MEASUREMENT_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + free_measurement_request(m_req); + break; default: LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break;