Add F1AP positioning measurement response message enc/dec + test
Reference: 3GPP 38.473 v16.21.0 Mandatory fields: Transcation ID (supported) LMF Measurement ID (supported) RAN Measurement ID (supported) Positioning Measurement Result List (range: 0..1) > Positioning Measurement Result List Item (range: 1..64) >> Positioning Measurement Result (supported) >> TRP ID (supported) Optional fields: Criticality Diagnostics (not supported)
This commit is contained in:
@@ -1295,6 +1295,130 @@ typedef enum f1ap_pos_report_characteristics_e {
|
|||||||
F1AP_POSREPORTCHARACTERISTICS_PERIODIC = 1
|
F1AP_POSREPORTCHARACTERISTICS_PERIODIC = 1
|
||||||
} f1ap_pos_report_characteristics_pr;
|
} f1ap_pos_report_characteristics_pr;
|
||||||
|
|
||||||
|
typedef struct f1ap_lcs_to_gcs_translationaoa_c {
|
||||||
|
uint16_t alpha;
|
||||||
|
uint16_t beta;
|
||||||
|
uint16_t gamma;
|
||||||
|
} f1ap_lcs_to_gcs_translationaoa_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_ul_aoa_s {
|
||||||
|
uint16_t azimuth_aoa;
|
||||||
|
uint16_t *zenith_aoa;
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *lcs_to_gcs_translation_aoa;
|
||||||
|
} f1ap_ul_aoa_t;
|
||||||
|
|
||||||
|
typedef union f1ap_relative_path_delay_c {
|
||||||
|
uint32_t k0;
|
||||||
|
uint32_t k1;
|
||||||
|
uint32_t k2;
|
||||||
|
uint32_t k3;
|
||||||
|
uint32_t k4;
|
||||||
|
uint32_t k5;
|
||||||
|
} f1ap_relative_path_delay_u, f1ap_ul_rtoa_measurement_item_u, f1ap_gnb_rx_tx_time_diff_meas_u;
|
||||||
|
|
||||||
|
typedef enum f1ap_gnb_rx_tx_time_diff_meas_e {
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_NOTHING,
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_K0,
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_K1,
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_K2,
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_K3,
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_K4,
|
||||||
|
F1AP_GNBRXTXTIMEDIFFMEAS_PR_K5
|
||||||
|
} f1ap_gnb_rx_tx_time_diff_meas_pr;
|
||||||
|
|
||||||
|
typedef struct f1ap_gnb_rx_tx_time_diff_meas_s {
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_pr present;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_u choice;
|
||||||
|
} f1ap_gnb_rx_tx_time_diff_meas_t;
|
||||||
|
|
||||||
|
typedef enum f1ap_ul_rtoa_measurement_item_e {
|
||||||
|
F1AP_ULRTOAMEAS_PR_NOTHING,
|
||||||
|
F1AP_ULRTOAMEAS_PR_K0,
|
||||||
|
F1AP_ULRTOAMEAS_PR_K1,
|
||||||
|
F1AP_ULRTOAMEAS_PR_K2,
|
||||||
|
F1AP_ULRTOAMEAS_PR_K3,
|
||||||
|
F1AP_ULRTOAMEAS_PR_K4,
|
||||||
|
F1AP_ULRTOAMEAS_PR_K5
|
||||||
|
} f1ap_ul_rtoa_measurement_item_pr;
|
||||||
|
|
||||||
|
typedef struct f1ap_ul_rtoa_measurement_item_s {
|
||||||
|
f1ap_ul_rtoa_measurement_item_pr present;
|
||||||
|
f1ap_ul_rtoa_measurement_item_u choice;
|
||||||
|
} f1ap_ul_rtoa_measurement_item_t;
|
||||||
|
|
||||||
|
typedef union f1ap_ul_rtoa_measurement_s {
|
||||||
|
f1ap_ul_rtoa_measurement_item_t ul_rtoa_measurement_item;
|
||||||
|
} f1ap_ul_rtoa_measurement_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_gnb_rx_tx_time_diff_s {
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t rx_tx_time_diff;
|
||||||
|
} f1ap_gnb_rx_tx_time_diff_t;
|
||||||
|
|
||||||
|
typedef union f1ap_measured_results_value_c {
|
||||||
|
f1ap_ul_aoa_t ul_angle_of_arrival;
|
||||||
|
uint8_t ul_srs_rsrp;
|
||||||
|
f1ap_ul_rtoa_measurement_t ul_rtoa;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t gnb_rx_tx_time_diff;
|
||||||
|
} f1ap_measured_results_value_u;
|
||||||
|
|
||||||
|
typedef enum f1ap_measured_results_value_e {
|
||||||
|
F1AP_MEASURED_RESULTS_VALUE_PR_NOTHING,
|
||||||
|
F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL,
|
||||||
|
F1AP_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP,
|
||||||
|
F1AP_MEASURED_RESULTS_VALUE_PR_UL_RTOA,
|
||||||
|
F1AP_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF
|
||||||
|
} f1ap_measured_results_value_pr;
|
||||||
|
|
||||||
|
typedef struct f1ap_measured_results_value_s {
|
||||||
|
f1ap_measured_results_value_pr present;
|
||||||
|
f1ap_measured_results_value_u choice;
|
||||||
|
} f1ap_measured_results_value_t;
|
||||||
|
|
||||||
|
typedef union f1ap_time_stamp_slot_index_c {
|
||||||
|
uint8_t scs_15;
|
||||||
|
uint8_t scs_30;
|
||||||
|
uint8_t scs_60;
|
||||||
|
uint8_t scs_120;
|
||||||
|
} f1ap_time_stamp_slot_index_u;
|
||||||
|
|
||||||
|
typedef enum f1ap_time_stamp_slot_index_e {
|
||||||
|
F1AP_TIME_STAMP_SLOT_INDEX_PR_NOTHING,
|
||||||
|
F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_15,
|
||||||
|
F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_30,
|
||||||
|
F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_60,
|
||||||
|
F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_120
|
||||||
|
} f1ap_time_stamp_slot_index_pr;
|
||||||
|
|
||||||
|
typedef struct f1ap_time_stamp_slot_index_s {
|
||||||
|
f1ap_time_stamp_slot_index_pr present;
|
||||||
|
f1ap_time_stamp_slot_index_u choice;
|
||||||
|
} f1ap_time_stamp_slot_index_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_time_stamp_s {
|
||||||
|
uint16_t system_frame_number;
|
||||||
|
f1ap_time_stamp_slot_index_t slot_index;
|
||||||
|
} f1ap_time_stamp_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_pos_measurement_result_item_s {
|
||||||
|
f1ap_measured_results_value_t measured_results_value;
|
||||||
|
f1ap_time_stamp_t time_stamp;
|
||||||
|
} f1ap_pos_measurement_result_item_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_pos_measurement_result_s {
|
||||||
|
f1ap_pos_measurement_result_item_t *pos_measurement_result_item;
|
||||||
|
uint32_t pos_measurement_result_item_length;
|
||||||
|
} f1ap_pos_measurement_result_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_pos_measurement_result_list_item_s {
|
||||||
|
f1ap_pos_measurement_result_t pos_measurement_result;
|
||||||
|
uint32_t trp_id;
|
||||||
|
} f1ap_pos_measurement_result_list_item_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_pos_measurement_result_list_s {
|
||||||
|
f1ap_pos_measurement_result_list_item_t *pos_measurement_result_list_item;
|
||||||
|
uint32_t pos_measurement_result_list_length;
|
||||||
|
} f1ap_pos_measurement_result_list_t;
|
||||||
|
|
||||||
typedef struct f1ap_positioning_information_req_s {
|
typedef struct f1ap_positioning_information_req_s {
|
||||||
// IE 9.3.1.4 (mandatory)
|
// IE 9.3.1.4 (mandatory)
|
||||||
uint32_t gNB_CU_ue_id;
|
uint32_t gNB_CU_ue_id;
|
||||||
@@ -1412,4 +1536,15 @@ typedef struct f1ap_measurement_req_s {
|
|||||||
f1ap_srs_configuration_t *srs_configuration;
|
f1ap_srs_configuration_t *srs_configuration;
|
||||||
} f1ap_positioning_measurement_req_t;
|
} f1ap_positioning_measurement_req_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_positioning_measurement_resp_s {
|
||||||
|
// IE 9.3.1.23 (mandatory)
|
||||||
|
uint8_t transaction_id;
|
||||||
|
// (mandatory)
|
||||||
|
uint16_t lmf_measurement_id;
|
||||||
|
// (mandatory)
|
||||||
|
uint16_t ran_measurement_id;
|
||||||
|
// (mandatory)
|
||||||
|
f1ap_pos_measurement_result_list_t *pos_measurement_result_list;
|
||||||
|
} f1ap_positioning_measurement_resp_t;
|
||||||
|
|
||||||
#endif /* F1AP_MESSAGES_TYPES_H_ */
|
#endif /* F1AP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -84,5 +84,11 @@
|
|||||||
#include "F1AP_RelativeCartesianLocation.h"
|
#include "F1AP_RelativeCartesianLocation.h"
|
||||||
#include "F1AP_TRP-MeasurementRequestItem.h"
|
#include "F1AP_TRP-MeasurementRequestItem.h"
|
||||||
#include "F1AP_PosMeasurementQuantities-Item.h"
|
#include "F1AP_PosMeasurementQuantities-Item.h"
|
||||||
|
#include "F1AP_PosMeasurementResultList-Item.h"
|
||||||
|
#include "F1AP_PosMeasurementResultItem.h"
|
||||||
|
#include "F1AP_UL-AoA.h"
|
||||||
|
#include "F1AP_UL-RTOA-Measurement.h"
|
||||||
|
#include "F1AP_GNB-RxTxTimeDiff.h"
|
||||||
|
#include "F1AP_LCS-to-GCS-TranslationAoA.h"
|
||||||
|
|
||||||
#endif /* F1AP_LIB_INCLUDES_H_ */
|
#endif /* F1AP_LIB_INCLUDES_H_ */
|
||||||
|
|||||||
@@ -2840,6 +2840,628 @@ static bool eq_trp_info_type_response_item(const f1ap_trp_information_type_respo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static F1AP_PosMeasurementResult_t encode_positioning_measurement_result(const f1ap_pos_measurement_result_t *posMeasurementResult)
|
||||||
|
{
|
||||||
|
F1AP_PosMeasurementResult_t f1_posMeasurementResult = {0};
|
||||||
|
for (int i = 0; i < posMeasurementResult->pos_measurement_result_item_length; i++) {
|
||||||
|
asn1cSequenceAdd(f1_posMeasurementResult.list, F1AP_PosMeasurementResultItem_t, f1_pos_measurement_result_item);
|
||||||
|
f1ap_pos_measurement_result_item_t *pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[i];
|
||||||
|
|
||||||
|
// measuredResultsValue
|
||||||
|
F1AP_MeasuredResultsValue_t *f1_measuredResultsValue = &f1_pos_measurement_result_item->measuredResultsValue;
|
||||||
|
f1ap_measured_results_value_t *measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
|
||||||
|
switch (measuredResultsValue->present) {
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_NOTHING:
|
||||||
|
f1_measuredResultsValue->present = F1AP_MeasuredResultsValue_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
// Angle of Arrival
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL:
|
||||||
|
f1_measuredResultsValue->present = F1AP_MeasuredResultsValue_PR_uL_AngleOfArrival;
|
||||||
|
asn1cCalloc(f1_measuredResultsValue->choice.uL_AngleOfArrival, f1_uL_AngleOfArrival);
|
||||||
|
f1ap_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival;
|
||||||
|
f1_uL_AngleOfArrival->azimuthAoA = uL_AngleOfArrival->azimuth_aoa;
|
||||||
|
if (uL_AngleOfArrival->zenith_aoa) {
|
||||||
|
asn1cCalloc(f1_uL_AngleOfArrival->zenithAoA, f1_zenithAoA);
|
||||||
|
*f1_zenithAoA = *uL_AngleOfArrival->zenith_aoa;
|
||||||
|
}
|
||||||
|
if (uL_AngleOfArrival->lcs_to_gcs_translation_aoa) {
|
||||||
|
asn1cCalloc(f1_uL_AngleOfArrival->lCS_to_GCS_TranslationAoA, f1_lCS_to_GCS_TranslationAoA);
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *lCS_to_GCS_TranslationAoA = uL_AngleOfArrival->lcs_to_gcs_translation_aoa;
|
||||||
|
|
||||||
|
f1_lCS_to_GCS_TranslationAoA->alpha = lCS_to_GCS_TranslationAoA->alpha;
|
||||||
|
f1_lCS_to_GCS_TranslationAoA->beta = lCS_to_GCS_TranslationAoA->beta;
|
||||||
|
f1_lCS_to_GCS_TranslationAoA->gamma = lCS_to_GCS_TranslationAoA->gamma;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// UL SRS RSRP
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP:
|
||||||
|
f1_measuredResultsValue->present = F1AP_MeasuredResultsValue_PR_uL_SRS_RSRP;
|
||||||
|
f1_measuredResultsValue->choice.uL_SRS_RSRP = measuredResultsValue->choice.ul_srs_rsrp;
|
||||||
|
break;
|
||||||
|
// UL RTOA
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_RTOA:
|
||||||
|
f1_measuredResultsValue->present = F1AP_MeasuredResultsValue_PR_uL_RTOA;
|
||||||
|
asn1cCalloc(f1_measuredResultsValue->choice.uL_RTOA, f1_uL_RTOA);
|
||||||
|
f1ap_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa;
|
||||||
|
f1ap_ul_rtoa_measurement_item_t *ul_rtoa_meas_item = &uL_RTOA->ul_rtoa_measurement_item;
|
||||||
|
F1AP_UL_RTOA_MeasurementItem_t *f1_ul_rtoa_meas_item = &f1_uL_RTOA->uL_RTOA_MeasurementItem;
|
||||||
|
|
||||||
|
switch (ul_rtoa_meas_item->present) {
|
||||||
|
case F1AP_ULRTOAMEAS_PR_NOTHING:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K0:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_k0;
|
||||||
|
f1_ul_rtoa_meas_item->choice.k0 = ul_rtoa_meas_item->choice.k0;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K1:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_k1;
|
||||||
|
f1_ul_rtoa_meas_item->choice.k1 = ul_rtoa_meas_item->choice.k1;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K2:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_k2;
|
||||||
|
f1_ul_rtoa_meas_item->choice.k2 = ul_rtoa_meas_item->choice.k2;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K3:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_k3;
|
||||||
|
f1_ul_rtoa_meas_item->choice.k3 = ul_rtoa_meas_item->choice.k3;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K4:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_k4;
|
||||||
|
f1_ul_rtoa_meas_item->choice.k4 = ul_rtoa_meas_item->choice.k4;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K5:
|
||||||
|
f1_ul_rtoa_meas_item->present = F1AP_UL_RTOA_MeasurementItem_PR_k5;
|
||||||
|
f1_ul_rtoa_meas_item->choice.k5 = ul_rtoa_meas_item->choice.k5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal uL_RTOA_MeasurementItem %d\n", ul_rtoa_meas_item->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// gNB RX-TX Time Diff
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF:
|
||||||
|
f1_measuredResultsValue->present = F1AP_MeasuredResultsValue_PR_gNB_RxTxTimeDiff;
|
||||||
|
asn1cCalloc(f1_measuredResultsValue->choice.gNB_RxTxTimeDiff, f1_gNB_RxTxTimeDiff);
|
||||||
|
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t *rx_tx_time_diff = &gNB_RxTxTimeDiff->rx_tx_time_diff;
|
||||||
|
F1AP_GNBRxTxTimeDiffMeas_t *f1_rxTxTimeDiff = &f1_gNB_RxTxTimeDiff->rxTxTimeDiff;
|
||||||
|
|
||||||
|
switch (rx_tx_time_diff->present) {
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_NOTHING:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K0:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_k0;
|
||||||
|
f1_rxTxTimeDiff->choice.k0 = rx_tx_time_diff->choice.k0;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K1:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_k1;
|
||||||
|
f1_rxTxTimeDiff->choice.k1 = rx_tx_time_diff->choice.k1;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K2:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_k2;
|
||||||
|
f1_rxTxTimeDiff->choice.k2 = rx_tx_time_diff->choice.k2;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K3:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_k3;
|
||||||
|
f1_rxTxTimeDiff->choice.k3 = rx_tx_time_diff->choice.k3;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K4:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_k4;
|
||||||
|
f1_rxTxTimeDiff->choice.k4 = rx_tx_time_diff->choice.k4;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K5:
|
||||||
|
f1_rxTxTimeDiff->present = F1AP_GNBRxTxTimeDiffMeas_PR_k5;
|
||||||
|
f1_rxTxTimeDiff->choice.k5 = rx_tx_time_diff->choice.k5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal rxTxTimeDiff value %d\n", rx_tx_time_diff->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal measuredResultsValue %d\n", measuredResultsValue->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeStamp
|
||||||
|
F1AP_TimeStamp_t *f1_timeStamp = &f1_pos_measurement_result_item->timeStamp;
|
||||||
|
f1ap_time_stamp_t *timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
f1_timeStamp->systemFrameNumber = timeStamp->system_frame_number;
|
||||||
|
F1AP_TimeStampSlotIndex_t *f1_slotIndex = &f1_timeStamp->slotIndex;
|
||||||
|
f1ap_time_stamp_slot_index_t *slot_index = &timeStamp->slot_index;
|
||||||
|
switch (slot_index->present) {
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_NOTHING:
|
||||||
|
f1_slotIndex->present = F1AP_TimeStampSlotIndex_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_15:
|
||||||
|
f1_slotIndex->present = F1AP_TimeStampSlotIndex_PR_sCS_15;
|
||||||
|
f1_slotIndex->choice.sCS_15 = slot_index->choice.scs_15;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_30:
|
||||||
|
f1_slotIndex->present = F1AP_TimeStampSlotIndex_PR_sCS_30;
|
||||||
|
f1_slotIndex->choice.sCS_30 = slot_index->choice.scs_30;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_60:
|
||||||
|
f1_slotIndex->present = F1AP_TimeStampSlotIndex_PR_sCS_60;
|
||||||
|
f1_slotIndex->choice.sCS_60 = slot_index->choice.scs_60;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_120:
|
||||||
|
f1_slotIndex->present = F1AP_TimeStampSlotIndex_PR_sCS_120;
|
||||||
|
f1_slotIndex->choice.sCS_120 = slot_index->choice.scs_120;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal slotIndex value %d\n", slot_index->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return f1_posMeasurementResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool decode_positioning_measurement_result(F1AP_PosMeasurementResult_t *f1_posMeasurementResult,
|
||||||
|
f1ap_pos_measurement_result_t *posMeasurementResult)
|
||||||
|
{
|
||||||
|
uint32_t pos_meas_result_length = f1_posMeasurementResult->list.count;
|
||||||
|
posMeasurementResult->pos_measurement_result_item_length = pos_meas_result_length;
|
||||||
|
posMeasurementResult->pos_measurement_result_item =
|
||||||
|
calloc_or_fail(pos_meas_result_length, sizeof(*posMeasurementResult->pos_measurement_result_item));
|
||||||
|
for (int i = 0; i < pos_meas_result_length; i++) {
|
||||||
|
F1AP_PosMeasurementResultItem_t *f1_pos_measurement_result_item = f1_posMeasurementResult->list.array[i];
|
||||||
|
f1ap_pos_measurement_result_item_t *pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[i];
|
||||||
|
|
||||||
|
// measuredResultsValue
|
||||||
|
F1AP_MeasuredResultsValue_t *f1_measuredResultsValue = &f1_pos_measurement_result_item->measuredResultsValue;
|
||||||
|
f1ap_measured_results_value_t *measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
|
||||||
|
switch (f1_measuredResultsValue->present) {
|
||||||
|
case F1AP_MeasuredResultsValue_PR_NOTHING:
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
// Angle of Arrival
|
||||||
|
case F1AP_MeasuredResultsValue_PR_uL_AngleOfArrival:
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL;
|
||||||
|
|
||||||
|
F1AP_UL_AoA_t *f1_uL_AngleOfArrival = f1_measuredResultsValue->choice.uL_AngleOfArrival;
|
||||||
|
f1ap_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival;
|
||||||
|
|
||||||
|
uL_AngleOfArrival->azimuth_aoa = f1_uL_AngleOfArrival->azimuthAoA;
|
||||||
|
if (f1_uL_AngleOfArrival->zenithAoA) {
|
||||||
|
uL_AngleOfArrival->zenith_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->zenith_aoa));
|
||||||
|
*uL_AngleOfArrival->zenith_aoa = *f1_uL_AngleOfArrival->zenithAoA;
|
||||||
|
}
|
||||||
|
if (f1_uL_AngleOfArrival->lCS_to_GCS_TranslationAoA) {
|
||||||
|
uL_AngleOfArrival->lcs_to_gcs_translation_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->lcs_to_gcs_translation_aoa));
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *lCS_to_GCS_TranslationAoA = uL_AngleOfArrival->lcs_to_gcs_translation_aoa;
|
||||||
|
F1AP_LCS_to_GCS_TranslationAoA_t *f1_lCS_to_GCS_TranslationAoA = f1_uL_AngleOfArrival->lCS_to_GCS_TranslationAoA;
|
||||||
|
|
||||||
|
lCS_to_GCS_TranslationAoA->alpha = f1_lCS_to_GCS_TranslationAoA->alpha;
|
||||||
|
lCS_to_GCS_TranslationAoA->beta = f1_lCS_to_GCS_TranslationAoA->beta;
|
||||||
|
lCS_to_GCS_TranslationAoA->gamma = f1_lCS_to_GCS_TranslationAoA->gamma;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// UL SRS RSRP
|
||||||
|
case F1AP_MeasuredResultsValue_PR_uL_SRS_RSRP:
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP;
|
||||||
|
measuredResultsValue->choice.ul_srs_rsrp = f1_measuredResultsValue->choice.uL_SRS_RSRP;
|
||||||
|
break;
|
||||||
|
// UL RTOA
|
||||||
|
case F1AP_MeasuredResultsValue_PR_uL_RTOA:
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_UL_RTOA;
|
||||||
|
F1AP_UL_RTOA_Measurement_t *f1_uL_RTOA = f1_measuredResultsValue->choice.uL_RTOA;
|
||||||
|
f1ap_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa;
|
||||||
|
F1AP_UL_RTOA_MeasurementItem_t *f1_ul_rtoa_meas_item = &f1_uL_RTOA->uL_RTOA_MeasurementItem;
|
||||||
|
f1ap_ul_rtoa_measurement_item_t *ul_rtoa_meas_item = &uL_RTOA->ul_rtoa_measurement_item;
|
||||||
|
|
||||||
|
switch (f1_ul_rtoa_meas_item->present) {
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_NOTHING:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_k0:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_K0;
|
||||||
|
ul_rtoa_meas_item->choice.k0 = f1_ul_rtoa_meas_item->choice.k0;
|
||||||
|
break;
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_k1:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_K1;
|
||||||
|
ul_rtoa_meas_item->choice.k1 = f1_ul_rtoa_meas_item->choice.k1;
|
||||||
|
break;
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_k2:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_K2;
|
||||||
|
ul_rtoa_meas_item->choice.k2 = f1_ul_rtoa_meas_item->choice.k2;
|
||||||
|
break;
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_k3:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_K3;
|
||||||
|
ul_rtoa_meas_item->choice.k3 = f1_ul_rtoa_meas_item->choice.k3;
|
||||||
|
break;
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_k4:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_K4;
|
||||||
|
ul_rtoa_meas_item->choice.k4 = f1_ul_rtoa_meas_item->choice.k4;
|
||||||
|
break;
|
||||||
|
case F1AP_UL_RTOA_MeasurementItem_PR_k5:
|
||||||
|
ul_rtoa_meas_item->present = F1AP_ULRTOAMEAS_PR_K5;
|
||||||
|
ul_rtoa_meas_item->choice.k5 = f1_ul_rtoa_meas_item->choice.k5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal uL_RTOA_MeasurementItem %d\n", f1_ul_rtoa_meas_item->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// gNB RX-TX Time Diff
|
||||||
|
case F1AP_MeasuredResultsValue_PR_gNB_RxTxTimeDiff:
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF;
|
||||||
|
F1AP_GNB_RxTxTimeDiff_t *f1_gNB_RxTxTimeDiff = f1_measuredResultsValue->choice.gNB_RxTxTimeDiff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
F1AP_GNBRxTxTimeDiffMeas_t *f1_rxTxTimeDiff = &f1_gNB_RxTxTimeDiff->rxTxTimeDiff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t *rx_tx_time_diff = &gNB_RxTxTimeDiff->rx_tx_time_diff;
|
||||||
|
|
||||||
|
switch (f1_rxTxTimeDiff->present) {
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_NOTHING:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_k0:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K0;
|
||||||
|
rx_tx_time_diff->choice.k0 = f1_rxTxTimeDiff->choice.k0;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_k1:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K1;
|
||||||
|
rx_tx_time_diff->choice.k1 = f1_rxTxTimeDiff->choice.k1;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_k2:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K2;
|
||||||
|
rx_tx_time_diff->choice.k2 = f1_rxTxTimeDiff->choice.k2;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_k3:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K3;
|
||||||
|
rx_tx_time_diff->choice.k3 = f1_rxTxTimeDiff->choice.k3;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_k4:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K4;
|
||||||
|
rx_tx_time_diff->choice.k4 = f1_rxTxTimeDiff->choice.k4;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRxTxTimeDiffMeas_PR_k5:
|
||||||
|
rx_tx_time_diff->present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K5;
|
||||||
|
rx_tx_time_diff->choice.k5 = f1_rxTxTimeDiff->choice.k5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal rxTxTimeDiff value %d\n", f1_rxTxTimeDiff->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal measuredResultsValue %d\n", f1_measuredResultsValue->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeStamp
|
||||||
|
F1AP_TimeStamp_t *f1_timeStamp = &f1_pos_measurement_result_item->timeStamp;
|
||||||
|
f1ap_time_stamp_t *timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
timeStamp->system_frame_number = f1_timeStamp->systemFrameNumber;
|
||||||
|
F1AP_TimeStampSlotIndex_t *f1_slotIndex = &f1_timeStamp->slotIndex;
|
||||||
|
f1ap_time_stamp_slot_index_t *slot_index = &timeStamp->slot_index;
|
||||||
|
switch (f1_slotIndex->present) {
|
||||||
|
case F1AP_TimeStampSlotIndex_PR_NOTHING:
|
||||||
|
slot_index->present = F1AP_TIME_STAMP_SLOT_INDEX_PR_NOTHING;
|
||||||
|
break;
|
||||||
|
case F1AP_TimeStampSlotIndex_PR_sCS_15:
|
||||||
|
slot_index->present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_15;
|
||||||
|
slot_index->choice.scs_15 = f1_slotIndex->choice.sCS_15;
|
||||||
|
break;
|
||||||
|
case F1AP_TimeStampSlotIndex_PR_sCS_30:
|
||||||
|
slot_index->present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_30;
|
||||||
|
slot_index->choice.scs_30 = f1_slotIndex->choice.sCS_30;
|
||||||
|
break;
|
||||||
|
case F1AP_TimeStampSlotIndex_PR_sCS_60:
|
||||||
|
slot_index->present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_60;
|
||||||
|
slot_index->choice.scs_60 = f1_slotIndex->choice.sCS_60;
|
||||||
|
break;
|
||||||
|
case F1AP_TimeStampSlotIndex_PR_sCS_120:
|
||||||
|
slot_index->present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_120;
|
||||||
|
slot_index->choice.scs_120 = f1_slotIndex->choice.sCS_120;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal slotIndex value %d\n", f1_slotIndex->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f1ap_pos_measurement_result_t cp_positioning_measurement_result(const f1ap_pos_measurement_result_t *in)
|
||||||
|
{
|
||||||
|
f1ap_pos_measurement_result_t out = {0};
|
||||||
|
uint32_t pos_meas_result_length = in->pos_measurement_result_item_length;
|
||||||
|
out.pos_measurement_result_item_length = pos_meas_result_length;
|
||||||
|
out.pos_measurement_result_item = calloc_or_fail(pos_meas_result_length, sizeof(*out.pos_measurement_result_item));
|
||||||
|
for (int i = 0; i < pos_meas_result_length; i++) {
|
||||||
|
f1ap_pos_measurement_result_item_t *f1_pos_measurement_result_item = &in->pos_measurement_result_item[i];
|
||||||
|
f1ap_pos_measurement_result_item_t *pos_measurement_result_item = &out.pos_measurement_result_item[i];
|
||||||
|
|
||||||
|
// measuredResultsValue
|
||||||
|
f1ap_measured_results_value_t *f1_measuredResultsValue = &f1_pos_measurement_result_item->measured_results_value;
|
||||||
|
f1ap_measured_results_value_t *measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
|
||||||
|
measuredResultsValue->present = f1_measuredResultsValue->present;
|
||||||
|
switch (f1_measuredResultsValue->present) {
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_NOTHING:
|
||||||
|
// nothing to copy
|
||||||
|
break;
|
||||||
|
// Angle of Arrival
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL: {
|
||||||
|
f1ap_ul_aoa_t *f1_uL_AngleOfArrival = &f1_measuredResultsValue->choice.ul_angle_of_arrival;
|
||||||
|
f1ap_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival;
|
||||||
|
|
||||||
|
uL_AngleOfArrival->azimuth_aoa = f1_uL_AngleOfArrival->azimuth_aoa;
|
||||||
|
if (f1_uL_AngleOfArrival->zenith_aoa) {
|
||||||
|
uL_AngleOfArrival->zenith_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->zenith_aoa));
|
||||||
|
*uL_AngleOfArrival->zenith_aoa = *f1_uL_AngleOfArrival->zenith_aoa;
|
||||||
|
}
|
||||||
|
if (f1_uL_AngleOfArrival->lcs_to_gcs_translation_aoa) {
|
||||||
|
uL_AngleOfArrival->lcs_to_gcs_translation_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->lcs_to_gcs_translation_aoa));
|
||||||
|
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *lCS_to_GCS_TranslationAoA = uL_AngleOfArrival->lcs_to_gcs_translation_aoa;
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *f1_lCS_to_GCS_TranslationAoA = f1_uL_AngleOfArrival->lcs_to_gcs_translation_aoa;
|
||||||
|
|
||||||
|
lCS_to_GCS_TranslationAoA->alpha = f1_lCS_to_GCS_TranslationAoA->alpha;
|
||||||
|
lCS_to_GCS_TranslationAoA->beta = f1_lCS_to_GCS_TranslationAoA->beta;
|
||||||
|
lCS_to_GCS_TranslationAoA->gamma = f1_lCS_to_GCS_TranslationAoA->gamma;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// UL SRS RSRP
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP:
|
||||||
|
measuredResultsValue->choice.ul_srs_rsrp = f1_measuredResultsValue->choice.ul_srs_rsrp;
|
||||||
|
break;
|
||||||
|
// UL RTOA
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_RTOA: {
|
||||||
|
f1ap_ul_rtoa_measurement_t *f1_uL_RTOA = &f1_measuredResultsValue->choice.ul_rtoa;
|
||||||
|
f1ap_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa;
|
||||||
|
f1ap_ul_rtoa_measurement_item_t *f1_ul_rtoa_meas_item = &f1_uL_RTOA->ul_rtoa_measurement_item;
|
||||||
|
f1ap_ul_rtoa_measurement_item_t *ul_rtoa_meas_item = &uL_RTOA->ul_rtoa_measurement_item;
|
||||||
|
|
||||||
|
switch (f1_ul_rtoa_meas_item->present) {
|
||||||
|
case F1AP_ULRTOAMEAS_PR_NOTHING:
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K0:
|
||||||
|
ul_rtoa_meas_item->choice.k0 = f1_ul_rtoa_meas_item->choice.k0;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K1:
|
||||||
|
ul_rtoa_meas_item->choice.k1 = f1_ul_rtoa_meas_item->choice.k1;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K2:
|
||||||
|
ul_rtoa_meas_item->choice.k2 = f1_ul_rtoa_meas_item->choice.k2;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K3:
|
||||||
|
ul_rtoa_meas_item->choice.k3 = f1_ul_rtoa_meas_item->choice.k3;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K4:
|
||||||
|
ul_rtoa_meas_item->choice.k4 = f1_ul_rtoa_meas_item->choice.k4;
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K5:
|
||||||
|
ul_rtoa_meas_item->choice.k5 = f1_ul_rtoa_meas_item->choice.k5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal uL_RTOA_MeasurementItem %d\n", f1_uL_RTOA->ul_rtoa_measurement_item.present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// gNB RX-TX Time Diff
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF: {
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *f1_gNB_RxTxTimeDiff = &f1_measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
f1_gNB_RxTxTimeDiff->rx_tx_time_diff.present = gNB_RxTxTimeDiff->rx_tx_time_diff.present;
|
||||||
|
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t *f1_rx_tx_time_diff = &f1_gNB_RxTxTimeDiff->rx_tx_time_diff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t *rx_tx_time_diff = &gNB_RxTxTimeDiff->rx_tx_time_diff;
|
||||||
|
|
||||||
|
switch (f1_rx_tx_time_diff->present) {
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_NOTHING:
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K0:
|
||||||
|
rx_tx_time_diff->choice.k0 = f1_rx_tx_time_diff->choice.k0;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K1:
|
||||||
|
rx_tx_time_diff->choice.k1 = f1_rx_tx_time_diff->choice.k1;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K2:
|
||||||
|
rx_tx_time_diff->choice.k2 = f1_rx_tx_time_diff->choice.k2;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K3:
|
||||||
|
rx_tx_time_diff->choice.k3 = f1_rx_tx_time_diff->choice.k3;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K4:
|
||||||
|
rx_tx_time_diff->choice.k4 = f1_rx_tx_time_diff->choice.k4;
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K5:
|
||||||
|
rx_tx_time_diff->choice.k5 = f1_rx_tx_time_diff->choice.k5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal rxTxTimeDiff value %d\n", f1_rx_tx_time_diff->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal measuredResultsValue %d\n", f1_measuredResultsValue->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeStamp
|
||||||
|
f1ap_time_stamp_t *f1_timeStamp = &f1_pos_measurement_result_item->time_stamp;
|
||||||
|
f1ap_time_stamp_t *timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
timeStamp->system_frame_number = f1_timeStamp->system_frame_number;
|
||||||
|
f1ap_time_stamp_slot_index_t *f1_slot_index = &f1_timeStamp->slot_index;
|
||||||
|
f1ap_time_stamp_slot_index_t *slot_index = &timeStamp->slot_index;
|
||||||
|
switch (f1_slot_index->present) {
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_NOTHING:
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_15:
|
||||||
|
slot_index->choice.scs_15 = f1_slot_index->choice.scs_15;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_30:
|
||||||
|
slot_index->choice.scs_30 = f1_slot_index->choice.scs_30;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_60:
|
||||||
|
slot_index->choice.scs_60 = f1_slot_index->choice.scs_60;
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_120:
|
||||||
|
slot_index->choice.scs_120 = f1_slot_index->choice.scs_120;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "Illegal slotIndex value %d\n", f1_slot_index->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool eq_positioning_measurement_result(const f1ap_pos_measurement_result_t *f1_posMeasurementResult,
|
||||||
|
const f1ap_pos_measurement_result_t *posMeasurementResult)
|
||||||
|
{
|
||||||
|
uint32_t pos_meas_result_length = f1_posMeasurementResult->pos_measurement_result_item_length;
|
||||||
|
_F1_EQ_CHECK_INT(posMeasurementResult->pos_measurement_result_item_length, pos_meas_result_length);
|
||||||
|
for (int i = 0; i < pos_meas_result_length; i++) {
|
||||||
|
f1ap_pos_measurement_result_item_t *f1_pos_measurement_result_item = &f1_posMeasurementResult->pos_measurement_result_item[i];
|
||||||
|
f1ap_pos_measurement_result_item_t *pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[i];
|
||||||
|
|
||||||
|
// measuredResultsValue
|
||||||
|
f1ap_measured_results_value_t *f1_measuredResultsValue = &f1_pos_measurement_result_item->measured_results_value;
|
||||||
|
f1ap_measured_results_value_t *measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
|
||||||
|
_F1_EQ_CHECK_INT(measuredResultsValue->present, f1_measuredResultsValue->present);
|
||||||
|
switch (measuredResultsValue->present) {
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_NOTHING:
|
||||||
|
// nothing to check
|
||||||
|
break;
|
||||||
|
// Angle of Arrival
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL: {
|
||||||
|
f1ap_ul_aoa_t *f1_uL_AngleOfArrival = &f1_measuredResultsValue->choice.ul_angle_of_arrival;
|
||||||
|
f1ap_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival;
|
||||||
|
|
||||||
|
_F1_EQ_CHECK_INT(uL_AngleOfArrival->azimuth_aoa, f1_uL_AngleOfArrival->azimuth_aoa);
|
||||||
|
if (f1_uL_AngleOfArrival->zenith_aoa) {
|
||||||
|
_F1_EQ_CHECK_INT(*uL_AngleOfArrival->zenith_aoa, *f1_uL_AngleOfArrival->zenith_aoa);
|
||||||
|
}
|
||||||
|
if (f1_uL_AngleOfArrival->lcs_to_gcs_translation_aoa) {
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *lCS_to_GCS_TranslationAoA = uL_AngleOfArrival->lcs_to_gcs_translation_aoa;
|
||||||
|
f1ap_lcs_to_gcs_translationaoa_t *f1_lCS_to_GCS_TranslationAoA = f1_uL_AngleOfArrival->lcs_to_gcs_translation_aoa;
|
||||||
|
|
||||||
|
_F1_EQ_CHECK_INT(lCS_to_GCS_TranslationAoA->alpha, f1_lCS_to_GCS_TranslationAoA->alpha);
|
||||||
|
_F1_EQ_CHECK_INT(lCS_to_GCS_TranslationAoA->beta, f1_lCS_to_GCS_TranslationAoA->beta);
|
||||||
|
_F1_EQ_CHECK_INT(lCS_to_GCS_TranslationAoA->gamma, f1_lCS_to_GCS_TranslationAoA->gamma);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// UL SRS RSRP
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP:
|
||||||
|
_F1_EQ_CHECK_INT(measuredResultsValue->choice.ul_srs_rsrp, f1_measuredResultsValue->choice.ul_srs_rsrp);
|
||||||
|
break;
|
||||||
|
// UL RTOA
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_UL_RTOA: {
|
||||||
|
f1ap_ul_rtoa_measurement_t *f1_uL_RTOA = &f1_measuredResultsValue->choice.ul_rtoa;
|
||||||
|
f1ap_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa;
|
||||||
|
|
||||||
|
f1ap_ul_rtoa_measurement_item_t *f1_ul_rtoa_meas_item = &f1_uL_RTOA->ul_rtoa_measurement_item;
|
||||||
|
f1ap_ul_rtoa_measurement_item_t *ul_rtoa_meas_item = &uL_RTOA->ul_rtoa_measurement_item;
|
||||||
|
|
||||||
|
switch (f1_ul_rtoa_meas_item->present) {
|
||||||
|
case F1AP_ULRTOAMEAS_PR_NOTHING:
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K0:
|
||||||
|
_F1_EQ_CHECK_INT(ul_rtoa_meas_item->choice.k0, f1_ul_rtoa_meas_item->choice.k0);
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K1:
|
||||||
|
_F1_EQ_CHECK_INT(ul_rtoa_meas_item->choice.k1, f1_ul_rtoa_meas_item->choice.k1);
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K2:
|
||||||
|
_F1_EQ_CHECK_INT(ul_rtoa_meas_item->choice.k2, f1_ul_rtoa_meas_item->choice.k2);
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K3:
|
||||||
|
_F1_EQ_CHECK_INT(ul_rtoa_meas_item->choice.k3, f1_ul_rtoa_meas_item->choice.k3);
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K4:
|
||||||
|
_F1_EQ_CHECK_INT(ul_rtoa_meas_item->choice.k4, f1_ul_rtoa_meas_item->choice.k4);
|
||||||
|
break;
|
||||||
|
case F1AP_ULRTOAMEAS_PR_K5:
|
||||||
|
_F1_EQ_CHECK_INT(ul_rtoa_meas_item->choice.k5, f1_ul_rtoa_meas_item->choice.k5);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal uL_RTOA_MeasurementItem %d\n", f1_ul_rtoa_meas_item->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// gNB RX-TX Time Diff
|
||||||
|
case F1AP_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF: {
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *f1_gNB_RxTxTimeDiff = &f1_measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t *f1_rx_tx_time_diff = &f1_gNB_RxTxTimeDiff->rx_tx_time_diff;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_meas_t *rx_tx_time_diff = &gNB_RxTxTimeDiff->rx_tx_time_diff;
|
||||||
|
_F1_EQ_CHECK_INT(f1_rx_tx_time_diff->present, rx_tx_time_diff->present);
|
||||||
|
switch (f1_rx_tx_time_diff->present) {
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_NOTHING:
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K0:
|
||||||
|
_F1_EQ_CHECK_INT(rx_tx_time_diff->choice.k0, f1_rx_tx_time_diff->choice.k0);
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K1:
|
||||||
|
_F1_EQ_CHECK_INT(rx_tx_time_diff->choice.k1, f1_rx_tx_time_diff->choice.k1);
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K2:
|
||||||
|
_F1_EQ_CHECK_INT(rx_tx_time_diff->choice.k2, f1_rx_tx_time_diff->choice.k2);
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K3:
|
||||||
|
_F1_EQ_CHECK_INT(rx_tx_time_diff->choice.k3, f1_rx_tx_time_diff->choice.k3);
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K4:
|
||||||
|
_F1_EQ_CHECK_INT(rx_tx_time_diff->choice.k4, f1_rx_tx_time_diff->choice.k4);
|
||||||
|
break;
|
||||||
|
case F1AP_GNBRXTXTIMEDIFFMEAS_PR_K5:
|
||||||
|
_F1_EQ_CHECK_INT(rx_tx_time_diff->choice.k5, f1_rx_tx_time_diff->choice.k5);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal rxTxTimeDiff value %d\n", f1_rx_tx_time_diff->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal measuredResultsValue %d\n", f1_measuredResultsValue->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeStamp
|
||||||
|
f1ap_time_stamp_t *f1_timeStamp = &f1_pos_measurement_result_item->time_stamp;
|
||||||
|
f1ap_time_stamp_t *timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
_F1_EQ_CHECK_INT(timeStamp->system_frame_number, f1_timeStamp->system_frame_number);
|
||||||
|
f1ap_time_stamp_slot_index_t *f1_slot_index = &f1_timeStamp->slot_index;
|
||||||
|
f1ap_time_stamp_slot_index_t *slot_index = &timeStamp->slot_index;
|
||||||
|
|
||||||
|
switch (f1_slot_index->present) {
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_NOTHING:
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_15:
|
||||||
|
_F1_EQ_CHECK_INT(slot_index->choice.scs_15, f1_slot_index->choice.scs_15);
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_30:
|
||||||
|
_F1_EQ_CHECK_INT(slot_index->choice.scs_30, f1_slot_index->choice.scs_30);
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_60:
|
||||||
|
_F1_EQ_CHECK_INT(slot_index->choice.scs_60, f1_slot_index->choice.scs_60);
|
||||||
|
break;
|
||||||
|
case F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_120:
|
||||||
|
_F1_EQ_CHECK_INT(slot_index->choice.scs_120, f1_slot_index->choice.scs_120);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertError(false, return false, "Illegal slotIndex value %d\n", f1_slot_index->present);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encode F1 positioning information request to ASN.1
|
* @brief Encode F1 positioning information request to ASN.1
|
||||||
*/
|
*/
|
||||||
@@ -4799,3 +5421,221 @@ void free_positioning_measurement_req(f1ap_positioning_measurement_req_t *msg)
|
|||||||
free(msg->srs_configuration);
|
free(msg->srs_configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode F1 positioning measurement response to ASN.1
|
||||||
|
*/
|
||||||
|
F1AP_F1AP_PDU_t *encode_positioning_measurement_resp(const f1ap_positioning_measurement_resp_t *msg)
|
||||||
|
{
|
||||||
|
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
|
||||||
|
|
||||||
|
/* Message Type */
|
||||||
|
pdu->present = F1AP_F1AP_PDU_PR_successfulOutcome;
|
||||||
|
asn1cCalloc(pdu->choice.successfulOutcome, tmp);
|
||||||
|
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningMeasurementExchange;
|
||||||
|
tmp->criticality = F1AP_Criticality_reject;
|
||||||
|
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_PositioningMeasurementResponse;
|
||||||
|
F1AP_PositioningMeasurementResponse_t *out = &tmp->value.choice.PositioningMeasurementResponse;
|
||||||
|
|
||||||
|
/* mandatory : TransactionID */
|
||||||
|
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementResponseIEs_t, ie1);
|
||||||
|
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||||
|
ie1->criticality = F1AP_Criticality_reject;
|
||||||
|
ie1->value.present = F1AP_PositioningMeasurementResponseIEs__value_PR_TransactionID;
|
||||||
|
ie1->value.choice.TransactionID = msg->transaction_id;
|
||||||
|
|
||||||
|
/* mandatory : LMF_MeasurementID */
|
||||||
|
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementResponseIEs_t, ie2);
|
||||||
|
ie2->id = F1AP_ProtocolIE_ID_id_LMF_MeasurementID;
|
||||||
|
ie2->criticality = F1AP_Criticality_reject;
|
||||||
|
ie2->value.present = F1AP_PositioningMeasurementResponseIEs__value_PR_LMF_MeasurementID;
|
||||||
|
ie2->value.choice.LMF_MeasurementID = msg->lmf_measurement_id;
|
||||||
|
|
||||||
|
/* mandatory : RAN_MeasurementID */
|
||||||
|
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementResponseIEs_t, ie3);
|
||||||
|
ie3->id = F1AP_ProtocolIE_ID_id_RAN_MeasurementID;
|
||||||
|
ie3->criticality = F1AP_Criticality_reject;
|
||||||
|
ie3->value.present = F1AP_PositioningMeasurementResponseIEs__value_PR_RAN_MeasurementID;
|
||||||
|
ie3->value.choice.RAN_MeasurementID = msg->ran_measurement_id;
|
||||||
|
|
||||||
|
/* Positioning Measurement Result List */
|
||||||
|
if (msg->pos_measurement_result_list) {
|
||||||
|
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementResponseIEs_t, ie4);
|
||||||
|
ie4->id = F1AP_ProtocolIE_ID_id_PosMeasurementResultList;
|
||||||
|
ie4->criticality = F1AP_Criticality_reject;
|
||||||
|
ie4->value.present = F1AP_PositioningMeasurementResponseIEs__value_PR_PosMeasurementResultList;
|
||||||
|
const f1ap_pos_measurement_result_list_t *in_list = msg->pos_measurement_result_list;
|
||||||
|
for (int i = 0; i < in_list->pos_measurement_result_list_length; i++) {
|
||||||
|
// mandatory : Positioning Measurement Result List Item
|
||||||
|
asn1cSequenceAdd(ie4->value.choice.PosMeasurementResultList.list, F1AP_PosMeasurementResultList_Item_t, out_item);
|
||||||
|
f1ap_pos_measurement_result_list_item_t *in_item = &in_list->pos_measurement_result_list_item[i];
|
||||||
|
F1AP_PosMeasurementResult_t *out_result = &out_item->posMeasurementResult;
|
||||||
|
f1ap_pos_measurement_result_t *in_result = &in_item->pos_measurement_result;
|
||||||
|
*out_result = encode_positioning_measurement_result(in_result);
|
||||||
|
out_item->tRPID = in_item->trp_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode F1 Positioning Measurement response
|
||||||
|
*/
|
||||||
|
bool decode_positioning_measurement_resp(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_measurement_resp_t *out)
|
||||||
|
{
|
||||||
|
DevAssert(out != NULL);
|
||||||
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
|
F1AP_PositioningMeasurementResponse_t *in = &pdu->choice.successfulOutcome->value.choice.PositioningMeasurementResponse;
|
||||||
|
F1AP_PositioningMeasurementResponseIEs_t *ie;
|
||||||
|
|
||||||
|
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementResponseIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||||
|
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementResponseIEs_t,
|
||||||
|
ie,
|
||||||
|
&in->protocolIEs.list,
|
||||||
|
F1AP_ProtocolIE_ID_id_LMF_MeasurementID,
|
||||||
|
true);
|
||||||
|
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementResponseIEs_t,
|
||||||
|
ie,
|
||||||
|
&in->protocolIEs.list,
|
||||||
|
F1AP_ProtocolIE_ID_id_RAN_MeasurementID,
|
||||||
|
true);
|
||||||
|
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementResponseIEs_t,
|
||||||
|
ie,
|
||||||
|
&in->protocolIEs.list,
|
||||||
|
F1AP_ProtocolIE_ID_id_PosMeasurementResultList,
|
||||||
|
false);
|
||||||
|
|
||||||
|
for (int i = 0; i < in->protocolIEs.list.count; ++i) {
|
||||||
|
ie = in->protocolIEs.list.array[i];
|
||||||
|
AssertError(ie != NULL, return false, "in->protocolIEs.list.array[i] is NULL");
|
||||||
|
switch (ie->id) {
|
||||||
|
case F1AP_ProtocolIE_ID_id_TransactionID:
|
||||||
|
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementResponseIEs__value_PR_TransactionID);
|
||||||
|
out->transaction_id = ie->value.choice.TransactionID;
|
||||||
|
break;
|
||||||
|
case F1AP_ProtocolIE_ID_id_LMF_MeasurementID:
|
||||||
|
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementResponseIEs__value_PR_LMF_MeasurementID);
|
||||||
|
out->lmf_measurement_id = ie->value.choice.LMF_MeasurementID;
|
||||||
|
break;
|
||||||
|
case F1AP_ProtocolIE_ID_id_RAN_MeasurementID:
|
||||||
|
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementResponseIEs__value_PR_RAN_MeasurementID);
|
||||||
|
out->ran_measurement_id = ie->value.choice.RAN_MeasurementID;
|
||||||
|
break;
|
||||||
|
case F1AP_ProtocolIE_ID_id_PosMeasurementResultList:
|
||||||
|
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementResponseIEs__value_PR_PosMeasurementResultList);
|
||||||
|
F1AP_PosMeasurementResultList_t *in_list = &ie->value.choice.PosMeasurementResultList;
|
||||||
|
uint32_t pos_meas_result_list_len = in_list->list.count;
|
||||||
|
out->pos_measurement_result_list = calloc_or_fail(1, sizeof(*out->pos_measurement_result_list));
|
||||||
|
f1ap_pos_measurement_result_list_t *out_list = out->pos_measurement_result_list;
|
||||||
|
out_list->pos_measurement_result_list_length = pos_meas_result_list_len;
|
||||||
|
out_list->pos_measurement_result_list_item =
|
||||||
|
calloc_or_fail(pos_meas_result_list_len, sizeof(*out_list->pos_measurement_result_list_item));
|
||||||
|
for (int i = 0; i < pos_meas_result_list_len; i++) {
|
||||||
|
F1AP_PosMeasurementResultList_Item_t *in_item = in_list->list.array[i];
|
||||||
|
f1ap_pos_measurement_result_list_item_t *out_item = &out_list->pos_measurement_result_list_item[i];
|
||||||
|
_F1_CHECK_EXP(decode_positioning_measurement_result(&in_item->posMeasurementResult, &out_item->pos_measurement_result));
|
||||||
|
out_item->trp_id = in_item->tRPID;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case F1AP_ProtocolIE_ID_id_CriticalityDiagnostics:
|
||||||
|
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld unknown, skipping\n", ie->id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief F1 Positioning Measurement response deep copy
|
||||||
|
*/
|
||||||
|
f1ap_positioning_measurement_resp_t cp_positioning_measurement_resp(const f1ap_positioning_measurement_resp_t *orig)
|
||||||
|
{
|
||||||
|
// copy all mandatory fields that are not dynamic memory
|
||||||
|
f1ap_positioning_measurement_resp_t cp = {
|
||||||
|
.transaction_id = orig->transaction_id,
|
||||||
|
.lmf_measurement_id = orig->lmf_measurement_id,
|
||||||
|
.ran_measurement_id = orig->ran_measurement_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (orig->pos_measurement_result_list) {
|
||||||
|
cp.pos_measurement_result_list = calloc_or_fail(1, sizeof(*cp.pos_measurement_result_list));
|
||||||
|
f1ap_pos_measurement_result_list_t *list_orig = orig->pos_measurement_result_list;
|
||||||
|
f1ap_pos_measurement_result_list_t *list_cp = cp.pos_measurement_result_list;
|
||||||
|
uint32_t pos_meas_result_list_len = list_orig->pos_measurement_result_list_length;
|
||||||
|
list_cp->pos_measurement_result_list_length = pos_meas_result_list_len;
|
||||||
|
list_cp->pos_measurement_result_list_item =
|
||||||
|
calloc_or_fail(pos_meas_result_list_len, sizeof(*list_cp->pos_measurement_result_list_item));
|
||||||
|
for (int i = 0; i < pos_meas_result_list_len; i++) {
|
||||||
|
f1ap_pos_measurement_result_list_item_t *item_cp = &list_cp->pos_measurement_result_list_item[i];
|
||||||
|
f1ap_pos_measurement_result_list_item_t *item_orig = &list_orig->pos_measurement_result_list_item[i];
|
||||||
|
item_cp->pos_measurement_result = cp_positioning_measurement_result(&item_orig->pos_measurement_result);
|
||||||
|
item_cp->trp_id = item_orig->trp_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief F1 Positioning Measurement response equality check
|
||||||
|
*/
|
||||||
|
bool eq_positioning_measurement_resp(const f1ap_positioning_measurement_resp_t *a, const f1ap_positioning_measurement_resp_t *b)
|
||||||
|
{
|
||||||
|
_F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
|
||||||
|
_F1_EQ_CHECK_INT(a->lmf_measurement_id, b->lmf_measurement_id);
|
||||||
|
_F1_EQ_CHECK_INT(a->ran_measurement_id, b->ran_measurement_id);
|
||||||
|
|
||||||
|
if ((a->pos_measurement_result_list == NULL) != (b->pos_measurement_result_list == NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a->pos_measurement_result_list) {
|
||||||
|
f1ap_pos_measurement_result_list_t *list_a = a->pos_measurement_result_list;
|
||||||
|
f1ap_pos_measurement_result_list_t *list_b = b->pos_measurement_result_list;
|
||||||
|
uint32_t pos_meas_result_list_len = list_a->pos_measurement_result_list_length;
|
||||||
|
_F1_EQ_CHECK_INT(list_b->pos_measurement_result_list_length, pos_meas_result_list_len);
|
||||||
|
for (int i = 0; i < pos_meas_result_list_len; i++) {
|
||||||
|
f1ap_pos_measurement_result_list_item_t *item_a = &list_a->pos_measurement_result_list_item[i];
|
||||||
|
f1ap_pos_measurement_result_list_item_t *item_b = &list_b->pos_measurement_result_list_item[i];
|
||||||
|
_F1_CHECK_EXP(eq_positioning_measurement_result(&item_a->pos_measurement_result, &item_b->pos_measurement_result));
|
||||||
|
_F1_EQ_CHECK_INT(item_a->trp_id, item_b->trp_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free Allocated F1 Positioning Measurement response
|
||||||
|
*/
|
||||||
|
void free_positioning_measurement_resp(f1ap_positioning_measurement_resp_t *msg)
|
||||||
|
{
|
||||||
|
if (msg->pos_measurement_result_list) {
|
||||||
|
f1ap_pos_measurement_result_list_t *list = msg->pos_measurement_result_list;
|
||||||
|
uint32_t pos_meas_result_list_len = list->pos_measurement_result_list_length;
|
||||||
|
for (int i = 0; i < pos_meas_result_list_len; i++) {
|
||||||
|
f1ap_pos_measurement_result_t *posMeasurementResult = &list->pos_measurement_result_list_item[i].pos_measurement_result;
|
||||||
|
uint32_t pos_meas_result_length = posMeasurementResult->pos_measurement_result_item_length;
|
||||||
|
for (int j = 0; j < pos_meas_result_length; j++) {
|
||||||
|
f1ap_pos_measurement_result_item_t *item = &posMeasurementResult->pos_measurement_result_item[j];
|
||||||
|
f1ap_measured_results_value_t *measuredResultsValue = &item->measured_results_value;
|
||||||
|
if (measuredResultsValue->present == F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL) {
|
||||||
|
if (measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa) {
|
||||||
|
free(measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa);
|
||||||
|
}
|
||||||
|
if (measuredResultsValue->choice.ul_angle_of_arrival.lcs_to_gcs_translation_aoa) {
|
||||||
|
free(measuredResultsValue->choice.ul_angle_of_arrival.lcs_to_gcs_translation_aoa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(posMeasurementResult->pos_measurement_result_item);
|
||||||
|
}
|
||||||
|
free(msg->pos_measurement_result_list->pos_measurement_result_list_item);
|
||||||
|
free(msg->pos_measurement_result_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -114,4 +114,10 @@ f1ap_positioning_measurement_req_t cp_positioning_measurement_req(const f1ap_pos
|
|||||||
bool eq_positioning_measurement_req(const f1ap_positioning_measurement_req_t *a, const f1ap_positioning_measurement_req_t *b);
|
bool eq_positioning_measurement_req(const f1ap_positioning_measurement_req_t *a, const f1ap_positioning_measurement_req_t *b);
|
||||||
void free_positioning_measurement_req(f1ap_positioning_measurement_req_t *msg);
|
void free_positioning_measurement_req(f1ap_positioning_measurement_req_t *msg);
|
||||||
|
|
||||||
|
// positioning measurement response
|
||||||
|
struct F1AP_F1AP_PDU *encode_positioning_measurement_resp(const f1ap_positioning_measurement_resp_t *msg);
|
||||||
|
bool decode_positioning_measurement_resp(const struct F1AP_F1AP_PDU *pdu, f1ap_positioning_measurement_resp_t *out);
|
||||||
|
f1ap_positioning_measurement_resp_t cp_positioning_measurement_resp(const f1ap_positioning_measurement_resp_t *orig);
|
||||||
|
bool eq_positioning_measurement_resp(const f1ap_positioning_measurement_resp_t *a, const f1ap_positioning_measurement_resp_t *b);
|
||||||
|
void free_positioning_measurement_resp(f1ap_positioning_measurement_resp_t *msg);
|
||||||
#endif /* F1AP_POSITIONING_H_ */
|
#endif /* F1AP_POSITIONING_H_ */
|
||||||
|
|||||||
@@ -2033,6 +2033,108 @@ static void test_f1ap_positioning_measurement_request()
|
|||||||
printf("%s() successful\n", __func__);
|
printf("%s() successful\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_f1ap_positioning_measurement_response()
|
||||||
|
{
|
||||||
|
f1ap_positioning_measurement_resp_t orig = {
|
||||||
|
.transaction_id = 12,
|
||||||
|
.lmf_measurement_id = 1999,
|
||||||
|
.ran_measurement_id = 2225,
|
||||||
|
};
|
||||||
|
|
||||||
|
orig.pos_measurement_result_list = calloc_or_fail(1, sizeof(*orig.pos_measurement_result_list));
|
||||||
|
uint32_t pos_meas_result_list_len = 2;
|
||||||
|
orig.pos_measurement_result_list->pos_measurement_result_list_length = pos_meas_result_list_len;
|
||||||
|
orig.pos_measurement_result_list->pos_measurement_result_list_item =
|
||||||
|
calloc_or_fail(pos_meas_result_list_len, sizeof(*orig.pos_measurement_result_list->pos_measurement_result_list_item));
|
||||||
|
for (int i = 0; i < pos_meas_result_list_len; i++) {
|
||||||
|
f1ap_pos_measurement_result_list_item_t *pos_meas_result_list_item =
|
||||||
|
&orig.pos_measurement_result_list->pos_measurement_result_list_item[i];
|
||||||
|
pos_meas_result_list_item->trp_id = 10 + i;
|
||||||
|
|
||||||
|
f1ap_pos_measurement_result_t *posMeasurementResult = &pos_meas_result_list_item->pos_measurement_result;
|
||||||
|
uint32_t pos_meas_result_length = 4;
|
||||||
|
posMeasurementResult->pos_measurement_result_item_length = pos_meas_result_length;
|
||||||
|
posMeasurementResult->pos_measurement_result_item =
|
||||||
|
calloc_or_fail(pos_meas_result_length, sizeof(*posMeasurementResult->pos_measurement_result_item));
|
||||||
|
|
||||||
|
// Angle of arrival
|
||||||
|
f1ap_pos_measurement_result_item_t *pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[0];
|
||||||
|
f1ap_measured_results_value_t *measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL;
|
||||||
|
f1ap_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;
|
||||||
|
uL_AngleOfArrival->lcs_to_gcs_translation_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->lcs_to_gcs_translation_aoa));
|
||||||
|
uL_AngleOfArrival->lcs_to_gcs_translation_aoa->alpha = 200;
|
||||||
|
uL_AngleOfArrival->lcs_to_gcs_translation_aoa->beta = 220;
|
||||||
|
uL_AngleOfArrival->lcs_to_gcs_translation_aoa->gamma = 280;
|
||||||
|
|
||||||
|
f1ap_time_stamp_t *timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
timeStamp->system_frame_number = 100;
|
||||||
|
timeStamp->slot_index.present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_30;
|
||||||
|
timeStamp->slot_index.choice.scs_30 = 15;
|
||||||
|
|
||||||
|
// UL SRS RSRP
|
||||||
|
pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[1];
|
||||||
|
measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP;
|
||||||
|
measuredResultsValue->choice.ul_srs_rsrp = 100 + i;
|
||||||
|
|
||||||
|
timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
timeStamp->system_frame_number = 101;
|
||||||
|
timeStamp->slot_index.present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_15;
|
||||||
|
timeStamp->slot_index.choice.scs_15 = 8;
|
||||||
|
|
||||||
|
// UL RToA
|
||||||
|
pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[2];
|
||||||
|
measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_UL_RTOA;
|
||||||
|
f1ap_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa;
|
||||||
|
uL_RTOA->ul_rtoa_measurement_item.present = F1AP_ULRTOAMEAS_PR_K1;
|
||||||
|
uL_RTOA->ul_rtoa_measurement_item.choice.k1 = 98500 + i;
|
||||||
|
|
||||||
|
timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
timeStamp->system_frame_number = 102;
|
||||||
|
timeStamp->slot_index.present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_60;
|
||||||
|
timeStamp->slot_index.choice.scs_60 = 31;
|
||||||
|
|
||||||
|
// gNB RX-TX Time Diff
|
||||||
|
pos_measurement_result_item = &posMeasurementResult->pos_measurement_result_item[3];
|
||||||
|
measuredResultsValue = &pos_measurement_result_item->measured_results_value;
|
||||||
|
measuredResultsValue->present = F1AP_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF;
|
||||||
|
f1ap_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff;
|
||||||
|
gNB_RxTxTimeDiff->rx_tx_time_diff.present = F1AP_GNBRXTXTIMEDIFFMEAS_PR_K3;
|
||||||
|
gNB_RxTxTimeDiff->rx_tx_time_diff.choice.k3 = 98412 + i;
|
||||||
|
|
||||||
|
timeStamp = &pos_measurement_result_item->time_stamp;
|
||||||
|
timeStamp->system_frame_number = 103;
|
||||||
|
timeStamp->slot_index.present = F1AP_TIME_STAMP_SLOT_INDEX_PR_SCS_120;
|
||||||
|
timeStamp->slot_index.choice.scs_120 = 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
F1AP_F1AP_PDU_t *f1enc = encode_positioning_measurement_resp(&orig);
|
||||||
|
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
|
||||||
|
f1ap_msg_free(f1enc);
|
||||||
|
|
||||||
|
f1ap_positioning_measurement_resp_t decoded = {0};
|
||||||
|
bool ret = decode_positioning_measurement_resp(f1dec, &decoded);
|
||||||
|
AssertFatal(ret, "decode_positioning_measurement_resp(): could not decode message\n");
|
||||||
|
f1ap_msg_free(f1dec);
|
||||||
|
|
||||||
|
ret = eq_positioning_measurement_resp(&orig, &decoded);
|
||||||
|
AssertFatal(ret, "eq_positioning_measurement_resp(): decoded message doesn't match\n");
|
||||||
|
free_positioning_measurement_resp(&decoded);
|
||||||
|
|
||||||
|
f1ap_positioning_measurement_resp_t cp = cp_positioning_measurement_resp(&orig);
|
||||||
|
ret = eq_positioning_measurement_resp(&orig, &cp);
|
||||||
|
AssertFatal(ret, "eq_positioning_measurement_resp(): copied message doesn't match\n");
|
||||||
|
free_positioning_measurement_resp(&orig);
|
||||||
|
free_positioning_measurement_resp(&cp);
|
||||||
|
|
||||||
|
printf("%s() successful\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_initial_ul_rrc_message_transfer();
|
test_initial_ul_rrc_message_transfer();
|
||||||
@@ -2071,5 +2173,6 @@ int main()
|
|||||||
test_f1ap_trp_information_response();
|
test_f1ap_trp_information_response();
|
||||||
test_f1ap_trp_information_failure();
|
test_f1ap_trp_information_failure();
|
||||||
test_f1ap_positioning_measurement_request();
|
test_f1ap_positioning_measurement_request();
|
||||||
|
test_f1ap_positioning_measurement_response();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user