Files
openairinterface5g/openair2/F1AP/lib/f1ap_positioning.c
T
Rakesh Mundlamuri 8a97d94725 Add F1AP positioning measurement failure message enc/dec + test
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transaction ID (supported)
LMF Measurement ID (supported)
RAN Measurement ID (supported)
Cause (supported)
Optional fields:
Criticality Diagnostics (not supported)
2026-01-15 15:26:35 +05:30

5784 lines
293 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "f1ap_positioning.h"
#include "f1ap_lib_common.h"
#include "f1ap_lib_includes.h"
#include "f1ap_messages_types.h"
#include "common/utils/assertions.h"
#include "openair3/UTILS/conversions.h"
#include "common/utils/oai_asn1.h"
#include "common/utils/utils.h"
#include "common/utils/ds/byte_array.h"
static F1AP_SRSConfig_t encode_srs_config(const f1ap_srs_config_t *in_config)
{
F1AP_SRSConfig_t out_config = {0};
// optional: srs_resource_list
if (in_config->srs_resource_list) {
f1ap_srs_resource_list_t *srs_resource_list = in_config->srs_resource_list;
uint32_t srs_resource_list_length = srs_resource_list->srs_resource_list_length;
asn1cCalloc(out_config.sRSResource_List, f1_sRSResource_List);
for (int i = 0; i < srs_resource_list_length; i++) {
asn1cSequenceAdd(f1_sRSResource_List->list, F1AP_SRSResource_t, f1_srs_resource);
f1ap_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i];
f1_srs_resource->sRSResourceID = srs_resource->srs_resource_id;
switch (srs_resource->nr_of_srs_ports) {
case F1AP_SRS_NUMBER_OF_PORTS_N1:
f1_srs_resource->nrofSRS_Ports = F1AP_SRSResource__nrofSRS_Ports_port1;
break;
case F1AP_SRS_NUMBER_OF_PORTS_N2:
f1_srs_resource->nrofSRS_Ports = F1AP_SRSResource__nrofSRS_Ports_ports2;
break;
case F1AP_SRS_NUMBER_OF_PORTS_N4:
f1_srs_resource->nrofSRS_Ports = F1AP_SRSResource__nrofSRS_Ports_ports4;
break;
default:
AssertFatal(false, "illegal number of srs ports %d\n", srs_resource->nr_of_srs_ports);
break;
}
f1ap_transmission_comb_t *srs_res_tx_comb = &srs_resource->transmission_comb;
switch (srs_res_tx_comb->present) {
case F1AP_TRANSMISSION_COMB_PR_NOTHING:
f1_srs_resource->transmissionComb.present = F1AP_TransmissionComb_PR_NOTHING;
break;
case F1AP_TRANSMISSION_COMB_PR_N2:
f1_srs_resource->transmissionComb.present = F1AP_TransmissionComb_PR_n2;
asn1cCalloc(f1_srs_resource->transmissionComb.choice.n2, f1_n2);
f1_n2->combOffset_n2 = srs_res_tx_comb->choice.n2.comb_offset_n2;
f1_n2->cyclicShift_n2 = srs_res_tx_comb->choice.n2.cyclic_shift_n2;
break;
case F1AP_TRANSMISSION_COMB_PR_N4:
f1_srs_resource->transmissionComb.present = F1AP_TransmissionComb_PR_n4;
asn1cCalloc(f1_srs_resource->transmissionComb.choice.n4, f1_n4);
f1_n4->combOffset_n4 = srs_res_tx_comb->choice.n4.comb_offset_n4;
f1_n4->cyclicShift_n4 = srs_res_tx_comb->choice.n4.cyclic_shift_n4;
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", srs_res_tx_comb->present);
break;
}
f1_srs_resource->startPosition = srs_resource->start_position;
switch (srs_resource->nr_of_symbols) {
case F1AP_SRS_NUMBER_OF_SYMBOLS_N1:
f1_srs_resource->nrofSymbols = F1AP_SRSResource__nrofSymbols_n1;
break;
case F1AP_SRS_NUMBER_OF_SYMBOLS_N2:
f1_srs_resource->nrofSymbols = F1AP_SRSResource__nrofSymbols_n2;
break;
case F1AP_SRS_NUMBER_OF_SYMBOLS_N4:
f1_srs_resource->nrofSymbols = F1AP_SRSResource__nrofSymbols_n4;
break;
default:
AssertFatal(false, "illegal number of symbols %d\n", srs_resource->nr_of_symbols);
break;
}
switch (srs_resource->repetition_factor) {
case F1AP_SRS_REPETITION_FACTOR_RF1:
f1_srs_resource->repetitionFactor = F1AP_SRSResource__repetitionFactor_n1;
break;
case F1AP_SRS_REPETITION_FACTOR_RF2:
f1_srs_resource->repetitionFactor = F1AP_SRSResource__repetitionFactor_n2;
break;
case F1AP_SRS_REPETITION_FACTOR_RF4:
f1_srs_resource->repetitionFactor = F1AP_SRSResource__repetitionFactor_n4;
break;
default:
AssertFatal(false, "illegal repetition factor %d\n", srs_resource->repetition_factor);
break;
}
f1_srs_resource->freqDomainPosition = srs_resource->freq_domain_position;
f1_srs_resource->freqDomainShift = srs_resource->freq_domain_shift;
f1_srs_resource->c_SRS = srs_resource->c_srs;
f1_srs_resource->b_SRS = srs_resource->b_srs;
f1_srs_resource->b_hop = srs_resource->b_hop;
switch (srs_resource->group_or_sequence_hopping) {
case F1AP_GROUPORSEQUENCEHOPPING_NOTHING:
f1_srs_resource->groupOrSequenceHopping = F1AP_SRSResource__groupOrSequenceHopping_neither;
break;
case F1AP_GROUPORSEQUENCEHOPPING_GROUPHOPPING:
f1_srs_resource->groupOrSequenceHopping = F1AP_SRSResource__groupOrSequenceHopping_groupHopping;
break;
case F1AP_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING:
f1_srs_resource->groupOrSequenceHopping = F1AP_SRSResource__groupOrSequenceHopping_sequenceHopping;
break;
default:
AssertFatal(false, "illegal groupOrSequenceHopping %d\n", srs_resource->group_or_sequence_hopping);
break;
}
F1AP_ResourceType_t *f1_resourceType = &f1_srs_resource->resourceType;
f1ap_resource_type_t *resource_type = &srs_resource->resource_type;
if (resource_type->present == F1AP_RESOURCE_TYPE_PR_NOTHING) {
f1_resourceType->present = F1AP_ResourceType_PR_NOTHING;
} else if (resource_type->present == F1AP_RESOURCE_TYPE_PR_PERIODIC) {
f1_resourceType->present = F1AP_ResourceType_PR_periodic;
asn1cCalloc(f1_resourceType->choice.periodic, f1_periodic);
switch (resource_type->choice.periodic.periodicity) {
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot1;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot2;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot4;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot5;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot8;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot10;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot16;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot20;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot32;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot40;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot64;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot80;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot160;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot320;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot640;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot1280;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560:
f1_periodic->periodicity = F1AP_ResourceTypePeriodic__periodicity_slot2560;
break;
default:
AssertFatal(false, "illegal periodicity %d\n", resource_type->choice.periodic.periodicity);
break;
}
f1_periodic->offset = resource_type->choice.periodic.offset;
} else if (resource_type->present == F1AP_RESOURCE_TYPE_PR_SEMI_PERSISTENT) {
f1_resourceType->present = F1AP_ResourceType_PR_semi_persistent;
asn1cCalloc(f1_resourceType->choice.semi_persistent, f1_semi_persistent);
switch (resource_type->choice.semi_persistent.periodicity) {
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot1;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot2;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot4;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot5;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot8;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot10;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot16;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot20;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot32;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot40;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot64;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot80;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot160;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot320;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot640;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot1280;
break;
case F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560:
f1_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistent__periodicity_slot2560;
break;
default:
AssertFatal(false, "illegal periodicity %d\n", resource_type->choice.semi_persistent.periodicity);
break;
}
f1_semi_persistent->offset = resource_type->choice.semi_persistent.offset;
} else if (resource_type->present == F1AP_RESOURCE_TYPE_PR_APERIODIC) {
f1_resourceType->present = F1AP_ResourceType_PR_aperiodic;
asn1cCalloc(f1_resourceType->choice.aperiodic, f1_aperiodic);
f1_aperiodic->aperiodicResourceType = resource_type->choice.aperiodic;
} else {
AssertFatal(false, "illegal resourceType %d\n", resource_type->present);
}
f1_srs_resource->sequenceId = srs_resource->sequence_id;
}
}
// optional: pos_srs_resource_list
if (in_config->pos_srs_resource_list) {
f1ap_pos_srs_resource_list_t *pos_srs_resource_list = in_config->pos_srs_resource_list;
uint32_t pos_srs_resource_list_length = pos_srs_resource_list->pos_srs_resource_list_length;
asn1cCalloc(out_config.posSRSResource_List, f1_posSRSResource_List);
for (int i = 0; i < pos_srs_resource_list_length; i++) {
asn1cSequenceAdd(f1_posSRSResource_List->list, F1AP_PosSRSResource_Item_t, f1_pos_srs_resource);
f1ap_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i];
f1_pos_srs_resource->srs_PosResourceId = pos_srs_resource->srs_pos_resource_id;
f1ap_transmission_comb_pos_t *pos_srs_res_tx_comb = &pos_srs_resource->transmission_comb_pos;
switch (pos_srs_res_tx_comb->present) {
case F1AP_TRANSMISSION_COMB_POS_PR_NOTHING:
f1_pos_srs_resource->transmissionCombPos.present = F1AP_TransmissionCombPos_PR_NOTHING;
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N2:
f1_pos_srs_resource->transmissionCombPos.present = F1AP_TransmissionCombPos_PR_n2;
asn1cCalloc(f1_pos_srs_resource->transmissionCombPos.choice.n2, f1_pos_srs_resource_n2);
f1ap_transmission_comb_pos_n2_t *pos_srs_resource_n2 = &pos_srs_res_tx_comb->choice.n2;
f1_pos_srs_resource_n2->combOffset_n2 = pos_srs_resource_n2->comb_offset_n2;
f1_pos_srs_resource_n2->cyclicShift_n2 = pos_srs_resource_n2->cyclic_shift_n2;
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N4:
f1_pos_srs_resource->transmissionCombPos.present = F1AP_TransmissionCombPos_PR_n4;
asn1cCalloc(f1_pos_srs_resource->transmissionCombPos.choice.n4, f1_pos_srs_resource_n4);
f1ap_transmission_comb_pos_n4_t *pos_srs_resource_n4 = &pos_srs_res_tx_comb->choice.n4;
f1_pos_srs_resource_n4->combOffset_n4 = pos_srs_resource_n4->comb_offset_n4;
f1_pos_srs_resource_n4->cyclicShift_n4 = pos_srs_resource_n4->cyclic_shift_n4;
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N8:
f1_pos_srs_resource->transmissionCombPos.present = F1AP_TransmissionCombPos_PR_n8;
asn1cCalloc(f1_pos_srs_resource->transmissionCombPos.choice.n8, f1_pos_srs_resource_n8);
f1ap_transmission_comb_pos_n8_t *pos_srs_resource_n8 = &pos_srs_res_tx_comb->choice.n8;
f1_pos_srs_resource_n8->combOffset_n8 = pos_srs_resource_n8->comb_offset_n8;
f1_pos_srs_resource_n8->cyclicShift_n8 = pos_srs_resource_n8->cyclic_shift_n8;
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", pos_srs_res_tx_comb->present);
break;
}
f1_pos_srs_resource->startPosition = pos_srs_resource->start_position;
switch (pos_srs_resource->nr_of_symbols) {
case F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1:
f1_pos_srs_resource->nrofSymbols = F1AP_PosSRSResource_Item__nrofSymbols_n1;
break;
case F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2:
f1_pos_srs_resource->nrofSymbols = F1AP_PosSRSResource_Item__nrofSymbols_n2;
break;
case F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4:
f1_pos_srs_resource->nrofSymbols = F1AP_PosSRSResource_Item__nrofSymbols_n4;
break;
case F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8:
f1_pos_srs_resource->nrofSymbols = F1AP_PosSRSResource_Item__nrofSymbols_n8;
break;
case F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12:
f1_pos_srs_resource->nrofSymbols = F1AP_PosSRSResource_Item__nrofSymbols_n12;
break;
default:
AssertFatal(false, "illegal number of symbols %d\n", pos_srs_resource->nr_of_symbols);
break;
}
f1_pos_srs_resource->freqDomainShift = pos_srs_resource->freq_domain_shift;
f1_pos_srs_resource->c_SRS = pos_srs_resource->c_srs;
switch (pos_srs_resource->group_or_sequence_hopping) {
case F1AP_GROUPORSEQUENCEHOPPING_NOTHING:
f1_pos_srs_resource->groupOrSequenceHopping = F1AP_PosSRSResource_Item__groupOrSequenceHopping_neither;
break;
case F1AP_GROUPORSEQUENCEHOPPING_GROUPHOPPING:
f1_pos_srs_resource->groupOrSequenceHopping = F1AP_PosSRSResource_Item__groupOrSequenceHopping_groupHopping;
break;
case F1AP_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING:
f1_pos_srs_resource->groupOrSequenceHopping = F1AP_PosSRSResource_Item__groupOrSequenceHopping_sequenceHopping;
break;
default:
AssertFatal(false, "illegal groupOrSequenceHopping %d\n", pos_srs_resource->group_or_sequence_hopping);
break;
}
f1ap_resource_type_pos_t *resource_type_pos = &pos_srs_resource->resource_type_pos;
F1AP_ResourceTypePos_t *f1_resourceTypePos = &f1_pos_srs_resource->resourceTypePos;
if (resource_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_NOTHING) {
f1_resourceTypePos->present = F1AP_ResourceTypePos_PR_NOTHING;
} else if (resource_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_PERIODIC) {
f1_resourceTypePos->present = F1AP_ResourceTypePos_PR_periodic;
asn1cCalloc(f1_resourceTypePos->choice.periodic, f1_pos_periodic);
switch (resource_type_pos->choice.periodic.periodicity) {
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot1;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot2;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot4;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot5;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot8;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot10;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot16;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot20;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot32;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot40;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot64;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot80;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot160;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot320;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot640;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot1280;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot2560;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot5120;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot10240;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot20480;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot40960;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920:
f1_pos_periodic->periodicity = F1AP_ResourceTypePeriodicPos__periodicity_slot81920;
break;
default:
AssertFatal(false, "illegal periodicity %d\n", resource_type_pos->choice.periodic.periodicity);
break;
}
f1_pos_periodic->offset = resource_type_pos->choice.periodic.offset;
} else if (resource_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT) {
f1_resourceTypePos->present = F1AP_ResourceTypePos_PR_semi_persistent;
asn1cCalloc(f1_resourceTypePos->choice.semi_persistent, f1_pos_semi_persistent);
switch (resource_type_pos->choice.semi_persistent.periodicity) {
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot1;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot2;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot4;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot5;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot8;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot10;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot16;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot20;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot32;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot40;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot64;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot80;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot160;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot320;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot640;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot1280;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot2560;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot5120;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot10240;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot20480;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot40960;
break;
case F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920:
f1_pos_semi_persistent->periodicity = F1AP_ResourceTypeSemi_persistentPos__periodicity_slot81920;
break;
default:
AssertFatal(false, "illegal periodicity %d\n", resource_type_pos->choice.semi_persistent.periodicity);
break;
}
f1_pos_semi_persistent->offset = resource_type_pos->choice.semi_persistent.offset;
} else if (resource_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_APERIODIC) {
f1_resourceTypePos->present = F1AP_ResourceTypePos_PR_aperiodic;
asn1cCalloc(f1_resourceTypePos->choice.aperiodic, f1_pos_aperiodic);
f1_pos_aperiodic->slotOffset = resource_type_pos->choice.aperiodic.slot_offset;
} else {
AssertFatal(false, "illegal resourceType %d\n", resource_type_pos->present);
}
f1_pos_srs_resource->sequenceId = pos_srs_resource->sequence_id;
}
}
// optional: srs_resource_set_list
if (in_config->srs_resource_set_list) {
f1ap_srs_resource_set_list_t *srs_resource_set_list = in_config->srs_resource_set_list;
uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length;
asn1cCalloc(out_config.sRSResourceSet_List, f1_sRSResourceSet_List);
for (int i = 0; i < srs_resource_set_list_length; i++) {
asn1cSequenceAdd(f1_sRSResourceSet_List->list, F1AP_SRSResourceSet_t, f1_srs_resource_set);
f1ap_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i];
f1_srs_resource_set->sRSResourceSetID = srs_resource_set->srs_resource_set_id;
uint8_t srs_resource_id_list_length = srs_resource_set->srs_resource_id_list.srs_resource_id_list_length;
for (int j = 0; j < srs_resource_id_list_length; j++) {
asn1cSequenceAdd(f1_srs_resource_set->sRSResourceID_List.list, F1AP_SRSResourceID_t, f1_srs_resource_id);
*f1_srs_resource_id = srs_resource_set->srs_resource_id_list.srs_resource_id[j];
}
F1AP_ResourceSetType_t *f1_resourceSetType = &f1_srs_resource_set->resourceSetType;
f1ap_resource_set_type_t *resource_set_type = &srs_resource_set->resource_set_type;
switch (resource_set_type->present) {
case F1AP_RESOURCE_SET_TYPE_PR_NOTHING:
f1_resourceSetType->present = F1AP_ResourceSetType_PR_NOTHING;
break;
case F1AP_RESOURCE_SET_TYPE_PR_PERIODIC:
f1_resourceSetType->present = F1AP_ResourceSetType_PR_periodic;
asn1cCalloc(f1_resourceSetType->choice.periodic, f1_periodic_set_type);
f1_periodic_set_type->periodicSet = resource_set_type->choice.periodic;
break;
case F1AP_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT:
f1_resourceSetType->present = F1AP_ResourceSetType_PR_semi_persistent;
asn1cCalloc(f1_resourceSetType->choice.semi_persistent, f1_semi_persistent_set_type);
f1_semi_persistent_set_type->semi_persistentSet = resource_set_type->choice.semi_persistent;
break;
case F1AP_RESOURCE_SET_TYPE_PR_APERIODIC:
f1_resourceSetType->present = F1AP_ResourceSetType_PR_aperiodic;
asn1cCalloc(f1_resourceSetType->choice.aperiodic, f1_aperiodic_set_type);
f1_aperiodic_set_type->sRSResourceTrigger_List = resource_set_type->choice.aperiodic.srs_resource_trigger;
f1_aperiodic_set_type->slotoffset = resource_set_type->choice.aperiodic.slot_offset;
break;
default:
AssertFatal(false, "illegal resource set type %d\n", resource_set_type->present);
break;
}
}
}
// optional: pos_srs_resource_set_list
if (in_config->pos_srs_resource_set_list) {
f1ap_pos_srs_resource_set_list_t *pos_srs_resource_set_list = in_config->pos_srs_resource_set_list;
uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length;
asn1cCalloc(out_config.posSRSResourceSet_List, f1_posSRSResourceSet_List);
for (int i = 0; i < pos_srs_resource_set_list_length; i++) {
asn1cSequenceAdd(f1_posSRSResourceSet_List->list, F1AP_PosSRSResourceSet_Item_t, f1_pos_srs_resource_set);
f1ap_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i];
f1_pos_srs_resource_set->possrsResourceSetID = pos_srs_resource_set->pos_srs_resource_set_id;
uint8_t pos_srs_resource_id_list_length = pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length;
for (int j = 0; j < pos_srs_resource_id_list_length; j++) {
asn1cSequenceAdd(f1_pos_srs_resource_set->possRSResourceID_List.list, F1AP_SRSPosResourceID_t, f1_pos_srs_resource_id);
*f1_pos_srs_resource_id = pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j];
}
F1AP_PosResourceSetType_t *f1_posresourceSetType = &f1_pos_srs_resource_set->posresourceSetType;
f1ap_pos_resource_set_type_t *pos_resource_set_type = &pos_srs_resource_set->pos_resource_set_type;
switch (pos_resource_set_type->present) {
case F1AP_POS_RESOURCE_SET_TYPE_PR_NOTHING:
f1_posresourceSetType->present = F1AP_PosResourceSetType_PR_NOTHING;
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_PERIODIC:
f1_posresourceSetType->present = F1AP_PosResourceSetType_PR_periodic;
asn1cCalloc(f1_posresourceSetType->choice.periodic, f1_pos_periodic_set_type);
f1_pos_periodic_set_type->posperiodicSet = pos_resource_set_type->choice.periodic;
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT:
f1_posresourceSetType->present = F1AP_PosResourceSetType_PR_semi_persistent;
asn1cCalloc(f1_posresourceSetType->choice.semi_persistent, f1_pos_semi_persistent_set_type);
f1_pos_semi_persistent_set_type->possemi_persistentSet = pos_resource_set_type->choice.semi_persistent;
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_APERIODIC:
f1_posresourceSetType->present = F1AP_PosResourceSetType_PR_aperiodic;
asn1cCalloc(f1_posresourceSetType->choice.aperiodic, f1_pos_aperiodic_set_type);
f1_pos_aperiodic_set_type->sRSResourceTrigger_List = pos_resource_set_type->choice.srs_resource;
break;
default:
AssertFatal(false, "illegal resource set type pos %d\n", pos_resource_set_type->present);
break;
}
}
}
return out_config;
}
static F1AP_SRSCarrier_List_Item_t encode_srs_carrier_list_item(const f1ap_srs_carrier_list_item_t *in_item)
{
F1AP_SRSCarrier_List_Item_t out_item = {0};
// pointA
out_item.pointA = in_item->pointA;
// Uplink Channel BW-PerSCS-List
const f1ap_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &in_item->uplink_channel_bw_per_scs_list;
F1AP_UplinkChannelBW_PerSCS_List_t *f1_uplink_channel_bw_per_scs_list = &out_item.uplinkChannelBW_PerSCS_List;
uint32_t scs_specific_carrier_list_length = uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length;
for (int i = 0; i < scs_specific_carrier_list_length; i++) {
asn1cSequenceAdd(f1_uplink_channel_bw_per_scs_list->list, F1AP_SCS_SpecificCarrier_t, f1_scs_specific_carrier);
f1ap_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i];
// offset to carrier
f1_scs_specific_carrier->offsetToCarrier = scs_specific_carrier->offset_to_carrier;
// subcarrier spacing
switch (scs_specific_carrier->subcarrier_spacing) {
case F1AP_SUBCARRIER_SPACING_15KHZ:
f1_scs_specific_carrier->subcarrierSpacing = F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz15;
break;
case F1AP_SUBCARRIER_SPACING_30KHZ:
f1_scs_specific_carrier->subcarrierSpacing = F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz30;
break;
case F1AP_SUBCARRIER_SPACING_60KHZ:
f1_scs_specific_carrier->subcarrierSpacing = F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz60;
break;
case F1AP_SUBCARRIER_SPACING_120KHZ:
f1_scs_specific_carrier->subcarrierSpacing = F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz120;
break;
default:
AssertFatal(false, "illegal subcarrier spacing %d\n", scs_specific_carrier->subcarrier_spacing);
break;
}
// carrier bandwidth
f1_scs_specific_carrier->carrierBandwidth = scs_specific_carrier->carrier_bandwidth;
}
// Active UL BWP
F1AP_ActiveULBWP_t *f1_active_ul_bwp = &out_item.activeULBWP;
const f1ap_active_ul_bwp_t *active_ul_bwp = &in_item->active_ul_bwp;
// location and bandwidth
f1_active_ul_bwp->locationAndBandwidth = active_ul_bwp->location_and_bandwidth;
// subcarrier spacing
switch (active_ul_bwp->subcarrier_spacing) {
case F1AP_SUBCARRIER_SPACING_15KHZ:
f1_active_ul_bwp->subcarrierSpacing = F1AP_ActiveULBWP__subcarrierSpacing_kHz15;
break;
case F1AP_SUBCARRIER_SPACING_30KHZ:
f1_active_ul_bwp->subcarrierSpacing = F1AP_ActiveULBWP__subcarrierSpacing_kHz30;
break;
case F1AP_SUBCARRIER_SPACING_60KHZ:
f1_active_ul_bwp->subcarrierSpacing = F1AP_ActiveULBWP__subcarrierSpacing_kHz60;
break;
case F1AP_SUBCARRIER_SPACING_120KHZ:
f1_active_ul_bwp->subcarrierSpacing = F1AP_ActiveULBWP__subcarrierSpacing_kHz120;
break;
default:
AssertFatal(false, "illegal subcarrier spacing %d\n", active_ul_bwp->subcarrier_spacing);
break;
}
// cyclic prefix
if (active_ul_bwp->cyclic_prefix == F1AP_CP_TYPE_NORMAL)
f1_active_ul_bwp->cyclicPrefix = F1AP_ActiveULBWP__cyclicPrefix_normal;
else
f1_active_ul_bwp->cyclicPrefix = F1AP_ActiveULBWP__cyclicPrefix_extended;
// Tx Direct Current Location
f1_active_ul_bwp->txDirectCurrentLocation = active_ul_bwp->tx_direct_current_location;
// SRS Config
const f1ap_srs_config_t *sRSConfig = &active_ul_bwp->srs_config;
f1_active_ul_bwp->sRSConfig = encode_srs_config(sRSConfig);
return out_item;
}
static F1AP_SRSCarrier_List_t encode_srs_carrier_list(const f1ap_srs_carrier_list_t *in_list)
{
F1AP_SRSCarrier_List_t out_list = {0};
uint32_t list_len = in_list->srs_carrier_list_length;
for (int i = 0; i < list_len; i++) {
asn1cSequenceAdd(out_list.list, F1AP_SRSCarrier_List_Item_t, out_item);
f1ap_srs_carrier_list_item_t *in_item = &in_list->srs_carrier_list_item[i];
*out_item = encode_srs_carrier_list_item(in_item);
}
return out_list;
}
static void decode_srs_config(const F1AP_SRSConfig_t *in_config, f1ap_srs_config_t *out_config)
{
// optional: sRSResource_List
if (in_config->sRSResource_List) {
out_config->srs_resource_list = calloc_or_fail(1, sizeof(*out_config->srs_resource_list));
f1ap_srs_resource_list_t *srs_resource_list = out_config->srs_resource_list;
uint32_t srs_resource_list_length = in_config->sRSResource_List->list.count;
srs_resource_list->srs_resource_list_length = srs_resource_list_length;
srs_resource_list->srs_resource = calloc_or_fail(srs_resource_list_length, sizeof(*srs_resource_list->srs_resource));
for (int i = 0; i < srs_resource_list_length; i++) {
f1ap_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i];
F1AP_SRSResource_t *f1_srs_resource = in_config->sRSResource_List->list.array[i];
srs_resource->srs_resource_id = f1_srs_resource->sRSResourceID;
switch (f1_srs_resource->nrofSRS_Ports) {
case F1AP_SRSResource__nrofSRS_Ports_port1:
srs_resource->nr_of_srs_ports = F1AP_SRS_NUMBER_OF_PORTS_N1;
break;
case F1AP_SRSResource__nrofSRS_Ports_ports2:
srs_resource->nr_of_srs_ports = F1AP_SRS_NUMBER_OF_PORTS_N2;
break;
case F1AP_SRSResource__nrofSRS_Ports_ports4:
srs_resource->nr_of_srs_ports = F1AP_SRS_NUMBER_OF_PORTS_N4;
break;
default:
AssertFatal(false, "illegal number of srs ports %ld\n", f1_srs_resource->nrofSRS_Ports);
break;
}
f1ap_transmission_comb_t *srs_tx_comb = &srs_resource->transmission_comb;
F1AP_TransmissionComb_t *f1_srs_tx_comb = &f1_srs_resource->transmissionComb;
switch (f1_srs_tx_comb->present) {
case F1AP_TransmissionComb_PR_NOTHING:
srs_tx_comb->present = F1AP_TRANSMISSION_COMB_PR_NOTHING;
break;
case F1AP_TransmissionComb_PR_n2:
srs_tx_comb->present = F1AP_TRANSMISSION_COMB_PR_N2;
srs_tx_comb->choice.n2.comb_offset_n2 = f1_srs_tx_comb->choice.n2->combOffset_n2;
srs_tx_comb->choice.n2.cyclic_shift_n2 = f1_srs_tx_comb->choice.n2->cyclicShift_n2;
break;
case F1AP_TransmissionComb_PR_n4:
srs_tx_comb->present = F1AP_TRANSMISSION_COMB_PR_N4;
srs_tx_comb->choice.n4.comb_offset_n4 = f1_srs_tx_comb->choice.n4->combOffset_n4;
srs_tx_comb->choice.n4.cyclic_shift_n4 = f1_srs_tx_comb->choice.n4->cyclicShift_n4;
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", f1_srs_tx_comb->present);
break;
}
srs_resource->start_position = f1_srs_resource->startPosition;
switch (f1_srs_resource->nrofSymbols) {
case F1AP_SRSResource__nrofSymbols_n1:
srs_resource->nr_of_symbols = F1AP_SRS_NUMBER_OF_SYMBOLS_N1;
break;
case F1AP_SRSResource__nrofSymbols_n2:
srs_resource->nr_of_symbols = F1AP_SRS_NUMBER_OF_SYMBOLS_N2;
break;
case F1AP_SRSResource__nrofSymbols_n4:
srs_resource->nr_of_symbols = F1AP_SRS_NUMBER_OF_SYMBOLS_N4;
break;
default:
AssertFatal(false, "illegal number of symbols %ld\n", f1_srs_resource->nrofSymbols);
break;
}
switch (f1_srs_resource->repetitionFactor) {
case F1AP_SRSResource__repetitionFactor_n1:
srs_resource->repetition_factor = F1AP_SRS_REPETITION_FACTOR_RF1;
break;
case F1AP_SRSResource__repetitionFactor_n2:
srs_resource->repetition_factor = F1AP_SRS_REPETITION_FACTOR_RF2;
break;
case F1AP_SRSResource__repetitionFactor_n4:
srs_resource->repetition_factor = F1AP_SRS_REPETITION_FACTOR_RF4;
break;
default:
AssertFatal(false, "illegal repetition factor %ld\n", f1_srs_resource->repetitionFactor);
break;
}
srs_resource->freq_domain_position = f1_srs_resource->freqDomainPosition;
srs_resource->freq_domain_shift = f1_srs_resource->freqDomainShift;
srs_resource->c_srs = f1_srs_resource->c_SRS;
srs_resource->b_srs = f1_srs_resource->b_SRS;
srs_resource->b_hop = f1_srs_resource->b_hop;
switch (f1_srs_resource->groupOrSequenceHopping) {
case F1AP_SRSResource__groupOrSequenceHopping_neither:
srs_resource->group_or_sequence_hopping = F1AP_GROUPORSEQUENCEHOPPING_NOTHING;
break;
case F1AP_SRSResource__groupOrSequenceHopping_groupHopping:
srs_resource->group_or_sequence_hopping = F1AP_GROUPORSEQUENCEHOPPING_GROUPHOPPING;
break;
case F1AP_SRSResource__groupOrSequenceHopping_sequenceHopping:
srs_resource->group_or_sequence_hopping = F1AP_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING;
break;
default:
AssertFatal(false, "illegal groupOrSequenceHopping %ld\n", f1_srs_resource->groupOrSequenceHopping);
break;
}
F1AP_ResourceType_t *f1_resourceType = &f1_srs_resource->resourceType;
f1ap_resource_type_t *resource_type = &srs_resource->resource_type;
if (f1_resourceType->present == F1AP_ResourceType_PR_NOTHING) {
resource_type->present = F1AP_RESOURCE_TYPE_PR_NOTHING;
} else if (f1_resourceType->present == F1AP_ResourceType_PR_periodic) {
resource_type->present = F1AP_RESOURCE_TYPE_PR_PERIODIC;
f1ap_resource_type_periodic_t *periodic = &resource_type->choice.periodic;
switch (f1_resourceType->choice.periodic->periodicity) {
case F1AP_ResourceTypePeriodic__periodicity_slot1:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot2:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot4:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot5:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot8:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot10:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot16:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot20:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot32:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot40:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot64:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot80:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot160:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot320:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot640:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot1280:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280;
break;
case F1AP_ResourceTypePeriodic__periodicity_slot2560:
periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560;
break;
default:
AssertFatal(false, "illegal periodicity %ld\n", f1_resourceType->choice.periodic->periodicity);
break;
}
periodic->offset = f1_resourceType->choice.periodic->offset;
} else if (f1_resourceType->present == F1AP_ResourceType_PR_semi_persistent) {
resource_type->present = F1AP_RESOURCE_TYPE_PR_SEMI_PERSISTENT;
f1ap_resource_type_semi_persistent_t *semi_persistent = &resource_type->choice.semi_persistent;
switch (f1_resourceType->choice.semi_persistent->periodicity) {
case F1AP_ResourceTypeSemi_persistent__periodicity_slot1:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot2:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot4:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot5:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot8:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot10:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot16:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot20:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot32:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot40:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot64:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot80:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot160:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot320:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot640:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot1280:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280;
break;
case F1AP_ResourceTypeSemi_persistent__periodicity_slot2560:
semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560;
break;
default:
AssertFatal(false, "illegal periodicity %ld\n", f1_resourceType->choice.semi_persistent->periodicity);
break;
}
semi_persistent->offset = f1_resourceType->choice.semi_persistent->offset;
} else if (f1_resourceType->present == F1AP_ResourceType_PR_aperiodic) {
resource_type->present = F1AP_RESOURCE_TYPE_PR_APERIODIC;
resource_type->choice.aperiodic = f1_resourceType->choice.aperiodic->aperiodicResourceType;
} else {
AssertFatal(false, "illegal resourceType %d\n", f1_resourceType->present);
}
srs_resource->sequence_id = f1_srs_resource->sequenceId;
}
}
// optional: posSRSResource_List
if (in_config->posSRSResource_List) {
out_config->pos_srs_resource_list = calloc_or_fail(1, sizeof(*out_config->pos_srs_resource_list));
f1ap_pos_srs_resource_list_t *pos_srs_resource_list = out_config->pos_srs_resource_list;
uint32_t pos_srs_resource_list_length = in_config->posSRSResource_List->list.count;
pos_srs_resource_list->pos_srs_resource_list_length = pos_srs_resource_list_length;
pos_srs_resource_list->pos_srs_resource_item =
calloc_or_fail(pos_srs_resource_list_length, sizeof(*pos_srs_resource_list->pos_srs_resource_item));
for (int i = 0; i < pos_srs_resource_list_length; i++) {
F1AP_PosSRSResource_Item_t *f1_pos_srs_resource = in_config->posSRSResource_List->list.array[i];
f1ap_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i];
pos_srs_resource->srs_pos_resource_id = f1_pos_srs_resource->srs_PosResourceId;
F1AP_TransmissionCombPos_t *f1_tx_comb_pos = &f1_pos_srs_resource->transmissionCombPos;
f1ap_transmission_comb_pos_t *tx_comb_pos = &pos_srs_resource->transmission_comb_pos;
switch (f1_tx_comb_pos->present) {
case F1AP_TransmissionCombPos_PR_NOTHING:
tx_comb_pos->present = F1AP_TRANSMISSION_COMB_POS_PR_NOTHING;
break;
case F1AP_TransmissionCombPos_PR_n2:
tx_comb_pos->present = F1AP_TRANSMISSION_COMB_POS_PR_N2;
tx_comb_pos->choice.n2.comb_offset_n2 = f1_tx_comb_pos->choice.n2->combOffset_n2;
tx_comb_pos->choice.n2.cyclic_shift_n2 = f1_tx_comb_pos->choice.n2->cyclicShift_n2;
break;
case F1AP_TransmissionCombPos_PR_n4:
tx_comb_pos->present = F1AP_TRANSMISSION_COMB_POS_PR_N4;
tx_comb_pos->choice.n4.comb_offset_n4 = f1_tx_comb_pos->choice.n4->combOffset_n4;
tx_comb_pos->choice.n4.cyclic_shift_n4 = f1_tx_comb_pos->choice.n4->cyclicShift_n4;
break;
case F1AP_TransmissionCombPos_PR_n8:
tx_comb_pos->present = F1AP_TRANSMISSION_COMB_POS_PR_N8;
tx_comb_pos->choice.n8.comb_offset_n8 = f1_tx_comb_pos->choice.n8->combOffset_n8;
tx_comb_pos->choice.n8.cyclic_shift_n8 = f1_tx_comb_pos->choice.n8->cyclicShift_n8;
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", f1_tx_comb_pos->present);
break;
}
pos_srs_resource->start_position = f1_pos_srs_resource->startPosition;
switch (f1_pos_srs_resource->nrofSymbols) {
case F1AP_PosSRSResource_Item__nrofSymbols_n1:
pos_srs_resource->nr_of_symbols = F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1;
break;
case F1AP_PosSRSResource_Item__nrofSymbols_n2:
pos_srs_resource->nr_of_symbols = F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2;
break;
case F1AP_PosSRSResource_Item__nrofSymbols_n4:
pos_srs_resource->nr_of_symbols = F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4;
break;
case F1AP_PosSRSResource_Item__nrofSymbols_n8:
pos_srs_resource->nr_of_symbols = F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8;
break;
case F1AP_PosSRSResource_Item__nrofSymbols_n12:
pos_srs_resource->nr_of_symbols = F1AP_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12;
break;
default:
AssertFatal(false, "illegal number of symbols %ld\n", f1_pos_srs_resource->nrofSymbols);
break;
}
pos_srs_resource->freq_domain_shift = f1_pos_srs_resource->freqDomainShift;
pos_srs_resource->c_srs = f1_pos_srs_resource->c_SRS;
switch (f1_pos_srs_resource->groupOrSequenceHopping) {
case F1AP_PosSRSResource_Item__groupOrSequenceHopping_neither:
pos_srs_resource->group_or_sequence_hopping = F1AP_GROUPORSEQUENCEHOPPING_NOTHING;
break;
case F1AP_PosSRSResource_Item__groupOrSequenceHopping_groupHopping:
pos_srs_resource->group_or_sequence_hopping = F1AP_GROUPORSEQUENCEHOPPING_GROUPHOPPING;
break;
case F1AP_PosSRSResource_Item__groupOrSequenceHopping_sequenceHopping:
pos_srs_resource->group_or_sequence_hopping = F1AP_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING;
break;
default:
AssertFatal(false, "illegal groupOrSequenceHopping %ld\n", f1_pos_srs_resource->groupOrSequenceHopping);
break;
}
F1AP_ResourceTypePos_t *f1_res_type_pos = &f1_pos_srs_resource->resourceTypePos;
f1ap_resource_type_pos_t *res_type_pos = &pos_srs_resource->resource_type_pos;
if (f1_res_type_pos->present == F1AP_ResourceTypePos_PR_NOTHING) {
res_type_pos->present = F1AP_RESOURCE_TYPE_POS_PR_NOTHING;
} else if (f1_res_type_pos->present == F1AP_ResourceTypePos_PR_periodic) {
res_type_pos->present = F1AP_RESOURCE_TYPE_POS_PR_PERIODIC;
f1ap_resource_type_periodic_pos_t *pos_periodic = &res_type_pos->choice.periodic;
switch (f1_res_type_pos->choice.periodic->periodicity) {
case F1AP_ResourceTypePeriodicPos__periodicity_slot1:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot2:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot4:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot5:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot8:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot10:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot16:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot20:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot32:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot40:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot64:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot80:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot160:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot320:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot640:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot1280:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot2560:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot5120:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot10240:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot20480:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot40960:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960;
break;
case F1AP_ResourceTypePeriodicPos__periodicity_slot81920:
pos_periodic->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920;
break;
default:
AssertFatal(false, "illegal periodicity %ld\n", f1_res_type_pos->choice.periodic->periodicity);
break;
}
pos_periodic->offset = f1_res_type_pos->choice.periodic->offset;
} else if (f1_res_type_pos->present == F1AP_ResourceTypePos_PR_semi_persistent) {
res_type_pos->present = F1AP_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT;
f1ap_resource_type_semi_persistent_pos_t *pos_semi_persistent = &res_type_pos->choice.semi_persistent;
switch (f1_res_type_pos->choice.semi_persistent->periodicity) {
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot1:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot2:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot4:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot5:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot8:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot10:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot16:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot20:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot32:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot40:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot64:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot80:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot160:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot320:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot640:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot1280:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot2560:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot5120:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot10240:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot20480:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot40960:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960;
break;
case F1AP_ResourceTypeSemi_persistentPos__periodicity_slot81920:
pos_semi_persistent->periodicity = F1AP_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920;
break;
default:
AssertFatal(false, "illegal periodicity %ld\n", f1_res_type_pos->choice.semi_persistent->periodicity);
break;
}
pos_semi_persistent->offset = f1_res_type_pos->choice.semi_persistent->offset;
} else if (f1_res_type_pos->present == F1AP_ResourceTypePos_PR_aperiodic) {
res_type_pos->present = F1AP_RESOURCE_TYPE_POS_PR_APERIODIC;
res_type_pos->choice.aperiodic.slot_offset = f1_res_type_pos->choice.aperiodic->slotOffset;
} else {
AssertFatal(false, "illegal resourceType %d\n", f1_res_type_pos->present);
}
pos_srs_resource->sequence_id = f1_pos_srs_resource->sequenceId;
}
}
// optional: sRSResourceSet_List
if (in_config->sRSResourceSet_List) {
out_config->srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config->srs_resource_set_list));
f1ap_srs_resource_set_list_t *srs_resource_set_list = out_config->srs_resource_set_list;
uint32_t srs_resource_set_list_length = in_config->sRSResourceSet_List->list.count;
srs_resource_set_list->srs_resource_set_list_length = srs_resource_set_list_length;
srs_resource_set_list->srs_resource_set =
calloc_or_fail(srs_resource_set_list_length, sizeof(*srs_resource_set_list->srs_resource_set));
for (int i = 0; i < srs_resource_set_list_length; i++) {
F1AP_SRSResourceSet_t *f1_srs_resource_set = in_config->sRSResourceSet_List->list.array[i];
f1ap_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i];
srs_resource_set->srs_resource_set_id = f1_srs_resource_set->sRSResourceSetID;
uint8_t srs_resource_id_list_length = f1_srs_resource_set->sRSResourceID_List.list.count;
srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length;
srs_resource_set->srs_resource_id_list.srs_resource_id =
calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id));
for (int j = 0; j < srs_resource_id_list_length; j++) {
F1AP_SRSResourceID_t *f1_srs_resource_id = f1_srs_resource_set->sRSResourceID_List.list.array[j];
srs_resource_set->srs_resource_id_list.srs_resource_id[j] = *f1_srs_resource_id;
}
F1AP_ResourceSetType_t *f1_res_set_type = &f1_srs_resource_set->resourceSetType;
f1ap_resource_set_type_t *res_set_type = &srs_resource_set->resource_set_type;
switch (f1_res_set_type->present) {
case F1AP_ResourceSetType_PR_NOTHING:
res_set_type->present = F1AP_RESOURCE_SET_TYPE_PR_NOTHING;
break;
case F1AP_ResourceSetType_PR_periodic:
res_set_type->present = F1AP_RESOURCE_SET_TYPE_PR_PERIODIC;
res_set_type->choice.periodic = f1_res_set_type->choice.periodic->periodicSet;
break;
case F1AP_ResourceSetType_PR_semi_persistent:
res_set_type->present = F1AP_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT;
res_set_type->choice.semi_persistent = f1_res_set_type->choice.semi_persistent->semi_persistentSet;
break;
case F1AP_ResourceSetType_PR_aperiodic:
res_set_type->present = F1AP_RESOURCE_SET_TYPE_PR_APERIODIC;
res_set_type->choice.aperiodic.srs_resource_trigger = f1_res_set_type->choice.aperiodic->sRSResourceTrigger_List;
res_set_type->choice.aperiodic.slot_offset = f1_res_set_type->choice.aperiodic->slotoffset;
break;
default:
AssertFatal(false, "illegal resource set type %d\n", f1_res_set_type->present);
break;
}
}
}
// optional: posSRSResourceSet_List
if (in_config->posSRSResourceSet_List) {
out_config->pos_srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config->pos_srs_resource_set_list));
f1ap_pos_srs_resource_set_list_t *pos_srs_resource_set_list = out_config->pos_srs_resource_set_list;
uint32_t pos_srs_resource_set_list_length = in_config->posSRSResourceSet_List->list.count;
pos_srs_resource_set_list->pos_srs_resource_set_list_length = pos_srs_resource_set_list_length;
pos_srs_resource_set_list->pos_srs_resource_set_item =
calloc_or_fail(pos_srs_resource_set_list_length, sizeof(*pos_srs_resource_set_list->pos_srs_resource_set_item));
for (int i = 0; i < pos_srs_resource_set_list_length; i++) {
F1AP_PosSRSResourceSet_Item_t *f1_pos_srs_resource_set = in_config->posSRSResourceSet_List->list.array[i];
f1ap_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i];
pos_srs_resource_set->pos_srs_resource_set_id = f1_pos_srs_resource_set->possrsResourceSetID;
uint8_t pos_srs_resource_id_list_length = f1_pos_srs_resource_set->possRSResourceID_List.list.count;
pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length;
pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id =
calloc_or_fail(pos_srs_resource_id_list_length,
sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id));
for (int j = 0; j < pos_srs_resource_id_list_length; j++) {
F1AP_SRSPosResourceID_t *f1_pos_srs_resource_id = f1_pos_srs_resource_set->possRSResourceID_List.list.array[j];
pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j] = *f1_pos_srs_resource_id;
}
F1AP_PosResourceSetType_t *f1_pos_res_set_type = &f1_pos_srs_resource_set->posresourceSetType;
f1ap_pos_resource_set_type_t *pos_res_set_type = &pos_srs_resource_set->pos_resource_set_type;
switch (f1_pos_res_set_type->present) {
case F1AP_PosResourceSetType_PR_NOTHING:
pos_res_set_type->present = F1AP_POS_RESOURCE_SET_TYPE_PR_NOTHING;
break;
case F1AP_PosResourceSetType_PR_periodic:
pos_res_set_type->present = F1AP_POS_RESOURCE_SET_TYPE_PR_PERIODIC;
pos_res_set_type->choice.periodic = f1_pos_res_set_type->choice.periodic->posperiodicSet;
break;
case F1AP_PosResourceSetType_PR_semi_persistent:
pos_res_set_type->present = F1AP_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT;
pos_res_set_type->choice.semi_persistent = f1_pos_res_set_type->choice.semi_persistent->possemi_persistentSet;
break;
case F1AP_PosResourceSetType_PR_aperiodic:
pos_res_set_type->present = F1AP_POS_RESOURCE_SET_TYPE_PR_APERIODIC;
pos_res_set_type->choice.srs_resource = f1_pos_res_set_type->choice.aperiodic->sRSResourceTrigger_List;
break;
default:
AssertFatal(false, "illegal resource set type pos %d\n", f1_pos_res_set_type->present);
break;
}
}
}
}
static void decode_srs_carrier_list_item(const F1AP_SRSCarrier_List_Item_t *in_item, f1ap_srs_carrier_list_item_t *out_item)
{
// pointA
out_item->pointA = in_item->pointA;
// Uplink Channel BW-PerSCS-List
f1ap_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &out_item->uplink_channel_bw_per_scs_list;
const F1AP_UplinkChannelBW_PerSCS_List_t *f1_uplink_channel_bw_per_scs_list = &in_item->uplinkChannelBW_PerSCS_List;
uint32_t scs_specific_carrier_list_length = f1_uplink_channel_bw_per_scs_list->list.count;
AssertFatal(scs_specific_carrier_list_length > 0, "Atleast 1 uplink channel bw per scs list should be present\n");
uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length = scs_specific_carrier_list_length;
uplink_channel_bw_per_scs_list->scs_specific_carrier =
calloc_or_fail(scs_specific_carrier_list_length, sizeof(*uplink_channel_bw_per_scs_list->scs_specific_carrier));
for (int i = 0; i < scs_specific_carrier_list_length; i++) {
F1AP_SCS_SpecificCarrier_t *f1_scs_specific_carrier = f1_uplink_channel_bw_per_scs_list->list.array[i];
f1ap_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i];
// offset to carrier
scs_specific_carrier->offset_to_carrier = f1_scs_specific_carrier->offsetToCarrier;
// subcarrier spacing
switch (f1_scs_specific_carrier->subcarrierSpacing) {
case F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz15:
scs_specific_carrier->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_15KHZ;
break;
case F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz30:
scs_specific_carrier->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_30KHZ;
break;
case F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz60:
scs_specific_carrier->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_60KHZ;
break;
case F1AP_SCS_SpecificCarrier__subcarrierSpacing_kHz120:
scs_specific_carrier->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_120KHZ;
break;
default:
AssertFatal(false, "illegal subcarrier spacing %ld\n", f1_scs_specific_carrier->subcarrierSpacing);
break;
}
// carrier bandwidth
scs_specific_carrier->carrier_bandwidth = f1_scs_specific_carrier->carrierBandwidth;
}
// Active UL BWP
const F1AP_ActiveULBWP_t *f1_active_ul_bwp = &in_item->activeULBWP;
f1ap_active_ul_bwp_t *active_ul_bwp = &out_item->active_ul_bwp;
// location and bandwidth
active_ul_bwp->location_and_bandwidth = f1_active_ul_bwp->locationAndBandwidth;
// subcarrier spacing
switch (f1_active_ul_bwp->subcarrierSpacing) {
case F1AP_ActiveULBWP__subcarrierSpacing_kHz15:
active_ul_bwp->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_15KHZ;
break;
case F1AP_ActiveULBWP__subcarrierSpacing_kHz30:
active_ul_bwp->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_30KHZ;
break;
case F1AP_ActiveULBWP__subcarrierSpacing_kHz60:
active_ul_bwp->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_60KHZ;
break;
case F1AP_ActiveULBWP__subcarrierSpacing_kHz120:
active_ul_bwp->subcarrier_spacing = F1AP_SUBCARRIER_SPACING_120KHZ;
break;
default:
AssertFatal(false, "illegal subcarrier spacing %ld\n", f1_active_ul_bwp->subcarrierSpacing);
break;
}
// cyclic prefix
if (f1_active_ul_bwp->cyclicPrefix == F1AP_ActiveULBWP__cyclicPrefix_normal)
active_ul_bwp->cyclic_prefix = F1AP_CP_TYPE_NORMAL;
else
active_ul_bwp->cyclic_prefix = F1AP_CP_TYPE_EXTENDED;
// Tx Direct Current Location
active_ul_bwp->tx_direct_current_location = f1_active_ul_bwp->txDirectCurrentLocation;
// SRS Config
const F1AP_SRSConfig_t *f1_sRSConfig = &f1_active_ul_bwp->sRSConfig;
f1ap_srs_config_t *sRSConfig = &active_ul_bwp->srs_config;
decode_srs_config(f1_sRSConfig, sRSConfig);
}
static void decode_srs_carrier_list(f1ap_srs_carrier_list_t *out_list, const F1AP_SRSCarrier_List_t *in_list)
{
uint32_t list_len = in_list->list.count;
AssertFatal(list_len > 0, "atleast 1 SRS carrier list must be present");
out_list->srs_carrier_list_length = list_len;
out_list->srs_carrier_list_item = calloc_or_fail(list_len, sizeof(*out_list->srs_carrier_list_item));
for (int i = 0; i < list_len; i++) {
F1AP_SRSCarrier_List_Item_t *in_item = in_list->list.array[i];
f1ap_srs_carrier_list_item_t *out_item = &out_list->srs_carrier_list_item[i];
decode_srs_carrier_list_item(in_item, out_item);
}
}
static f1ap_srs_config_t cp_srs_config(const f1ap_srs_config_t *in_config)
{
f1ap_srs_config_t out_config = {0};
// optional: srs_resource_list
if (in_config->srs_resource_list) {
f1ap_srs_resource_list_t *srs_resource_list = in_config->srs_resource_list;
out_config.srs_resource_list = calloc_or_fail(1, sizeof(*out_config.srs_resource_list));
f1ap_srs_resource_list_t *f1_srs_resource_list = out_config.srs_resource_list;
uint32_t srs_resource_list_length = srs_resource_list->srs_resource_list_length;
f1_srs_resource_list->srs_resource_list_length = srs_resource_list_length;
f1_srs_resource_list->srs_resource = calloc_or_fail(srs_resource_list_length, sizeof(*f1_srs_resource_list->srs_resource));
for (int i = 0; i < srs_resource_list_length; i++) {
f1ap_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i];
f1ap_srs_resource_t *f1_srs_resource = &f1_srs_resource_list->srs_resource[i];
f1_srs_resource->srs_resource_id = srs_resource->srs_resource_id;
f1_srs_resource->nr_of_srs_ports = srs_resource->nr_of_srs_ports;
f1ap_transmission_comb_t *f1_srs_tx_comb = &f1_srs_resource->transmission_comb;
f1ap_transmission_comb_t *srs_tx_comb = &srs_resource->transmission_comb;
f1_srs_tx_comb->present = srs_tx_comb->present;
switch (srs_tx_comb->present) {
case F1AP_TRANSMISSION_COMB_PR_NOTHING:
// nothing to copy
break;
case F1AP_TRANSMISSION_COMB_PR_N2:
f1_srs_tx_comb->choice.n2.comb_offset_n2 = srs_tx_comb->choice.n2.comb_offset_n2;
f1_srs_tx_comb->choice.n2.cyclic_shift_n2 = srs_tx_comb->choice.n2.cyclic_shift_n2;
break;
case F1AP_TRANSMISSION_COMB_PR_N4:
f1_srs_tx_comb->choice.n4.comb_offset_n4 = srs_tx_comb->choice.n4.comb_offset_n4;
f1_srs_tx_comb->choice.n4.cyclic_shift_n4 = srs_tx_comb->choice.n4.cyclic_shift_n4;
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", srs_tx_comb->present);
break;
}
f1_srs_resource->start_position = srs_resource->start_position;
f1_srs_resource->nr_of_symbols = srs_resource->nr_of_symbols;
f1_srs_resource->repetition_factor = srs_resource->repetition_factor;
f1_srs_resource->freq_domain_position = srs_resource->freq_domain_position;
f1_srs_resource->freq_domain_shift = srs_resource->freq_domain_shift;
f1_srs_resource->c_srs = srs_resource->c_srs;
f1_srs_resource->b_srs = srs_resource->b_srs;
f1_srs_resource->b_hop = srs_resource->b_hop;
f1_srs_resource->group_or_sequence_hopping = srs_resource->group_or_sequence_hopping;
f1_srs_resource->resource_type.present = srs_resource->resource_type.present;
f1ap_resource_type_t *f1_res_type = &f1_srs_resource->resource_type;
f1ap_resource_type_t *res_type = &srs_resource->resource_type;
if (res_type->present == F1AP_RESOURCE_TYPE_PR_NOTHING) {
// nothing to copy
} else if (res_type->present == F1AP_RESOURCE_TYPE_PR_PERIODIC) {
f1_res_type->choice.periodic.periodicity = res_type->choice.periodic.periodicity;
f1_res_type->choice.periodic.offset = res_type->choice.periodic.offset;
} else if (res_type->present == F1AP_RESOURCE_TYPE_PR_SEMI_PERSISTENT) {
f1_res_type->choice.semi_persistent.periodicity = res_type->choice.semi_persistent.periodicity;
f1_res_type->choice.semi_persistent.offset = res_type->choice.semi_persistent.offset;
} else if (res_type->present == F1AP_RESOURCE_TYPE_PR_APERIODIC) {
f1_res_type->choice.aperiodic = res_type->choice.aperiodic;
} else {
AssertFatal(false, "illegal resourceType %d\n", res_type->present);
}
f1_srs_resource->sequence_id = srs_resource->sequence_id;
}
}
// optional: pos_srs_resource_list
if (in_config->pos_srs_resource_list) {
f1ap_pos_srs_resource_list_t *pos_srs_resource_list = in_config->pos_srs_resource_list;
out_config.pos_srs_resource_list = calloc_or_fail(1, sizeof(*out_config.pos_srs_resource_list));
f1ap_pos_srs_resource_list_t *f1_pos_srs_resource_list = out_config.pos_srs_resource_list;
uint32_t pos_srs_resource_list_length = pos_srs_resource_list->pos_srs_resource_list_length;
f1_pos_srs_resource_list->pos_srs_resource_list_length = pos_srs_resource_list_length;
f1_pos_srs_resource_list->pos_srs_resource_item =
calloc_or_fail(pos_srs_resource_list_length, sizeof(*f1_pos_srs_resource_list->pos_srs_resource_item));
for (int i = 0; i < pos_srs_resource_list_length; i++) {
f1ap_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i];
f1ap_pos_srs_resource_item_t *f1_pos_srs_resource = &f1_pos_srs_resource_list->pos_srs_resource_item[i];
f1_pos_srs_resource->srs_pos_resource_id = pos_srs_resource->srs_pos_resource_id;
f1_pos_srs_resource->transmission_comb_pos.present = pos_srs_resource->transmission_comb_pos.present;
f1ap_transmission_comb_pos_t *f1_tx_comb_pos = &f1_pos_srs_resource->transmission_comb_pos;
f1ap_transmission_comb_pos_t *tx_comb_pos = &pos_srs_resource->transmission_comb_pos;
switch (tx_comb_pos->present) {
case F1AP_TRANSMISSION_COMB_POS_PR_NOTHING:
// nothing to copy
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N2:
f1_tx_comb_pos->choice.n2.comb_offset_n2 = tx_comb_pos->choice.n2.comb_offset_n2;
f1_tx_comb_pos->choice.n2.cyclic_shift_n2 = tx_comb_pos->choice.n2.cyclic_shift_n2;
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N4:
f1_tx_comb_pos->choice.n4.comb_offset_n4 = tx_comb_pos->choice.n4.comb_offset_n4;
f1_tx_comb_pos->choice.n4.cyclic_shift_n4 = tx_comb_pos->choice.n4.cyclic_shift_n4;
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N8:
f1_tx_comb_pos->choice.n8.comb_offset_n8 = tx_comb_pos->choice.n8.comb_offset_n8;
f1_tx_comb_pos->choice.n8.cyclic_shift_n8 = tx_comb_pos->choice.n8.cyclic_shift_n8;
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", tx_comb_pos->present);
break;
}
f1_pos_srs_resource->start_position = pos_srs_resource->start_position;
f1_pos_srs_resource->nr_of_symbols = pos_srs_resource->nr_of_symbols;
f1_pos_srs_resource->freq_domain_shift = pos_srs_resource->freq_domain_shift;
f1_pos_srs_resource->c_srs = pos_srs_resource->c_srs;
f1_pos_srs_resource->group_or_sequence_hopping = pos_srs_resource->group_or_sequence_hopping;
f1ap_resource_type_pos_t *f1_res_type_pos = &f1_pos_srs_resource->resource_type_pos;
f1ap_resource_type_pos_t *res_type_pos = &pos_srs_resource->resource_type_pos;
f1_res_type_pos->present = res_type_pos->present;
if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_NOTHING) {
// nothing to copy
} else if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_PERIODIC) {
f1_res_type_pos->choice.periodic.periodicity = res_type_pos->choice.periodic.periodicity;
f1_res_type_pos->choice.periodic.offset = res_type_pos->choice.periodic.offset;
} else if (pos_srs_resource->resource_type_pos.present == F1AP_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT) {
f1_res_type_pos->choice.semi_persistent.periodicity = res_type_pos->choice.semi_persistent.periodicity;
f1_res_type_pos->choice.semi_persistent.offset = res_type_pos->choice.semi_persistent.offset;
} else if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_APERIODIC) {
f1_res_type_pos->choice.aperiodic.slot_offset = res_type_pos->choice.aperiodic.slot_offset;
} else {
AssertFatal(false, "illegal resourceType %d\n", res_type_pos->present);
}
f1_pos_srs_resource->sequence_id = pos_srs_resource->sequence_id;
}
}
// optional: srs_resource_set_list
if (in_config->srs_resource_set_list) {
f1ap_srs_resource_set_list_t *srs_resource_set_list = in_config->srs_resource_set_list;
out_config.srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config.srs_resource_set_list));
f1ap_srs_resource_set_list_t *f1_srs_resource_set_list = out_config.srs_resource_set_list;
uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length;
f1_srs_resource_set_list->srs_resource_set_list_length = srs_resource_set_list_length;
f1_srs_resource_set_list->srs_resource_set =
calloc_or_fail(srs_resource_set_list_length, sizeof(*f1_srs_resource_set_list->srs_resource_set));
for (int i = 0; i < srs_resource_set_list_length; i++) {
f1ap_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i];
f1ap_srs_resource_set_t *f1_srs_resource_set = &f1_srs_resource_set_list->srs_resource_set[i];
f1_srs_resource_set->srs_resource_set_id = srs_resource_set->srs_resource_set_id;
uint8_t srs_resource_id_list_length = srs_resource_set->srs_resource_id_list.srs_resource_id_list_length;
f1_srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length;
f1_srs_resource_set->srs_resource_id_list.srs_resource_id =
calloc_or_fail(srs_resource_id_list_length, sizeof(*f1_srs_resource_set->srs_resource_id_list.srs_resource_id));
for (int j = 0; j < srs_resource_id_list_length; j++) {
f1_srs_resource_set->srs_resource_id_list.srs_resource_id[j] = srs_resource_set->srs_resource_id_list.srs_resource_id[j];
}
f1ap_resource_set_type_t *f1_res_set_type = &f1_srs_resource_set->resource_set_type;
f1ap_resource_set_type_t *res_set_type = &srs_resource_set->resource_set_type;
f1_res_set_type->present = res_set_type->present;
switch (res_set_type->present) {
case F1AP_RESOURCE_SET_TYPE_PR_NOTHING:
// nothing to copy
break;
case F1AP_RESOURCE_SET_TYPE_PR_PERIODIC:
f1_res_set_type->choice.periodic = res_set_type->choice.periodic;
break;
case F1AP_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT:
f1_res_set_type->choice.semi_persistent = res_set_type->choice.semi_persistent;
break;
case F1AP_RESOURCE_SET_TYPE_PR_APERIODIC:
f1_res_set_type->choice.aperiodic.srs_resource_trigger = res_set_type->choice.aperiodic.srs_resource_trigger;
f1_res_set_type->choice.aperiodic.slot_offset = res_set_type->choice.aperiodic.slot_offset;
break;
default:
AssertFatal(false, "illegal resource set type %d\n", res_set_type->present);
break;
}
}
}
// optional: pos_srs_resource_set_list
if (in_config->pos_srs_resource_set_list) {
f1ap_pos_srs_resource_set_list_t *pos_srs_resource_set_list = in_config->pos_srs_resource_set_list;
out_config.pos_srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config.pos_srs_resource_set_list));
f1ap_pos_srs_resource_set_list_t *f1_pos_srs_resource_set_list = out_config.pos_srs_resource_set_list;
uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length;
f1_pos_srs_resource_set_list->pos_srs_resource_set_list_length = pos_srs_resource_set_list_length;
f1_pos_srs_resource_set_list->pos_srs_resource_set_item =
calloc_or_fail(pos_srs_resource_set_list_length, sizeof(*f1_pos_srs_resource_set_list->pos_srs_resource_set_item));
for (int i = 0; i < pos_srs_resource_set_list_length; i++) {
f1ap_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i];
f1ap_pos_srs_resource_set_item_t *f1_pos_srs_resource_set = &f1_pos_srs_resource_set_list->pos_srs_resource_set_item[i];
f1_pos_srs_resource_set->pos_srs_resource_set_id = pos_srs_resource_set->pos_srs_resource_set_id;
uint8_t pos_srs_resource_id_list_length = pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length;
f1_pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length;
f1_pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id =
calloc_or_fail(pos_srs_resource_id_list_length,
sizeof(*f1_pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id));
for (int j = 0; j < pos_srs_resource_id_list_length; j++) {
f1_pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j] =
pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j];
}
f1ap_pos_resource_set_type_t *f1_pos_res_set_type = &f1_pos_srs_resource_set->pos_resource_set_type;
f1ap_pos_resource_set_type_t *pos_res_set_type = &pos_srs_resource_set->pos_resource_set_type;
f1_pos_res_set_type->present = pos_res_set_type->present;
switch (pos_res_set_type->present) {
case F1AP_POS_RESOURCE_SET_TYPE_PR_NOTHING:
// nothing to copy
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_PERIODIC:
f1_pos_res_set_type->choice.periodic = pos_res_set_type->choice.periodic;
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT:
f1_pos_res_set_type->choice.semi_persistent = pos_res_set_type->choice.semi_persistent;
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_APERIODIC:
f1_pos_res_set_type->choice.srs_resource = pos_res_set_type->choice.srs_resource;
break;
default:
AssertFatal(false, "illegal resource set type pos %d\n", pos_res_set_type->present);
break;
}
}
}
return out_config;
}
static f1ap_srs_carrier_list_item_t cp_srs_carrier_list_item(const f1ap_srs_carrier_list_item_t *in_item)
{
f1ap_srs_carrier_list_item_t out_item = {0};
// pointA
out_item.pointA = in_item->pointA;
// Uplink Channel BW-PerSCS-List
const f1ap_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &in_item->uplink_channel_bw_per_scs_list;
f1ap_uplink_channel_bw_per_scs_list_t *f1_uplink_channel_bw_per_scs_list = &out_item.uplink_channel_bw_per_scs_list;
uint32_t scs_specific_carrier_list_length = uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length;
f1_uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length = scs_specific_carrier_list_length;
f1_uplink_channel_bw_per_scs_list->scs_specific_carrier =
calloc_or_fail(scs_specific_carrier_list_length, sizeof(*f1_uplink_channel_bw_per_scs_list->scs_specific_carrier));
for (int i = 0; i < scs_specific_carrier_list_length; i++) {
f1ap_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i];
f1ap_scs_specific_carrier_t *f1_scs_specific_carrier = &f1_uplink_channel_bw_per_scs_list->scs_specific_carrier[i];
// offset to carrier
f1_scs_specific_carrier->offset_to_carrier = scs_specific_carrier->offset_to_carrier;
// subcarrier spacing
f1_scs_specific_carrier->subcarrier_spacing = scs_specific_carrier->subcarrier_spacing;
// carrier bandwidth
f1_scs_specific_carrier->carrier_bandwidth = scs_specific_carrier->carrier_bandwidth;
}
// Active UL BWP
f1ap_active_ul_bwp_t *f1_active_ul_bwp = &out_item.active_ul_bwp;
const f1ap_active_ul_bwp_t *active_ul_bwp = &in_item->active_ul_bwp;
// location and bandwidth
f1_active_ul_bwp->location_and_bandwidth = active_ul_bwp->location_and_bandwidth;
// subcarrier spacing
f1_active_ul_bwp->subcarrier_spacing = active_ul_bwp->subcarrier_spacing;
// cyclic prefix
f1_active_ul_bwp->cyclic_prefix = active_ul_bwp->cyclic_prefix;
// Tx Direct Current Location
f1_active_ul_bwp->tx_direct_current_location = active_ul_bwp->tx_direct_current_location;
// SRS Config
f1ap_srs_config_t *f1_sRSConfig = &f1_active_ul_bwp->srs_config;
const f1ap_srs_config_t *sRSConfig = &active_ul_bwp->srs_config;
*f1_sRSConfig = cp_srs_config(sRSConfig);
return out_item;
}
static f1ap_srs_carrier_list_t cp_srs_carrier_list(const f1ap_srs_carrier_list_t *in_list)
{
f1ap_srs_carrier_list_t out_list = {0};
uint32_t list_len = in_list->srs_carrier_list_length;
out_list.srs_carrier_list_length = list_len;
out_list.srs_carrier_list_item = calloc_or_fail(list_len, sizeof(*out_list.srs_carrier_list_item));
for (int i = 0; i < list_len; i++) {
f1ap_srs_carrier_list_item_t *in_item = &in_list->srs_carrier_list_item[i];
f1ap_srs_carrier_list_item_t *out_item = &out_list.srs_carrier_list_item[i];
*out_item = cp_srs_carrier_list_item(in_item);
}
return out_list;
}
static bool eq_srs_config(const f1ap_srs_config_t *f1_sRSConfig, const f1ap_srs_config_t *sRSConfig)
{
// optional: srs_resource_list
if ((f1_sRSConfig->srs_resource_list == NULL) != (sRSConfig->srs_resource_list == NULL)) {
return false;
}
if (sRSConfig->srs_resource_list) {
f1ap_srs_resource_list_t *srs_resource_list = sRSConfig->srs_resource_list;
f1ap_srs_resource_list_t *f1_srs_resource_list = f1_sRSConfig->srs_resource_list;
uint32_t srs_resource_list_length = srs_resource_list->srs_resource_list_length;
_F1_EQ_CHECK_INT(f1_srs_resource_list->srs_resource_list_length, srs_resource_list_length);
for (int i = 0; i < srs_resource_list_length; i++) {
f1ap_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i];
f1ap_srs_resource_t *f1_srs_resource = &f1_srs_resource_list->srs_resource[i];
_F1_EQ_CHECK_INT(f1_srs_resource->srs_resource_id, srs_resource->srs_resource_id);
_F1_EQ_CHECK_INT(f1_srs_resource->nr_of_srs_ports, srs_resource->nr_of_srs_ports);
f1ap_transmission_comb_t *f1_srs_tx_comb = &f1_srs_resource->transmission_comb;
f1ap_transmission_comb_t *srs_tx_comb = &srs_resource->transmission_comb;
_F1_EQ_CHECK_INT(f1_srs_tx_comb->present, srs_tx_comb->present);
switch (srs_tx_comb->present) {
case F1AP_TRANSMISSION_COMB_PR_NOTHING:
// nothing to check
break;
case F1AP_TRANSMISSION_COMB_PR_N2:
_F1_EQ_CHECK_INT(f1_srs_tx_comb->choice.n2.comb_offset_n2, srs_tx_comb->choice.n2.comb_offset_n2);
_F1_EQ_CHECK_INT(f1_srs_tx_comb->choice.n2.cyclic_shift_n2, srs_tx_comb->choice.n2.cyclic_shift_n2);
break;
case F1AP_TRANSMISSION_COMB_PR_N4:
_F1_EQ_CHECK_INT(f1_srs_tx_comb->choice.n4.comb_offset_n4, srs_tx_comb->choice.n4.comb_offset_n4);
_F1_EQ_CHECK_INT(f1_srs_tx_comb->choice.n4.cyclic_shift_n4, srs_tx_comb->choice.n4.cyclic_shift_n4);
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", srs_tx_comb->present);
break;
}
_F1_EQ_CHECK_INT(f1_srs_resource->start_position, srs_resource->start_position);
_F1_EQ_CHECK_INT(f1_srs_resource->nr_of_symbols, srs_resource->nr_of_symbols);
_F1_EQ_CHECK_INT(f1_srs_resource->repetition_factor, srs_resource->repetition_factor);
_F1_EQ_CHECK_INT(f1_srs_resource->freq_domain_position, srs_resource->freq_domain_position);
_F1_EQ_CHECK_INT(f1_srs_resource->freq_domain_shift, srs_resource->freq_domain_shift);
_F1_EQ_CHECK_INT(f1_srs_resource->c_srs, srs_resource->c_srs);
_F1_EQ_CHECK_INT(f1_srs_resource->b_srs, srs_resource->b_srs);
_F1_EQ_CHECK_INT(f1_srs_resource->b_hop, srs_resource->b_hop);
_F1_EQ_CHECK_INT(f1_srs_resource->group_or_sequence_hopping, srs_resource->group_or_sequence_hopping);
f1ap_resource_type_t *f1_res_type = &f1_srs_resource->resource_type;
f1ap_resource_type_t *res_type = &srs_resource->resource_type;
_F1_EQ_CHECK_INT(f1_res_type->present, res_type->present);
if (res_type->present == F1AP_RESOURCE_TYPE_PR_NOTHING) {
// nothing to check
} else if (res_type->present == F1AP_RESOURCE_TYPE_PR_PERIODIC) {
_F1_EQ_CHECK_INT(f1_res_type->choice.periodic.periodicity, res_type->choice.periodic.periodicity);
_F1_EQ_CHECK_INT(f1_res_type->choice.periodic.offset, res_type->choice.periodic.offset);
} else if (res_type->present == F1AP_RESOURCE_TYPE_PR_SEMI_PERSISTENT) {
_F1_EQ_CHECK_INT(f1_res_type->choice.semi_persistent.periodicity, res_type->choice.semi_persistent.periodicity);
_F1_EQ_CHECK_INT(f1_res_type->choice.semi_persistent.offset, res_type->choice.semi_persistent.offset);
} else if (res_type->present == F1AP_RESOURCE_TYPE_PR_APERIODIC) {
_F1_EQ_CHECK_INT(f1_res_type->choice.aperiodic, res_type->choice.aperiodic);
} else {
AssertFatal(false, "illegal resourceType %d\n", res_type->present);
}
_F1_EQ_CHECK_INT(f1_srs_resource->sequence_id, srs_resource->sequence_id);
}
}
// optional: pos_srs_resource_list
if ((f1_sRSConfig->pos_srs_resource_list == NULL) != (sRSConfig->pos_srs_resource_list == NULL)) {
return false;
}
if (sRSConfig->pos_srs_resource_list) {
f1ap_pos_srs_resource_list_t *pos_srs_resource_list = sRSConfig->pos_srs_resource_list;
f1ap_pos_srs_resource_list_t *f1_pos_srs_resource_list = f1_sRSConfig->pos_srs_resource_list;
uint32_t pos_srs_resource_list_length = pos_srs_resource_list->pos_srs_resource_list_length;
_F1_EQ_CHECK_INT(f1_pos_srs_resource_list->pos_srs_resource_list_length, pos_srs_resource_list_length);
for (int i = 0; i < pos_srs_resource_list_length; i++) {
f1ap_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i];
f1ap_pos_srs_resource_item_t *f1_pos_srs_resource = &f1_pos_srs_resource_list->pos_srs_resource_item[i];
_F1_EQ_CHECK_INT(f1_pos_srs_resource->srs_pos_resource_id, pos_srs_resource->srs_pos_resource_id);
_F1_EQ_CHECK_INT(f1_pos_srs_resource->transmission_comb_pos.present, pos_srs_resource->transmission_comb_pos.present);
f1ap_transmission_comb_pos_t *f1_srs_tx_comb_pos = &f1_pos_srs_resource->transmission_comb_pos;
f1ap_transmission_comb_pos_t *srs_tx_comb_pos = &pos_srs_resource->transmission_comb_pos;
switch (srs_tx_comb_pos->present) {
case F1AP_TRANSMISSION_COMB_POS_PR_NOTHING:
// nothing to check
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N2:
_F1_EQ_CHECK_INT(f1_srs_tx_comb_pos->choice.n2.comb_offset_n2, srs_tx_comb_pos->choice.n2.comb_offset_n2);
_F1_EQ_CHECK_INT(f1_srs_tx_comb_pos->choice.n2.cyclic_shift_n2, srs_tx_comb_pos->choice.n2.cyclic_shift_n2);
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N4:
_F1_EQ_CHECK_INT(f1_srs_tx_comb_pos->choice.n4.comb_offset_n4, srs_tx_comb_pos->choice.n4.comb_offset_n4);
_F1_EQ_CHECK_INT(f1_srs_tx_comb_pos->choice.n4.cyclic_shift_n4, srs_tx_comb_pos->choice.n4.cyclic_shift_n4);
break;
case F1AP_TRANSMISSION_COMB_POS_PR_N8:
_F1_EQ_CHECK_INT(f1_srs_tx_comb_pos->choice.n8.comb_offset_n8, srs_tx_comb_pos->choice.n8.comb_offset_n8);
_F1_EQ_CHECK_INT(f1_srs_tx_comb_pos->choice.n8.cyclic_shift_n8, srs_tx_comb_pos->choice.n8.cyclic_shift_n8);
break;
default:
AssertFatal(false, "illegal transmissionComb %d\n", srs_tx_comb_pos->present);
break;
}
_F1_EQ_CHECK_INT(f1_pos_srs_resource->start_position, pos_srs_resource->start_position);
_F1_EQ_CHECK_INT(f1_pos_srs_resource->nr_of_symbols, pos_srs_resource->nr_of_symbols);
_F1_EQ_CHECK_INT(f1_pos_srs_resource->freq_domain_shift, pos_srs_resource->freq_domain_shift);
_F1_EQ_CHECK_INT(f1_pos_srs_resource->c_srs, pos_srs_resource->c_srs);
_F1_EQ_CHECK_INT(f1_pos_srs_resource->group_or_sequence_hopping, pos_srs_resource->group_or_sequence_hopping);
f1ap_resource_type_pos_t *f1_res_type_pos = &f1_pos_srs_resource->resource_type_pos;
f1ap_resource_type_pos_t *res_type_pos = &pos_srs_resource->resource_type_pos;
_F1_EQ_CHECK_INT(f1_res_type_pos->present, res_type_pos->present);
if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_NOTHING) {
// nothing to check
} else if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_PERIODIC) {
_F1_EQ_CHECK_INT(f1_res_type_pos->choice.periodic.periodicity, res_type_pos->choice.periodic.periodicity);
_F1_EQ_CHECK_INT(f1_res_type_pos->choice.periodic.offset, res_type_pos->choice.periodic.offset);
} else if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT) {
_F1_EQ_CHECK_INT(f1_res_type_pos->choice.semi_persistent.periodicity, res_type_pos->choice.semi_persistent.periodicity);
_F1_EQ_CHECK_INT(f1_res_type_pos->choice.semi_persistent.offset, res_type_pos->choice.semi_persistent.offset);
} else if (res_type_pos->present == F1AP_RESOURCE_TYPE_POS_PR_APERIODIC) {
_F1_EQ_CHECK_INT(f1_res_type_pos->choice.aperiodic.slot_offset, res_type_pos->choice.aperiodic.slot_offset);
} else {
AssertFatal(false, "illegal resourceType %d\n", res_type_pos->present);
}
_F1_EQ_CHECK_INT(f1_pos_srs_resource->sequence_id, pos_srs_resource->sequence_id);
}
}
// optional: srs_resource_set_list
if ((f1_sRSConfig->srs_resource_set_list == NULL) != (sRSConfig->srs_resource_set_list == NULL)) {
return false;
}
if (sRSConfig->srs_resource_set_list) {
f1ap_srs_resource_set_list_t *srs_resource_set_list = sRSConfig->srs_resource_set_list;
f1ap_srs_resource_set_list_t *f1_srs_resource_set_list = f1_sRSConfig->srs_resource_set_list;
uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length;
_F1_EQ_CHECK_INT(f1_srs_resource_set_list->srs_resource_set_list_length, srs_resource_set_list_length);
for (int i = 0; i < srs_resource_set_list_length; i++) {
f1ap_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i];
f1ap_srs_resource_set_t *f1_srs_resource_set = &f1_srs_resource_set_list->srs_resource_set[i];
_F1_EQ_CHECK_INT(f1_srs_resource_set->srs_resource_set_id, srs_resource_set->srs_resource_set_id);
uint8_t srs_resource_id_list_length = srs_resource_set->srs_resource_id_list.srs_resource_id_list_length;
_F1_EQ_CHECK_INT(f1_srs_resource_set->srs_resource_id_list.srs_resource_id_list_length, srs_resource_id_list_length);
for (int j = 0; j < srs_resource_id_list_length; j++) {
_F1_EQ_CHECK_LONG(f1_srs_resource_set->srs_resource_id_list.srs_resource_id[j],
srs_resource_set->srs_resource_id_list.srs_resource_id[j]);
}
f1ap_resource_set_type_t *f1_res_set_type = &f1_srs_resource_set->resource_set_type;
f1ap_resource_set_type_t *res_set_type = &srs_resource_set->resource_set_type;
_F1_EQ_CHECK_INT(f1_res_set_type->present, res_set_type->present);
switch (res_set_type->present) {
case F1AP_RESOURCE_SET_TYPE_PR_NOTHING:
// nothing to check
break;
case F1AP_RESOURCE_SET_TYPE_PR_PERIODIC:
_F1_EQ_CHECK_INT(f1_res_set_type->choice.periodic, res_set_type->choice.periodic);
break;
case F1AP_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT:
_F1_EQ_CHECK_INT(f1_res_set_type->choice.semi_persistent, res_set_type->choice.semi_persistent);
break;
case F1AP_RESOURCE_SET_TYPE_PR_APERIODIC:
_F1_EQ_CHECK_INT(f1_res_set_type->choice.aperiodic.srs_resource_trigger,
res_set_type->choice.aperiodic.srs_resource_trigger);
_F1_EQ_CHECK_LONG(f1_res_set_type->choice.aperiodic.slot_offset, res_set_type->choice.aperiodic.slot_offset);
break;
default:
AssertFatal(false, "illegal resource set type %d\n", res_set_type->present);
break;
}
}
}
// optional: pos_srs_resource_set_list
if ((f1_sRSConfig->pos_srs_resource_set_list == NULL) != (sRSConfig->pos_srs_resource_set_list == NULL)) {
return false;
}
if (sRSConfig->pos_srs_resource_set_list) {
f1ap_pos_srs_resource_set_list_t *pos_srs_resource_set_list = sRSConfig->pos_srs_resource_set_list;
f1ap_pos_srs_resource_set_list_t *f1_pos_srs_resource_set_list = f1_sRSConfig->pos_srs_resource_set_list;
uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length;
_F1_EQ_CHECK_INT(f1_pos_srs_resource_set_list->pos_srs_resource_set_list_length, pos_srs_resource_set_list_length);
for (int i = 0; i < pos_srs_resource_set_list_length; i++) {
f1ap_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i];
f1ap_pos_srs_resource_set_item_t *f1_pos_srs_resource_set = &f1_pos_srs_resource_set_list->pos_srs_resource_set_item[i];
_F1_EQ_CHECK_INT(f1_pos_srs_resource_set->pos_srs_resource_set_id, pos_srs_resource_set->pos_srs_resource_set_id);
uint8_t pos_srs_resource_id_list_length = pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length;
_F1_EQ_CHECK_INT(f1_pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length,
pos_srs_resource_id_list_length);
for (int j = 0; j < pos_srs_resource_id_list_length; j++) {
_F1_EQ_CHECK_LONG(f1_pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j],
pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j]);
}
f1ap_pos_resource_set_type_t *f1_pos_res_set_type = &f1_pos_srs_resource_set->pos_resource_set_type;
f1ap_pos_resource_set_type_t *pos_res_set_type = &pos_srs_resource_set->pos_resource_set_type;
_F1_EQ_CHECK_INT(f1_pos_res_set_type->present, pos_res_set_type->present);
switch (pos_res_set_type->present) {
case F1AP_POS_RESOURCE_SET_TYPE_PR_NOTHING:
// nothing to check
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_PERIODIC:
_F1_EQ_CHECK_INT(f1_pos_res_set_type->choice.periodic, pos_res_set_type->choice.periodic);
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT:
_F1_EQ_CHECK_INT(f1_pos_res_set_type->choice.semi_persistent, pos_res_set_type->choice.semi_persistent);
break;
case F1AP_POS_RESOURCE_SET_TYPE_PR_APERIODIC:
_F1_EQ_CHECK_INT(f1_pos_res_set_type->choice.srs_resource, pos_res_set_type->choice.srs_resource);
break;
default:
AssertFatal(false, "illegal resource set type pos %d\n", pos_res_set_type->present);
break;
}
}
}
return true;
}
static bool eq_srs_carrier_list_item(const f1ap_srs_carrier_list_item_t *f1_srs_carrier_list_item,
const f1ap_srs_carrier_list_item_t *srs_carrier_list_item)
{
// pointA
_F1_EQ_CHECK_INT(f1_srs_carrier_list_item->pointA, srs_carrier_list_item->pointA);
// Uplink Channel BW-PerSCS-List
const f1ap_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list =
&srs_carrier_list_item->uplink_channel_bw_per_scs_list;
const f1ap_uplink_channel_bw_per_scs_list_t *f1_uplink_channel_bw_per_scs_list =
&f1_srs_carrier_list_item->uplink_channel_bw_per_scs_list;
uint32_t scs_specific_carrier_list_length = uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length;
_F1_EQ_CHECK_INT(f1_uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length, scs_specific_carrier_list_length);
for (int i = 0; i < scs_specific_carrier_list_length; i++) {
f1ap_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i];
f1ap_scs_specific_carrier_t *f1_scs_specific_carrier = &f1_uplink_channel_bw_per_scs_list->scs_specific_carrier[i];
// offset to carrier
_F1_EQ_CHECK_INT(f1_scs_specific_carrier->offset_to_carrier, scs_specific_carrier->offset_to_carrier);
// subcarrier spacing
_F1_EQ_CHECK_INT(f1_scs_specific_carrier->subcarrier_spacing, scs_specific_carrier->subcarrier_spacing);
// carrier bandwidth
_F1_EQ_CHECK_INT(f1_scs_specific_carrier->carrier_bandwidth, scs_specific_carrier->carrier_bandwidth);
}
// Active UL BWP
const f1ap_active_ul_bwp_t *f1_active_ul_bwp = &f1_srs_carrier_list_item->active_ul_bwp;
const f1ap_active_ul_bwp_t *active_ul_bwp = &srs_carrier_list_item->active_ul_bwp;
// location and bandwidth
_F1_EQ_CHECK_INT(f1_active_ul_bwp->location_and_bandwidth, active_ul_bwp->location_and_bandwidth);
// subcarrier spacing
_F1_EQ_CHECK_INT(f1_active_ul_bwp->subcarrier_spacing, active_ul_bwp->subcarrier_spacing);
// cyclic prefix
_F1_EQ_CHECK_INT(f1_active_ul_bwp->cyclic_prefix, active_ul_bwp->cyclic_prefix);
// Tx Direct Current Location
_F1_EQ_CHECK_INT(f1_active_ul_bwp->tx_direct_current_location, active_ul_bwp->tx_direct_current_location);
// SRS Config
const f1ap_srs_config_t *f1_sRSConfig = &f1_active_ul_bwp->srs_config;
const f1ap_srs_config_t *sRSConfig = &active_ul_bwp->srs_config;
_F1_CHECK_EXP(eq_srs_config(f1_sRSConfig, sRSConfig));
return true;
}
static bool eq_srs_carrier_list(const f1ap_srs_carrier_list_t *srs_carrier_list_a,
const f1ap_srs_carrier_list_t *srs_carrier_list_b)
{
uint32_t srs_carrier_list_len = srs_carrier_list_a->srs_carrier_list_length;
_F1_EQ_CHECK_INT(srs_carrier_list_b->srs_carrier_list_length, srs_carrier_list_len);
for (int i = 0; i < srs_carrier_list_len; i++) {
f1ap_srs_carrier_list_item_t *srs_carrier_list_item_a = &srs_carrier_list_a->srs_carrier_list_item[i];
f1ap_srs_carrier_list_item_t *srs_carrier_list_item_b = &srs_carrier_list_b->srs_carrier_list_item[i];
_F1_CHECK_EXP(eq_srs_carrier_list_item(srs_carrier_list_item_a, srs_carrier_list_item_b));
}
return true;
}
static void free_srs_carrier_list(f1ap_srs_carrier_list_t *srs_carrier_list)
{
uint32_t srs_carrier_list_len = srs_carrier_list->srs_carrier_list_length;
for (int i = 0; i < srs_carrier_list_len; i++) {
f1ap_srs_carrier_list_item_t *srs_carrier_list_item = &srs_carrier_list->srs_carrier_list_item[i];
free(srs_carrier_list_item->uplink_channel_bw_per_scs_list.scs_specific_carrier);
f1ap_active_ul_bwp_t *active_ul_bwp = &srs_carrier_list_item->active_ul_bwp;
f1ap_srs_config_t *sRSConfig = &active_ul_bwp->srs_config;
if (sRSConfig->srs_resource_list) {
f1ap_srs_resource_list_t *srs_resource_list = sRSConfig->srs_resource_list;
free(srs_resource_list->srs_resource);
free(sRSConfig->srs_resource_list);
}
if (sRSConfig->pos_srs_resource_list) {
f1ap_pos_srs_resource_list_t *pos_srs_resource_list = sRSConfig->pos_srs_resource_list;
free(pos_srs_resource_list->pos_srs_resource_item);
free(sRSConfig->pos_srs_resource_list);
}
if (sRSConfig->srs_resource_set_list) {
f1ap_srs_resource_set_list_t *srs_resource_set_list = sRSConfig->srs_resource_set_list;
uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length;
for (int j = 0; j < srs_resource_set_list_length; j++) {
f1ap_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[j];
free(srs_resource_set->srs_resource_id_list.srs_resource_id);
}
free(srs_resource_set_list->srs_resource_set);
free(sRSConfig->srs_resource_set_list);
}
if (sRSConfig->pos_srs_resource_set_list) {
f1ap_pos_srs_resource_set_list_t *pos_srs_resource_set_list = sRSConfig->pos_srs_resource_set_list;
uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length;
for (int j = 0; j < pos_srs_resource_set_list_length; j++) {
f1ap_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[j];
free(pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id);
}
free(pos_srs_resource_set_list->pos_srs_resource_set_item);
free(sRSConfig->pos_srs_resource_set_list);
}
}
free(srs_carrier_list->srs_carrier_list_item);
}
static F1AP_SRSType_t encode_f1ap_srstype(const f1ap_srs_type_t *srs_type)
{
F1AP_SRSType_t f1_srstype = {0};
switch (srs_type->present) {
case F1AP_SRS_TYPE_PR_NOTHING:
f1_srstype.present = F1AP_SRSType_PR_NOTHING;
break;
case F1AP_SRS_TYPE_PR_SEMIPERSISTENTSRS:
f1_srstype.present = F1AP_SRSType_PR_semipersistentSRS;
asn1cCalloc(f1_srstype.choice.semipersistentSRS, sp_srs);
sp_srs->sRSResourceSetID = *srs_type->choice.srs_resource_set_id;
break;
case F1AP_SRS_TYPE_PR_APERIODICSRS:
f1_srstype.present = F1AP_SRSType_PR_aperiodicSRS;
asn1cCalloc(f1_srstype.choice.aperiodicSRS, ap_srs);
ap_srs->aperiodic = *srs_type->choice.aperiodic;
break;
default:
AssertFatal(false, "unknown SRS type %d\n", srs_type->present);
break;
}
return f1_srstype;
}
static bool decode_f1ap_srstype(const F1AP_SRSType_t *srs_type, f1ap_srs_type_t *out)
{
switch (srs_type->present) {
case F1AP_SRSType_PR_NOTHING:
out->present = F1AP_SRS_TYPE_PR_NOTHING;
break;
case F1AP_SRSType_PR_semipersistentSRS:
out->present = F1AP_SRS_TYPE_PR_SEMIPERSISTENTSRS;
out->choice.srs_resource_set_id = calloc_or_fail(1, sizeof(*out->choice.srs_resource_set_id));
*out->choice.srs_resource_set_id = srs_type->choice.semipersistentSRS->sRSResourceSetID;
break;
case F1AP_SRSType_PR_aperiodicSRS:
out->present = F1AP_SRS_TYPE_PR_APERIODICSRS;
out->choice.aperiodic = calloc_or_fail(1, sizeof(*out->choice.aperiodic));
*out->choice.aperiodic = srs_type->choice.aperiodicSRS->aperiodic;
break;
default:
PRINT_ERROR("received illegal SRS type %d\n", srs_type->present);
return false;
break;
}
return true;
}
static F1AP_AbortTransmission_t encode_f1ap_abort_transmission(const f1ap_abort_transmission_t *abort_tx)
{
F1AP_AbortTransmission_t f1_abort_tx = {0};
switch (abort_tx->present) {
case F1AP_ABORT_TRANSMISSION_PR_NOTHING:
f1_abort_tx.present = F1AP_AbortTransmission_PR_NOTHING;
break;
case F1AP_ABORT_TRANSMISSION_PR_SRSRESOURCESETID:
f1_abort_tx.present = F1AP_AbortTransmission_PR_sRSResourceSetID;
f1_abort_tx.choice.sRSResourceSetID = abort_tx->choice.srs_resource_set_id;
break;
case F1AP_ABORT_TRANSMISSION_PR_RELEASEALL:
f1_abort_tx.present = F1AP_AbortTransmission_PR_releaseALL;
break;
default:
AssertFatal(false, "unknown Abort Transmission %d\n", abort_tx->present);
break;
}
return f1_abort_tx;
}
static bool decode_f1ap_abort_transmission(const F1AP_AbortTransmission_t *in, f1ap_abort_transmission_t *out)
{
switch (in->present) {
case F1AP_AbortTransmission_PR_NOTHING:
out->present = F1AP_ABORT_TRANSMISSION_PR_NOTHING;
break;
case F1AP_AbortTransmission_PR_sRSResourceSetID:
out->present = F1AP_ABORT_TRANSMISSION_PR_SRSRESOURCESETID;
out->choice.srs_resource_set_id = in->choice.sRSResourceSetID;
break;
case F1AP_AbortTransmission_PR_releaseALL:
out->present = F1AP_ABORT_TRANSMISSION_PR_RELEASEALL;
out->choice.release_all = true;
break;
default:
AssertError(false, return false, "received illegal Abort Transmission %d\n", in->present);
break;
}
return true;
}
static F1AP_TRPReferencePointType_t encode_reference_point_type(const f1ap_trp_reference_point_type_t *in)
{
F1AP_TRPReferencePointType_t out = {0};
switch (in->present) {
case F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC:
out.present = F1AP_TRPReferencePointType_PR_tRPPositionRelativeGeodetic;
asn1cCalloc(out.choice.tRPPositionRelativeGeodetic, f1_tRPPositionRelativeGeodetic);
const f1ap_relative_geodetic_location_t *tRPPositionRelativeGeodetic = &in->choice.trp_position_relative_geodetic;
f1_tRPPositionRelativeGeodetic->milli_Arc_SecondUnits = tRPPositionRelativeGeodetic->milli_arc_second_units;
f1_tRPPositionRelativeGeodetic->heightUnits = tRPPositionRelativeGeodetic->height_units;
f1_tRPPositionRelativeGeodetic->deltaLatitude = tRPPositionRelativeGeodetic->delta_latitude;
f1_tRPPositionRelativeGeodetic->deltaLongitude = tRPPositionRelativeGeodetic->delta_longitude;
f1_tRPPositionRelativeGeodetic->deltaHeight = tRPPositionRelativeGeodetic->delta_height;
F1AP_LocationUncertainty_t *f1_locationUncertainty_g = &f1_tRPPositionRelativeGeodetic->locationUncertainty;
const f1ap_location_uncertainty_t *locationUncertainty_g = &tRPPositionRelativeGeodetic->location_uncertainty;
f1_locationUncertainty_g->horizontalUncertainty = locationUncertainty_g->horizontal_uncertainty;
f1_locationUncertainty_g->horizontalConfidence = locationUncertainty_g->horizontal_confidence;
f1_locationUncertainty_g->verticalUncertainty = locationUncertainty_g->vertical_uncertainty;
f1_locationUncertainty_g->verticalConfidence = locationUncertainty_g->vertical_confidence;
break;
case F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN:
out.present = F1AP_TRPReferencePointType_PR_tRPPositionRelativeCartesian;
asn1cCalloc(out.choice.tRPPositionRelativeCartesian, f1_tRPPositionRelativeCartesian);
const f1ap_relative_cartesian_location_t *tRPPositionRelativeCartesian = &in->choice.trp_position_relative_cartesian;
f1_tRPPositionRelativeCartesian->xYZunit = tRPPositionRelativeCartesian->xyz_unit;
f1_tRPPositionRelativeCartesian->xvalue = tRPPositionRelativeCartesian->xvalue;
f1_tRPPositionRelativeCartesian->yvalue = tRPPositionRelativeCartesian->yvalue;
f1_tRPPositionRelativeCartesian->zvalue = tRPPositionRelativeCartesian->zvalue;
F1AP_LocationUncertainty_t *f1_locationUncertainty_c = &f1_tRPPositionRelativeCartesian->locationUncertainty;
const f1ap_location_uncertainty_t *locationUncertainty_c = &tRPPositionRelativeCartesian->location_uncertainty;
f1_locationUncertainty_c->horizontalUncertainty = locationUncertainty_c->horizontal_uncertainty;
f1_locationUncertainty_c->horizontalConfidence = locationUncertainty_c->horizontal_confidence;
f1_locationUncertainty_c->verticalUncertainty = locationUncertainty_c->vertical_uncertainty;
f1_locationUncertainty_c->verticalConfidence = locationUncertainty_c->vertical_confidence;
break;
default:
AssertFatal(false, "illegal trp reference point type entry %d\n", in->present);
break;
}
return out;
}
static F1AP_NGRANHighAccuracyAccessPointPosition_t encode_trp_ha_pos(const f1ap_ngran_high_accuracy_access_point_position_t *in)
{
F1AP_NGRANHighAccuracyAccessPointPosition_t out = {0};
out.latitude = in->latitude;
out.longitude = in->longitude;
out.altitude = in->altitude;
out.uncertaintySemi_major = in->uncertainty_semi_major;
out.uncertaintySemi_minor = in->uncertainty_semi_minor;
out.orientationOfMajorAxis = in->orientation_of_major_axis;
out.horizontalConfidence = in->horizontal_confidence;
out.uncertaintyAltitude = in->uncertainty_altitude;
out.verticalConfidence = in->vertical_confidence;
return out;
}
static F1AP_GeographicalCoordinates_t encode_geographical_coordinates(const f1ap_geographical_coordinates_t *in)
{
F1AP_GeographicalCoordinates_t out = {0};
F1AP_TRPPositionDefinitionType_t *f1_trp_pos_def_type = &out.tRPPositionDefinitionType;
const f1ap_trp_position_definition_type_t *trp_pos_def_type = &in->trp_position_definition_type;
switch (trp_pos_def_type->present) {
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING:
f1_trp_pos_def_type->present = F1AP_TRPPositionDefinitionType_PR_NOTHING;
break;
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT:
f1_trp_pos_def_type->present = F1AP_TRPPositionDefinitionType_PR_direct;
asn1cCalloc(f1_trp_pos_def_type->choice.direct, f1_direct);
const f1ap_trp_position_direct_t *direct = &trp_pos_def_type->choice.direct;
if (direct->accuracy.present == F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION) {
f1_direct->accuracy.present = F1AP_TRPPositionDirectAccuracy_PR_tRPPosition;
const f1ap_access_point_position_t *trp_pos = &direct->accuracy.choice.trp_position;
F1AP_AccessPointPosition_t *f1_trp_pos = f1_direct->accuracy.choice.tRPPosition;
f1_trp_pos->latitudeSign = trp_pos->latitude_sign;
f1_trp_pos->latitude = trp_pos->latitude;
f1_trp_pos->longitude = trp_pos->longitude;
f1_trp_pos->directionOfAltitude = trp_pos->direction_of_altitude;
f1_trp_pos->altitude = trp_pos->altitude;
f1_trp_pos->uncertaintySemi_major = trp_pos->uncertainty_semi_major;
f1_trp_pos->uncertaintySemi_minor = trp_pos->uncertainty_semi_minor;
f1_trp_pos->orientationOfMajorAxis = trp_pos->orientation_of_major_axis;
f1_trp_pos->uncertaintyAltitude = trp_pos->uncertainty_altitude;
f1_trp_pos->confidence = trp_pos->confidence;
} else if (direct->accuracy.present == F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION) {
f1_direct->accuracy.present = F1AP_TRPPositionDirectAccuracy_PR_tRPHAposition;
const f1ap_ngran_high_accuracy_access_point_position_t *trp_ha_pos = &direct->accuracy.choice.trp_HAposition;
F1AP_NGRANHighAccuracyAccessPointPosition_t *f1_trp_ha_pos = f1_direct->accuracy.choice.tRPHAposition;
*f1_trp_ha_pos = encode_trp_ha_pos(trp_ha_pos);
} else {
AssertFatal(false, "illegal direct accuracy entry %d\n", direct->accuracy.present);
}
break;
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED:
f1_trp_pos_def_type->present = F1AP_TRPPositionDefinitionType_PR_referenced;
asn1cCalloc(f1_trp_pos_def_type->choice.referenced, f1_referenced);
const f1ap_trp_position_referenced_t *referenced = &trp_pos_def_type->choice.referenced;
F1AP_ReferencePoint_t *f1_referencePoint = &f1_referenced->referencePoint;
const f1ap_reference_point_t *referencePoint = &referenced->reference_point;
if (referencePoint->present == F1AP_REFERENCE_POINT_PR_COORDINATEID) {
f1_referencePoint->present = F1AP_ReferencePoint_PR_coordinateID;
f1_referencePoint->choice.coordinateID = referencePoint->choice.coordinate_id;
} else if (referencePoint->present == F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE) {
f1_referencePoint->present = F1AP_ReferencePoint_PR_referencePointCoordinate;
const f1ap_access_point_position_t *referencePointCoordinate = &referencePoint->choice.reference_point_coordinate;
asn1cCalloc(f1_referencePoint->choice.referencePointCoordinate, f1_referencePointCoordinate);
f1_referencePointCoordinate->latitudeSign = referencePointCoordinate->latitude_sign;
f1_referencePointCoordinate->latitude = referencePointCoordinate->latitude;
f1_referencePointCoordinate->longitude = referencePointCoordinate->longitude;
f1_referencePointCoordinate->directionOfAltitude = referencePointCoordinate->direction_of_altitude;
f1_referencePointCoordinate->altitude = referencePointCoordinate->altitude;
f1_referencePointCoordinate->uncertaintySemi_major = referencePointCoordinate->uncertainty_semi_major;
f1_referencePointCoordinate->uncertaintySemi_minor = referencePointCoordinate->uncertainty_semi_minor;
f1_referencePointCoordinate->orientationOfMajorAxis = referencePointCoordinate->orientation_of_major_axis;
f1_referencePointCoordinate->uncertaintyAltitude = referencePointCoordinate->uncertainty_altitude;
f1_referencePointCoordinate->confidence = referencePointCoordinate->confidence;
} else if (referencePoint->present == F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA) {
f1_referencePoint->present = F1AP_ReferencePoint_PR_referencePointCoordinateHA;
const f1ap_ngran_high_accuracy_access_point_position_t *referencePointCoordinateHA =
&referencePoint->choice.reference_point_coordinateHA;
asn1cCalloc(f1_referencePoint->choice.referencePointCoordinateHA, f1_referencePointCoordinateHA);
*f1_referencePointCoordinateHA = encode_trp_ha_pos(referencePointCoordinateHA);
} else {
AssertFatal(false, "illegal reference point entry %d\n", referencePoint->present);
}
F1AP_TRPReferencePointType_t *f1_referencePointType = &f1_referenced->referencePointType;
const f1ap_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type;
*f1_referencePointType = encode_reference_point_type(referencePointType);
break;
default:
AssertFatal(false, "illegal Geographical Coordinates entry\n");
break;
}
return out;
}
static void decode_reference_point_type(const F1AP_TRPReferencePointType_t *in, f1ap_trp_reference_point_type_t *out)
{
switch (in->present) {
case F1AP_TRPReferencePointType_PR_tRPPositionRelativeGeodetic:
out->present = F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC;
F1AP_RelativeGeodeticLocation_t *f1_tRPPositionRelativeGeodetic = in->choice.tRPPositionRelativeGeodetic;
f1ap_relative_geodetic_location_t *tRPPositionRelativeGeodetic = &out->choice.trp_position_relative_geodetic;
tRPPositionRelativeGeodetic->milli_arc_second_units = f1_tRPPositionRelativeGeodetic->milli_Arc_SecondUnits;
tRPPositionRelativeGeodetic->height_units = f1_tRPPositionRelativeGeodetic->heightUnits;
tRPPositionRelativeGeodetic->delta_latitude = f1_tRPPositionRelativeGeodetic->deltaLatitude;
tRPPositionRelativeGeodetic->delta_longitude = f1_tRPPositionRelativeGeodetic->deltaLongitude;
tRPPositionRelativeGeodetic->delta_height = f1_tRPPositionRelativeGeodetic->deltaHeight;
F1AP_LocationUncertainty_t *f1_locationUncertainty_g = &f1_tRPPositionRelativeGeodetic->locationUncertainty;
f1ap_location_uncertainty_t *locationUncertainty_g = &tRPPositionRelativeGeodetic->location_uncertainty;
locationUncertainty_g->horizontal_uncertainty = f1_locationUncertainty_g->horizontalUncertainty;
locationUncertainty_g->horizontal_confidence = f1_locationUncertainty_g->horizontalConfidence;
locationUncertainty_g->vertical_uncertainty = f1_locationUncertainty_g->verticalUncertainty;
locationUncertainty_g->vertical_confidence = f1_locationUncertainty_g->verticalConfidence;
break;
case F1AP_TRPReferencePointType_PR_tRPPositionRelativeCartesian:
out->present = F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN;
F1AP_RelativeCartesianLocation_t *f1_tRPPositionRelativeCartesian = in->choice.tRPPositionRelativeCartesian;
f1ap_relative_cartesian_location_t *tRPPositionRelativeCartesian = &out->choice.trp_position_relative_cartesian;
tRPPositionRelativeCartesian->xyz_unit = f1_tRPPositionRelativeCartesian->xYZunit;
tRPPositionRelativeCartesian->xvalue = f1_tRPPositionRelativeCartesian->xvalue;
tRPPositionRelativeCartesian->yvalue = f1_tRPPositionRelativeCartesian->yvalue;
tRPPositionRelativeCartesian->zvalue = f1_tRPPositionRelativeCartesian->zvalue;
F1AP_LocationUncertainty_t *f1_locationUncertainty_c = &f1_tRPPositionRelativeCartesian->locationUncertainty;
f1ap_location_uncertainty_t *locationUncertainty_c = &tRPPositionRelativeCartesian->location_uncertainty;
locationUncertainty_c->horizontal_uncertainty = f1_locationUncertainty_c->horizontalUncertainty;
locationUncertainty_c->horizontal_confidence = f1_locationUncertainty_c->horizontalConfidence;
locationUncertainty_c->vertical_uncertainty = f1_locationUncertainty_c->verticalUncertainty;
locationUncertainty_c->vertical_confidence = f1_locationUncertainty_c->verticalConfidence;
break;
default:
AssertFatal(false, "illegal trp reference point type entry %d\n", in->present);
break;
}
}
static void decode_trp_ha_pos(const F1AP_NGRANHighAccuracyAccessPointPosition_t *in,
f1ap_ngran_high_accuracy_access_point_position_t *out)
{
out->latitude = in->latitude;
out->longitude = in->longitude;
out->altitude = in->altitude;
out->uncertainty_semi_major = in->uncertaintySemi_major;
out->uncertainty_semi_minor = in->uncertaintySemi_minor;
out->orientation_of_major_axis = in->orientationOfMajorAxis;
out->horizontal_confidence = in->horizontalConfidence;
out->uncertainty_altitude = in->uncertaintyAltitude;
out->vertical_confidence = in->verticalConfidence;
}
static void decode_geographical_coordinates(const F1AP_GeographicalCoordinates_t *in, f1ap_geographical_coordinates_t *out)
{
const F1AP_TRPPositionDefinitionType_t *f1_trp_pos_def_type = &in->tRPPositionDefinitionType;
f1ap_trp_position_definition_type_t *trp_pos_def_type = &out->trp_position_definition_type;
switch (f1_trp_pos_def_type->present) {
case F1AP_TRPPositionDefinitionType_PR_NOTHING:
trp_pos_def_type->present = F1AP_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING;
break;
case F1AP_TRPPositionDefinitionType_PR_direct:
trp_pos_def_type->present = F1AP_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT;
F1AP_TRPPositionDirect_t *f1_direct = f1_trp_pos_def_type->choice.direct;
f1ap_trp_position_direct_t *direct = &trp_pos_def_type->choice.direct;
if (f1_direct->accuracy.present == F1AP_TRPPositionDirectAccuracy_PR_tRPPosition) {
direct->accuracy.present = F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION;
f1ap_access_point_position_t *trp_pos = &direct->accuracy.choice.trp_position;
F1AP_AccessPointPosition_t *f1_trp_pos = f1_direct->accuracy.choice.tRPPosition;
trp_pos->latitude_sign = f1_trp_pos->latitudeSign;
trp_pos->latitude = f1_trp_pos->latitude;
trp_pos->longitude = f1_trp_pos->longitude;
trp_pos->direction_of_altitude = f1_trp_pos->directionOfAltitude;
trp_pos->altitude = f1_trp_pos->altitude;
trp_pos->uncertainty_semi_major = f1_trp_pos->uncertaintySemi_major;
trp_pos->uncertainty_semi_minor = f1_trp_pos->uncertaintySemi_minor;
trp_pos->orientation_of_major_axis = f1_trp_pos->orientationOfMajorAxis;
trp_pos->uncertainty_altitude = f1_trp_pos->uncertaintyAltitude;
trp_pos->confidence = f1_trp_pos->confidence;
} else if (f1_direct->accuracy.present == F1AP_TRPPositionDirectAccuracy_PR_tRPHAposition) {
direct->accuracy.present = F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION;
f1ap_ngran_high_accuracy_access_point_position_t *trp_ha_pos = &direct->accuracy.choice.trp_HAposition;
F1AP_NGRANHighAccuracyAccessPointPosition_t *f1_trp_ha_pos = f1_direct->accuracy.choice.tRPHAposition;
decode_trp_ha_pos(f1_trp_ha_pos, trp_ha_pos);
} else {
AssertFatal(false, "illegal direct accuracy entry %d\n", direct->accuracy.present);
}
break;
case F1AP_TRPPositionDefinitionType_PR_referenced:
trp_pos_def_type->present = F1AP_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED;
F1AP_TRPPositionReferenced_t *f1_referenced = f1_trp_pos_def_type->choice.referenced;
f1ap_trp_position_referenced_t *referenced = &trp_pos_def_type->choice.referenced;
F1AP_ReferencePoint_t *f1_referencePoint = &f1_referenced->referencePoint;
f1ap_reference_point_t *referencePoint = &referenced->reference_point;
if (f1_referencePoint->present == F1AP_ReferencePoint_PR_coordinateID) {
referencePoint->present = F1AP_REFERENCE_POINT_PR_COORDINATEID;
referencePoint->choice.coordinate_id = f1_referencePoint->choice.coordinateID;
} else if (f1_referencePoint->present == F1AP_ReferencePoint_PR_referencePointCoordinate) {
referencePoint->present = F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE;
f1ap_access_point_position_t *referencePointCoordinate = &referencePoint->choice.reference_point_coordinate;
F1AP_AccessPointPosition_t *f1_referencePointCoordinate = f1_referencePoint->choice.referencePointCoordinate;
referencePointCoordinate->latitude_sign = f1_referencePointCoordinate->latitudeSign;
referencePointCoordinate->latitude = f1_referencePointCoordinate->latitude;
referencePointCoordinate->longitude = f1_referencePointCoordinate->longitude;
referencePointCoordinate->direction_of_altitude = f1_referencePointCoordinate->directionOfAltitude;
referencePointCoordinate->altitude = f1_referencePointCoordinate->altitude;
referencePointCoordinate->uncertainty_semi_major = f1_referencePointCoordinate->uncertaintySemi_major;
referencePointCoordinate->uncertainty_semi_minor = f1_referencePointCoordinate->uncertaintySemi_minor;
referencePointCoordinate->orientation_of_major_axis = f1_referencePointCoordinate->orientationOfMajorAxis;
referencePointCoordinate->uncertainty_altitude = f1_referencePointCoordinate->uncertaintyAltitude;
referencePointCoordinate->confidence = f1_referencePointCoordinate->confidence;
} else if (f1_referencePoint->present == F1AP_ReferencePoint_PR_referencePointCoordinateHA) {
referencePoint->present = F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA;
f1ap_ngran_high_accuracy_access_point_position_t *referencePointCoordinateHA =
&referencePoint->choice.reference_point_coordinateHA;
F1AP_NGRANHighAccuracyAccessPointPosition_t *f1_referencePointCoordinateHA =
f1_referencePoint->choice.referencePointCoordinateHA;
decode_trp_ha_pos(f1_referencePointCoordinateHA, referencePointCoordinateHA);
} else {
AssertFatal(false, "illegal reference point entry %d\n", referencePoint->present);
}
F1AP_TRPReferencePointType_t *f1_referencePointType = &f1_referenced->referencePointType;
f1ap_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type;
decode_reference_point_type(f1_referencePointType, referencePointType);
break;
default:
AssertFatal(false, "illegal Geographical Coordinates entry\n");
break;
}
}
static f1ap_trp_reference_point_type_t cp_encode_reference_point_type(const f1ap_trp_reference_point_type_t *in)
{
f1ap_trp_reference_point_type_t out = {0};
switch (in->present) {
case F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC:
out.present = F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC;
const f1ap_relative_geodetic_location_t *f1_tRPPositionRelativeGeodetic = &in->choice.trp_position_relative_geodetic;
f1ap_relative_geodetic_location_t *tRPPositionRelativeGeodetic = &out.choice.trp_position_relative_geodetic;
tRPPositionRelativeGeodetic->milli_arc_second_units = f1_tRPPositionRelativeGeodetic->milli_arc_second_units;
tRPPositionRelativeGeodetic->height_units = f1_tRPPositionRelativeGeodetic->height_units;
tRPPositionRelativeGeodetic->delta_latitude = f1_tRPPositionRelativeGeodetic->delta_latitude;
tRPPositionRelativeGeodetic->delta_longitude = f1_tRPPositionRelativeGeodetic->delta_longitude;
tRPPositionRelativeGeodetic->delta_height = f1_tRPPositionRelativeGeodetic->delta_height;
const f1ap_location_uncertainty_t *f1_locationUncertainty_g = &f1_tRPPositionRelativeGeodetic->location_uncertainty;
f1ap_location_uncertainty_t *locationUncertainty_g = &tRPPositionRelativeGeodetic->location_uncertainty;
locationUncertainty_g->horizontal_uncertainty = f1_locationUncertainty_g->horizontal_uncertainty;
locationUncertainty_g->horizontal_confidence = f1_locationUncertainty_g->horizontal_confidence;
locationUncertainty_g->vertical_uncertainty = f1_locationUncertainty_g->vertical_uncertainty;
locationUncertainty_g->vertical_confidence = f1_locationUncertainty_g->vertical_confidence;
break;
case F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN:
out.present = F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN;
const f1ap_relative_cartesian_location_t *f1_tRPPositionRelativeCartesian = &in->choice.trp_position_relative_cartesian;
f1ap_relative_cartesian_location_t *tRPPositionRelativeCartesian = &out.choice.trp_position_relative_cartesian;
tRPPositionRelativeCartesian->xyz_unit = f1_tRPPositionRelativeCartesian->xyz_unit;
tRPPositionRelativeCartesian->xvalue = f1_tRPPositionRelativeCartesian->xvalue;
tRPPositionRelativeCartesian->yvalue = f1_tRPPositionRelativeCartesian->yvalue;
tRPPositionRelativeCartesian->zvalue = f1_tRPPositionRelativeCartesian->zvalue;
const f1ap_location_uncertainty_t *f1_locationUncertainty_c = &f1_tRPPositionRelativeCartesian->location_uncertainty;
f1ap_location_uncertainty_t *locationUncertainty_c = &tRPPositionRelativeCartesian->location_uncertainty;
locationUncertainty_c->horizontal_uncertainty = f1_locationUncertainty_c->horizontal_uncertainty;
locationUncertainty_c->horizontal_confidence = f1_locationUncertainty_c->horizontal_confidence;
locationUncertainty_c->vertical_uncertainty = f1_locationUncertainty_c->vertical_uncertainty;
locationUncertainty_c->vertical_confidence = f1_locationUncertainty_c->vertical_confidence;
break;
default:
AssertFatal(false, "illegal trp reference point type entry %d\n", in->present);
break;
}
return out;
}
static f1ap_ngran_high_accuracy_access_point_position_t cp_trp_ha_pos(const f1ap_ngran_high_accuracy_access_point_position_t *in)
{
f1ap_ngran_high_accuracy_access_point_position_t out = {0};
out.latitude = in->latitude;
out.longitude = in->longitude;
out.altitude = in->altitude;
out.uncertainty_semi_major = in->uncertainty_semi_major;
out.uncertainty_semi_minor = in->uncertainty_semi_minor;
out.orientation_of_major_axis = in->orientation_of_major_axis;
out.horizontal_confidence = in->horizontal_confidence;
out.uncertainty_altitude = in->uncertainty_altitude;
out.vertical_confidence = in->vertical_confidence;
return out;
}
static f1ap_geographical_coordinates_t cp_geographical_coordinates(const f1ap_geographical_coordinates_t *in)
{
f1ap_geographical_coordinates_t out = {0};
const f1ap_trp_position_definition_type_t *f1_trp_pos_def_type = &in->trp_position_definition_type;
f1ap_trp_position_definition_type_t *trp_pos_def_type = &out.trp_position_definition_type;
switch (f1_trp_pos_def_type->present) {
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING:
trp_pos_def_type->present = F1AP_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING;
break;
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT:
trp_pos_def_type->present = F1AP_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT;
const f1ap_trp_position_direct_t *f1_direct = &f1_trp_pos_def_type->choice.direct;
f1ap_trp_position_direct_t *direct = &trp_pos_def_type->choice.direct;
if (f1_direct->accuracy.present == F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION) {
direct->accuracy.present = F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION;
f1ap_access_point_position_t *trp_pos = &direct->accuracy.choice.trp_position;
const f1ap_access_point_position_t *f1_trp_pos = &f1_direct->accuracy.choice.trp_position;
trp_pos->latitude_sign = f1_trp_pos->latitude_sign;
trp_pos->latitude = f1_trp_pos->latitude;
trp_pos->longitude = f1_trp_pos->longitude;
trp_pos->direction_of_altitude = f1_trp_pos->direction_of_altitude;
trp_pos->altitude = f1_trp_pos->altitude;
trp_pos->uncertainty_semi_major = f1_trp_pos->uncertainty_semi_major;
trp_pos->uncertainty_semi_minor = f1_trp_pos->uncertainty_semi_minor;
trp_pos->orientation_of_major_axis = f1_trp_pos->orientation_of_major_axis;
trp_pos->uncertainty_altitude = f1_trp_pos->uncertainty_altitude;
trp_pos->confidence = f1_trp_pos->confidence;
} else if (f1_direct->accuracy.present == F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION) {
direct->accuracy.present = F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION;
f1ap_ngran_high_accuracy_access_point_position_t *trp_ha_pos = &direct->accuracy.choice.trp_HAposition;
const f1ap_ngran_high_accuracy_access_point_position_t *f1_trp_ha_pos = &f1_direct->accuracy.choice.trp_HAposition;
*trp_ha_pos = cp_trp_ha_pos(f1_trp_ha_pos);
} else {
AssertFatal(false, "illegal direct accuracy entry %d\n", direct->accuracy.present);
}
break;
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED:
trp_pos_def_type->present = F1AP_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED;
const f1ap_trp_position_referenced_t *f1_referenced = &f1_trp_pos_def_type->choice.referenced;
f1ap_trp_position_referenced_t *referenced = &trp_pos_def_type->choice.referenced;
const f1ap_reference_point_t *f1_referencePoint = &f1_referenced->reference_point;
f1ap_reference_point_t *referencePoint = &referenced->reference_point;
if (f1_referencePoint->present == F1AP_REFERENCE_POINT_PR_COORDINATEID) {
referencePoint->present = F1AP_REFERENCE_POINT_PR_COORDINATEID;
referencePoint->choice.coordinate_id = f1_referencePoint->choice.coordinate_id;
} else if (f1_referencePoint->present == F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE) {
referencePoint->present = F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE;
f1ap_access_point_position_t *referencePointCoordinate = &referencePoint->choice.reference_point_coordinate;
const f1ap_access_point_position_t *f1_referencePointCoordinate = &f1_referencePoint->choice.reference_point_coordinate;
referencePointCoordinate->latitude_sign = f1_referencePointCoordinate->latitude_sign;
referencePointCoordinate->latitude = f1_referencePointCoordinate->latitude;
referencePointCoordinate->longitude = f1_referencePointCoordinate->longitude;
referencePointCoordinate->direction_of_altitude = f1_referencePointCoordinate->direction_of_altitude;
referencePointCoordinate->altitude = f1_referencePointCoordinate->altitude;
referencePointCoordinate->uncertainty_semi_major = f1_referencePointCoordinate->uncertainty_semi_major;
referencePointCoordinate->uncertainty_semi_minor = f1_referencePointCoordinate->uncertainty_semi_minor;
referencePointCoordinate->orientation_of_major_axis = f1_referencePointCoordinate->orientation_of_major_axis;
referencePointCoordinate->uncertainty_altitude = f1_referencePointCoordinate->uncertainty_altitude;
referencePointCoordinate->confidence = f1_referencePointCoordinate->confidence;
} else if (f1_referencePoint->present == F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA) {
referencePoint->present = F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA;
f1ap_ngran_high_accuracy_access_point_position_t *referencePointCoordinateHA =
&referencePoint->choice.reference_point_coordinateHA;
const f1ap_ngran_high_accuracy_access_point_position_t *f1_referencePointCoordinateHA =
&f1_referencePoint->choice.reference_point_coordinateHA;
*referencePointCoordinateHA = cp_trp_ha_pos(f1_referencePointCoordinateHA);
} else {
AssertFatal(false, "illegal reference point entry %d\n", referencePoint->present);
}
const f1ap_trp_reference_point_type_t *f1_referencePointType = &f1_referenced->reference_point_type;
f1ap_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type;
*referencePointType = cp_encode_reference_point_type(f1_referencePointType);
break;
default:
AssertFatal(false, "illegal Geographical Coordinates entry\n");
break;
}
return out;
}
static bool eq_reference_point_type(const f1ap_trp_reference_point_type_t *f1_referencePointType,
const f1ap_trp_reference_point_type_t *referencePointType)
{
_F1_EQ_CHECK_INT(f1_referencePointType->present, referencePointType->present);
switch (f1_referencePointType->present) {
case F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC: {
const f1ap_relative_geodetic_location_t *f1_tRPPositionRelativeGeodetic =
&f1_referencePointType->choice.trp_position_relative_geodetic;
const f1ap_relative_geodetic_location_t *tRPPositionRelativeGeodetic =
&referencePointType->choice.trp_position_relative_geodetic;
_F1_EQ_CHECK_LONG(tRPPositionRelativeGeodetic->milli_arc_second_units,
f1_tRPPositionRelativeGeodetic->milli_arc_second_units);
_F1_EQ_CHECK_LONG(tRPPositionRelativeGeodetic->height_units, f1_tRPPositionRelativeGeodetic->height_units);
_F1_EQ_CHECK_LONG(tRPPositionRelativeGeodetic->delta_latitude, f1_tRPPositionRelativeGeodetic->delta_latitude);
_F1_EQ_CHECK_LONG(tRPPositionRelativeGeodetic->delta_longitude, f1_tRPPositionRelativeGeodetic->delta_longitude);
_F1_EQ_CHECK_LONG(tRPPositionRelativeGeodetic->delta_height, f1_tRPPositionRelativeGeodetic->delta_height);
const f1ap_location_uncertainty_t *f1_locationUncertainty_g = &f1_tRPPositionRelativeGeodetic->location_uncertainty;
const f1ap_location_uncertainty_t *locationUncertainty_g = &tRPPositionRelativeGeodetic->location_uncertainty;
_F1_EQ_CHECK_LONG(locationUncertainty_g->horizontal_uncertainty, f1_locationUncertainty_g->horizontal_uncertainty);
_F1_EQ_CHECK_LONG(locationUncertainty_g->horizontal_confidence, f1_locationUncertainty_g->horizontal_confidence);
_F1_EQ_CHECK_LONG(locationUncertainty_g->vertical_uncertainty, f1_locationUncertainty_g->vertical_uncertainty);
_F1_EQ_CHECK_LONG(locationUncertainty_g->vertical_confidence, f1_locationUncertainty_g->vertical_confidence);
break;
}
case F1AP_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN: {
const f1ap_relative_cartesian_location_t *f1_tRPPositionRelativeCartesian =
&f1_referencePointType->choice.trp_position_relative_cartesian;
const f1ap_relative_cartesian_location_t *tRPPositionRelativeCartesian =
&referencePointType->choice.trp_position_relative_cartesian;
_F1_EQ_CHECK_LONG(tRPPositionRelativeCartesian->xyz_unit, f1_tRPPositionRelativeCartesian->xyz_unit);
_F1_EQ_CHECK_LONG(tRPPositionRelativeCartesian->xvalue, f1_tRPPositionRelativeCartesian->xvalue);
_F1_EQ_CHECK_LONG(tRPPositionRelativeCartesian->yvalue, f1_tRPPositionRelativeCartesian->yvalue);
_F1_EQ_CHECK_LONG(tRPPositionRelativeCartesian->zvalue, f1_tRPPositionRelativeCartesian->zvalue);
const f1ap_location_uncertainty_t *f1_locationUncertainty_c = &f1_tRPPositionRelativeCartesian->location_uncertainty;
const f1ap_location_uncertainty_t *locationUncertainty_c = &tRPPositionRelativeCartesian->location_uncertainty;
_F1_EQ_CHECK_LONG(locationUncertainty_c->horizontal_uncertainty, f1_locationUncertainty_c->horizontal_uncertainty);
_F1_EQ_CHECK_LONG(locationUncertainty_c->horizontal_confidence, f1_locationUncertainty_c->horizontal_confidence);
_F1_EQ_CHECK_LONG(locationUncertainty_c->vertical_uncertainty, f1_locationUncertainty_c->vertical_uncertainty);
_F1_EQ_CHECK_LONG(locationUncertainty_c->vertical_confidence, f1_locationUncertainty_c->vertical_confidence);
break;
}
default:
AssertError(false, return false, "illegal trp reference point type entry %d\n", f1_referencePointType->present);
break;
}
return true;
}
static bool eq_trp_ha_pos(const f1ap_ngran_high_accuracy_access_point_position_t *trp_ha_pos,
const f1ap_ngran_high_accuracy_access_point_position_t *f1_trp_ha_pos)
{
_F1_EQ_CHECK_LONG(trp_ha_pos->latitude, f1_trp_ha_pos->latitude);
_F1_EQ_CHECK_LONG(trp_ha_pos->longitude, f1_trp_ha_pos->longitude);
_F1_EQ_CHECK_LONG(trp_ha_pos->altitude, f1_trp_ha_pos->altitude);
_F1_EQ_CHECK_LONG(trp_ha_pos->uncertainty_semi_major, f1_trp_ha_pos->uncertainty_semi_major);
_F1_EQ_CHECK_LONG(trp_ha_pos->uncertainty_semi_minor, f1_trp_ha_pos->uncertainty_semi_minor);
_F1_EQ_CHECK_LONG(trp_ha_pos->orientation_of_major_axis, f1_trp_ha_pos->orientation_of_major_axis);
_F1_EQ_CHECK_LONG(trp_ha_pos->horizontal_confidence, f1_trp_ha_pos->horizontal_confidence);
_F1_EQ_CHECK_LONG(trp_ha_pos->uncertainty_altitude, f1_trp_ha_pos->uncertainty_altitude);
_F1_EQ_CHECK_LONG(trp_ha_pos->vertical_confidence, f1_trp_ha_pos->vertical_confidence);
return true;
}
static bool eq_geographical_coordinates(const f1ap_geographical_coordinates_t *in, const f1ap_geographical_coordinates_t *out)
{
const f1ap_trp_position_definition_type_t *f1_trp_pos_def_type = &in->trp_position_definition_type;
const f1ap_trp_position_definition_type_t *trp_pos_def_type = &out->trp_position_definition_type;
_F1_EQ_CHECK_INT(f1_trp_pos_def_type->present, trp_pos_def_type->present);
switch (f1_trp_pos_def_type->present) {
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING:
// nothing to check
break;
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT: {
const f1ap_trp_position_direct_t *f1_direct = &f1_trp_pos_def_type->choice.direct;
const f1ap_trp_position_direct_t *direct = &trp_pos_def_type->choice.direct;
_F1_EQ_CHECK_INT(f1_direct->accuracy.present, direct->accuracy.present);
if (f1_direct->accuracy.present == F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION) {
const f1ap_access_point_position_t *trp_pos = &direct->accuracy.choice.trp_position;
const f1ap_access_point_position_t *f1_trp_pos = &f1_direct->accuracy.choice.trp_position;
_F1_EQ_CHECK_LONG(trp_pos->latitude_sign, f1_trp_pos->latitude_sign);
_F1_EQ_CHECK_LONG(trp_pos->latitude, f1_trp_pos->latitude);
_F1_EQ_CHECK_LONG(trp_pos->longitude, f1_trp_pos->longitude);
_F1_EQ_CHECK_LONG(trp_pos->direction_of_altitude, f1_trp_pos->direction_of_altitude);
_F1_EQ_CHECK_LONG(trp_pos->altitude, f1_trp_pos->altitude);
_F1_EQ_CHECK_LONG(trp_pos->uncertainty_semi_major, f1_trp_pos->uncertainty_semi_major);
_F1_EQ_CHECK_LONG(trp_pos->uncertainty_semi_minor, f1_trp_pos->uncertainty_semi_minor);
_F1_EQ_CHECK_LONG(trp_pos->orientation_of_major_axis, f1_trp_pos->orientation_of_major_axis);
_F1_EQ_CHECK_LONG(trp_pos->uncertainty_altitude, f1_trp_pos->uncertainty_altitude);
_F1_EQ_CHECK_LONG(trp_pos->confidence, f1_trp_pos->confidence);
} else if (f1_direct->accuracy.present == F1AP_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION) {
const f1ap_ngran_high_accuracy_access_point_position_t *trp_ha_pos = &direct->accuracy.choice.trp_HAposition;
const f1ap_ngran_high_accuracy_access_point_position_t *f1_trp_ha_pos = &f1_direct->accuracy.choice.trp_HAposition;
_F1_CHECK_EXP(eq_trp_ha_pos(trp_ha_pos, f1_trp_ha_pos));
} else {
AssertError(false, return false, "illegal direct accuracy entry %d\n", direct->accuracy.present);
}
break;
}
case F1AP_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED: {
const f1ap_trp_position_referenced_t *f1_referenced = &f1_trp_pos_def_type->choice.referenced;
const f1ap_trp_position_referenced_t *referenced = &trp_pos_def_type->choice.referenced;
const f1ap_reference_point_t *f1_referencePoint = &f1_referenced->reference_point;
const f1ap_reference_point_t *referencePoint = &referenced->reference_point;
_F1_EQ_CHECK_INT(f1_referencePoint->present, referencePoint->present);
if (f1_referencePoint->present == F1AP_REFERENCE_POINT_PR_COORDINATEID) {
_F1_EQ_CHECK_LONG(referencePoint->choice.coordinate_id, f1_referencePoint->choice.coordinate_id);
} else if (f1_referencePoint->present == F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE) {
const f1ap_access_point_position_t *referencePointCoordinate = &referencePoint->choice.reference_point_coordinate;
const f1ap_access_point_position_t *f1_referencePointCoordinate = &f1_referencePoint->choice.reference_point_coordinate;
_F1_EQ_CHECK_LONG(referencePointCoordinate->latitude_sign, f1_referencePointCoordinate->latitude_sign);
_F1_EQ_CHECK_LONG(referencePointCoordinate->latitude, f1_referencePointCoordinate->latitude);
_F1_EQ_CHECK_LONG(referencePointCoordinate->longitude, f1_referencePointCoordinate->longitude);
_F1_EQ_CHECK_LONG(referencePointCoordinate->direction_of_altitude, f1_referencePointCoordinate->direction_of_altitude);
_F1_EQ_CHECK_LONG(referencePointCoordinate->altitude, f1_referencePointCoordinate->altitude);
_F1_EQ_CHECK_LONG(referencePointCoordinate->uncertainty_semi_major, f1_referencePointCoordinate->uncertainty_semi_major);
_F1_EQ_CHECK_LONG(referencePointCoordinate->uncertainty_semi_minor, f1_referencePointCoordinate->uncertainty_semi_minor);
_F1_EQ_CHECK_LONG(referencePointCoordinate->orientation_of_major_axis,
f1_referencePointCoordinate->orientation_of_major_axis);
_F1_EQ_CHECK_LONG(referencePointCoordinate->uncertainty_altitude, f1_referencePointCoordinate->uncertainty_altitude);
_F1_EQ_CHECK_LONG(referencePointCoordinate->confidence, f1_referencePointCoordinate->confidence);
} else if (f1_referencePoint->present == F1AP_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA) {
const f1ap_ngran_high_accuracy_access_point_position_t *referencePointCoordinateHA =
&referencePoint->choice.reference_point_coordinateHA;
const f1ap_ngran_high_accuracy_access_point_position_t *f1_referencePointCoordinateHA =
&f1_referencePoint->choice.reference_point_coordinateHA;
_F1_CHECK_EXP(eq_trp_ha_pos(referencePointCoordinateHA, f1_referencePointCoordinateHA));
} else {
AssertError(false, return false, "illegal reference point entry %d\n", referencePoint->present);
}
const f1ap_trp_reference_point_type_t *f1_referencePointType = &f1_referenced->reference_point_type;
const f1ap_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type;
_F1_CHECK_EXP(eq_reference_point_type(f1_referencePointType, referencePointType));
break;
}
default:
AssertError(false, return false, "illegal Geographical Coordinates entry\n");
break;
}
return true;
}
static F1AP_TRPInformationTypeResponseItem_t encode_trp_info_type_response_item(const f1ap_trp_information_type_response_item_t *in)
{
F1AP_TRPInformationTypeResponseItem_t out = {0};
switch (in->present) {
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING:
out.present = F1AP_TRPInformationTypeResponseItem_PR_NOTHING;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR:
out.present = F1AP_TRPInformationTypeResponseItem_PR_pCI_NR;
out.choice.pCI_NR = in->choice.pci_nr;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI:
out.present = F1AP_TRPInformationTypeResponseItem_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));
NR_CELL_ID_TO_BIT_STRING(in->choice.ng_ran_cgi.nr_cellid, &(nG_RAN_CGI->nRCellIdentity));
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN:
out.present = F1AP_TRPInformationTypeResponseItem_PR_nRARFCN;
out.choice.nRARFCN = in->choice.nr_arfcn;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION:
out.present = F1AP_TRPInformationTypeResponseItem_PR_pRSConfiguration;
AssertFatal(false, "TRP information type response item PRS configuration unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION:
out.present = F1AP_TRPInformationTypeResponseItem_PR_sSBinformation;
AssertFatal(false, "TRP information type response item SSB Information unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME:
out.present = F1AP_TRPInformationTypeResponseItem_PR_sFNInitialisationTime;
AssertFatal(false, "TRP information type response item SFN Initialization Time unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION:
out.present = F1AP_TRPInformationTypeResponseItem_PR_spatialDirectionInformation;
AssertFatal(false, "TRP information type response item Spatial Direction Information unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES:
out.present = F1AP_TRPInformationTypeResponseItem_PR_geographicalCoordinates;
asn1cCalloc(out.choice.geographicalCoordinates, f1_geo_coord);
f1ap_geographical_coordinates_t geo_coord = in->choice.geographical_coordinates;
*f1_geo_coord = encode_geographical_coordinates(&geo_coord);
break;
default:
AssertFatal(false, "received illegal trp information type response item %d\n", in->present);
break;
}
return out;
}
static void decode_trp_info_type_response_item(const F1AP_TRPInformationTypeResponseItem_t *in,
f1ap_trp_information_type_response_item_t *out)
{
switch (in->present) {
case F1AP_TRPInformationTypeResponseItem_PR_NOTHING:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING;
break;
case F1AP_TRPInformationTypeResponseItem_PR_pCI_NR:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR;
out->choice.pci_nr = in->choice.pCI_NR;
break;
case F1AP_TRPInformationTypeResponseItem_PR_nG_RAN_CGI:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI;
// NR CGI (M)
PLMNID_TO_MCC_MNC(&(in->choice.nG_RAN_CGI->pLMN_Identity),
out->choice.ng_ran_cgi.plmn.mcc,
out->choice.ng_ran_cgi.plmn.mnc,
out->choice.ng_ran_cgi.plmn.mnc_digit_length);
// NR Cell Identity (M)
BIT_STRING_TO_NR_CELL_IDENTITY(&in->choice.nG_RAN_CGI->nRCellIdentity, out->choice.ng_ran_cgi.nr_cellid);
break;
case F1AP_TRPInformationTypeResponseItem_PR_nRARFCN:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN;
out->choice.nr_arfcn = in->choice.nRARFCN;
break;
case F1AP_TRPInformationTypeResponseItem_PR_pRSConfiguration:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION;
AssertFatal(false, "TRP information type response item PRS configuration unsupported\n");
break;
case F1AP_TRPInformationTypeResponseItem_PR_sSBinformation:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION;
AssertFatal(false, "TRP information type response item SSB Information unsupported\n");
break;
case F1AP_TRPInformationTypeResponseItem_PR_sFNInitialisationTime:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME;
AssertFatal(false, "TRP information type response item SFN Initialization Time unsupported\n");
break;
case F1AP_TRPInformationTypeResponseItem_PR_spatialDirectionInformation:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION;
AssertFatal(false, "TRP information type response item Spatial Direction Information unsupported\n");
break;
case F1AP_TRPInformationTypeResponseItem_PR_geographicalCoordinates:
out->present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES;
decode_geographical_coordinates(in->choice.geographicalCoordinates, &out->choice.geographical_coordinates);
break;
default:
AssertFatal(false, "received illegal trp information type response item %d\n", in->present);
break;
}
}
static f1ap_trp_information_type_response_item_t cp_trp_info_type_response_item(const f1ap_trp_information_type_response_item_t *in)
{
f1ap_trp_information_type_response_item_t out = {0};
switch (in->present) {
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR;
out.choice.pci_nr = in->choice.pci_nr;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI;
out.choice.ng_ran_cgi.plmn.mcc = in->choice.ng_ran_cgi.plmn.mcc;
out.choice.ng_ran_cgi.plmn.mnc = in->choice.ng_ran_cgi.plmn.mnc;
out.choice.ng_ran_cgi.plmn.mnc_digit_length = in->choice.ng_ran_cgi.plmn.mnc_digit_length;
out.choice.ng_ran_cgi.nr_cellid = in->choice.ng_ran_cgi.nr_cellid;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN;
out.choice.nr_arfcn = in->choice.nr_arfcn;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION;
AssertFatal(false, "TRP information type response item PRS configuration unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION;
AssertFatal(false, "TRP information type response item SSB Information unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME;
AssertFatal(false, "TRP information type response item SFN Initialization Time unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION;
AssertFatal(false, "TRP information type response item Spatial Direction Information unsupported\n");
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES:
out.present = F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES;
out.choice.geographical_coordinates = cp_geographical_coordinates(&in->choice.geographical_coordinates);
break;
default:
AssertFatal(false, "received illegal trp information type response item %d\n", in->present);
break;
}
return out;
}
static bool eq_trp_info_type_response_item(const f1ap_trp_information_type_response_item_t *in,
const f1ap_trp_information_type_response_item_t *out)
{
_F1_EQ_CHECK_INT(in->present, out->present);
switch (in->present) {
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING:
// nothing to check
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR:
_F1_EQ_CHECK_INT(in->choice.pci_nr, out->choice.pci_nr);
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI:
_F1_EQ_CHECK_INT(in->choice.ng_ran_cgi.plmn.mcc, out->choice.ng_ran_cgi.plmn.mcc);
_F1_EQ_CHECK_INT(in->choice.ng_ran_cgi.plmn.mnc, out->choice.ng_ran_cgi.plmn.mnc);
_F1_EQ_CHECK_INT(in->choice.ng_ran_cgi.plmn.mnc_digit_length, out->choice.ng_ran_cgi.plmn.mnc_digit_length);
_F1_EQ_CHECK_LONG(in->choice.ng_ran_cgi.nr_cellid, out->choice.ng_ran_cgi.nr_cellid);
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN:
_F1_EQ_CHECK_INT(in->choice.nr_arfcn, out->choice.nr_arfcn);
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION:
PRINT_ERROR("TRP information type response item PRS configuration unsupported\n");
return false;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION:
PRINT_ERROR("TRP information type response item SSB Information unsupported\n");
return false;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME:
PRINT_ERROR("TRP information type response item SFN Initialization Time unsupported\n");
return false;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION:
PRINT_ERROR("TRP information type response item Spatial Direction Information unsupported\n");
return false;
break;
case F1AP_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES:
_F1_CHECK_EXP(eq_geographical_coordinates(&in->choice.geographical_coordinates, &out->choice.geographical_coordinates));
break;
default:
PRINT_ERROR("received illegal trp information type response item %d\n", in->present);
return false;
break;
}
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
*/
F1AP_F1AP_PDU_t *encode_positioning_information_req(const f1ap_positioning_information_req_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningInformationExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_InitiatingMessage__value_PR_PositioningInformationRequest;
F1AP_PositioningInformationRequest_t *out = &tmp->value.choice.PositioningInformationRequest;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationRequestIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningInformationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningInformationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
return pdu;
}
/**
* @brief Decode F1 positioning information request
*/
bool decode_positioning_information_req(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_information_req_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningInformationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.PositioningInformationRequest;
F1AP_PositioningInformationRequestIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningInformationRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_RequestedSRSTransmissionCharacteristics:
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 information request deep copy
*/
f1ap_positioning_information_req_t cp_positioning_information_req(const f1ap_positioning_information_req_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_information_req_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
};
return cp;
}
/**
* @brief F1 positioning information request equality check
*/
bool eq_positioning_information_req(const f1ap_positioning_information_req_t *a, const f1ap_positioning_information_req_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
return true;
}
/**
* @brief Free Allocated F1 positioning information request
*/
void free_positioning_information_req(f1ap_positioning_information_req_t *msg)
{
// nothing to free
}
/**
* @brief Encode F1 positioning information response to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_information_resp(const f1ap_positioning_information_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_PositioningInformationExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_PositioningInformationResponse;
F1AP_PositioningInformationResponse_t *out = &tmp->value.choice.PositioningInformationResponse;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationResponseIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningInformationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationResponseIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningInformationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* optional : SRSConfiguration */
if (msg->srs_configuration) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationResponseIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_SRSConfiguration;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_PositioningInformationResponseIEs__value_PR_SRSConfiguration;
f1ap_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list;
ie3->value.choice.SRSConfiguration.sRSCarrier_List = encode_srs_carrier_list(srs_carrier_list);
}
return pdu;
}
/**
* @brief Decode F1 positioning information response
*/
bool decode_positioning_information_resp(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_information_resp_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningInformationResponse_t *in = &pdu->choice.successfulOutcome->value.choice.PositioningInformationResponse;
F1AP_PositioningInformationResponseIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningInformationResponseIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationResponseIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationResponseIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_SRSConfiguration,
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_SRSConfiguration:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationResponseIEs__value_PR_SRSConfiguration);
F1AP_SRSCarrier_List_t *f1_sRSCarrier_List = &ie->value.choice.SRSConfiguration.sRSCarrier_List;
out->srs_configuration = calloc_or_fail(1, sizeof(*out->srs_configuration));
f1ap_srs_carrier_list_t *srs_carrier_list = &out->srs_configuration->srs_carrier_list;
decode_srs_carrier_list(srs_carrier_list, f1_sRSCarrier_List);
break;
case F1AP_ProtocolIE_ID_id_SFNInitialisationTime:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
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 information response deep copy
*/
f1ap_positioning_information_resp_t cp_positioning_information_resp(const f1ap_positioning_information_resp_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_information_resp_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
};
/* optional: SRS Configuration */
if (orig->srs_configuration) {
cp.srs_configuration = calloc_or_fail(1, sizeof(*cp.srs_configuration));
f1ap_srs_carrier_list_t *srs_carrier_list_cp = &cp.srs_configuration->srs_carrier_list;
f1ap_srs_carrier_list_t *srs_carrier_list = &orig->srs_configuration->srs_carrier_list;
*srs_carrier_list_cp = cp_srs_carrier_list(srs_carrier_list);
}
return cp;
}
/**
* @brief F1 positioning information response equality check
*/
bool eq_positioning_information_resp(const f1ap_positioning_information_resp_t *a, const f1ap_positioning_information_resp_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
/* optional: SRS Configuration (O) */
if ((a->srs_configuration == NULL) != (b->srs_configuration == NULL)) {
return false;
}
if (a->srs_configuration) {
f1ap_srs_carrier_list_t *srs_carrier_list_a = &a->srs_configuration->srs_carrier_list;
f1ap_srs_carrier_list_t *srs_carrier_list_b = &b->srs_configuration->srs_carrier_list;
_F1_CHECK_EXP(eq_srs_carrier_list(srs_carrier_list_a, srs_carrier_list_b));
}
return true;
}
/**
* @brief Free Allocated F1 positioning information response
*/
void free_positioning_information_resp(f1ap_positioning_information_resp_t *msg)
{
/* SRS Configuration (O) */
if (msg->srs_configuration) {
f1ap_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list;
free_srs_carrier_list(srs_carrier_list);
free(msg->srs_configuration);
}
}
/**
* @brief Encode F1 positioning information failure to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_information_failure(const f1ap_positioning_information_failure_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
asn1cCalloc(pdu->choice.unsuccessfulOutcome, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningInformationExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_PositioningInformationFailure;
F1AP_PositioningInformationFailure_t *out = &tmp->value.choice.PositioningInformationFailure;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationFailureIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningInformationFailureIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationFailureIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningInformationFailureIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* mandatory : Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationFailureIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_Cause;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_PositioningInformationFailureIEs__value_PR_Cause;
ie3->value.choice.Cause = encode_f1ap_cause(msg->cause, msg->cause_value);
return pdu;
}
/**
* @brief Decode F1 positioning information failure
*/
bool decode_positioning_information_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_information_failure_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningInformationFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.PositioningInformationFailure;
F1AP_PositioningInformationFailureIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningInformationFailureIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationFailureIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationFailureIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_Cause, true);
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationFailureIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationFailureIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationFailureIEs__value_PR_Cause);
_F1_CHECK_EXP(decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value));
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 information failure deep copy
*/
f1ap_positioning_information_failure_t cp_positioning_information_failure(const f1ap_positioning_information_failure_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_information_failure_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
.cause = orig->cause,
.cause_value = orig->cause_value,
};
return cp;
}
/**
* @brief F1 positioning information failure equality check
*/
bool eq_positioning_information_failure(const f1ap_positioning_information_failure_t *a,
const f1ap_positioning_information_failure_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
return true;
}
/**
* @brief Free Allocated F1 positioning information failure
*/
void free_positioning_information_failure(f1ap_positioning_information_failure_t *msg)
{
// nothing to free
}
/**
* @brief Encode F1 positioning activation request to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_activation_req(const f1ap_positioning_activation_req_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningActivation;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_InitiatingMessage__value_PR_PositioningActivationRequest;
F1AP_PositioningActivationRequest_t *out = &tmp->value.choice.PositioningActivationRequest;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationRequestIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningActivationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningActivationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* mandatory : SRS type */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationRequestIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_SRSType;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_PositioningActivationRequestIEs__value_PR_SRSType;
ie3->value.choice.SRSType = encode_f1ap_srstype(&msg->srs_type);
return pdu;
}
/**
* @brief Decode F1 positioning activation request
*/
bool decode_positioning_activation_req(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_activation_req_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningActivationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.PositioningActivationRequest;
F1AP_PositioningActivationRequestIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningActivationRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningActivationRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningActivationRequestIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_SRSType, true);
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_SRSType:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationRequestIEs__value_PR_SRSType);
_F1_CHECK_EXP(decode_f1ap_srstype(&ie->value.choice.SRSType, &out->srs_type));
break;
case F1AP_ProtocolIE_ID_id_ActivationTime:
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 activation request deep copy
*/
f1ap_positioning_activation_req_t cp_positioning_activation_req(const f1ap_positioning_activation_req_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_activation_req_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
.srs_type.present = orig->srs_type.present,
};
switch (orig->srs_type.present) {
case F1AP_SRS_TYPE_PR_NOTHING:
// nothing to copy
break;
case F1AP_SRS_TYPE_PR_SEMIPERSISTENTSRS:
cp.srs_type.choice.srs_resource_set_id = calloc_or_fail(1, sizeof(*cp.srs_type.choice.srs_resource_set_id));
*cp.srs_type.choice.srs_resource_set_id = *orig->srs_type.choice.srs_resource_set_id;
break;
case F1AP_SRS_TYPE_PR_APERIODICSRS:
cp.srs_type.choice.aperiodic = calloc_or_fail(1, sizeof(*cp.srs_type.choice.aperiodic));
*cp.srs_type.choice.aperiodic = *orig->srs_type.choice.aperiodic;
break;
default:
PRINT_ERROR("received illegal SRS type %d\n", orig->srs_type.present);
break;
}
return cp;
}
/**
* @brief F1 positioning activation request equality check
*/
bool eq_positioning_activation_req(const f1ap_positioning_activation_req_t *a, const f1ap_positioning_activation_req_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->srs_type.present, b->srs_type.present);
const f1ap_srs_type_t *srs_type_a = &a->srs_type;
const f1ap_srs_type_t *srs_type_b = &b->srs_type;
switch (srs_type_a->present) {
case F1AP_SRS_TYPE_PR_NOTHING:
// nothing to check
break;
case F1AP_SRS_TYPE_PR_SEMIPERSISTENTSRS:
_F1_EQ_CHECK_INT(*srs_type_a->choice.srs_resource_set_id, *srs_type_b->choice.srs_resource_set_id);
break;
case F1AP_SRS_TYPE_PR_APERIODICSRS:
_F1_EQ_CHECK_INT(*srs_type_a->choice.aperiodic, *srs_type_b->choice.aperiodic);
break;
default:
PRINT_ERROR("received illegal SRS type %d\n", srs_type_a->present);
break;
}
return true;
}
/**
* @brief Free Allocated F1 activation request
*/
void free_positioning_activation_req(f1ap_positioning_activation_req_t *msg)
{
DevAssert(msg != NULL);
switch (msg->srs_type.present) {
case F1AP_SRS_TYPE_PR_NOTHING:
// nothing to free
return;
case F1AP_SRS_TYPE_PR_SEMIPERSISTENTSRS:
free(msg->srs_type.choice.srs_resource_set_id);
break;
case F1AP_SRS_TYPE_PR_APERIODICSRS:
free(msg->srs_type.choice.aperiodic);
break;
default:
PRINT_ERROR("received illegal SRS type %d\n", msg->srs_type.present);
break;
}
}
/**
* @brief Encode F1 positioning activation response to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_activation_resp(const f1ap_positioning_activation_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_PositioningActivation;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_PositioningActivationResponse;
F1AP_PositioningActivationResponse_t *out = &tmp->value.choice.PositioningActivationResponse;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationResponseIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningActivationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationResponseIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningActivationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
return pdu;
}
/**
* @brief Decode F1 positioning activation response
*/
bool decode_positioning_activation_resp(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_activation_resp_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningActivationResponse_t *in = &pdu->choice.successfulOutcome->value.choice.PositioningActivationResponse;
F1AP_PositioningActivationResponseIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningActivationResponseIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningActivationResponseIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_SystemFrameNumber:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
break;
case F1AP_ProtocolIE_ID_id_SlotNumber:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not handled, skipping\n", ie->id);
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 activation response deep copy
*/
f1ap_positioning_activation_resp_t cp_positioning_activation_resp(const f1ap_positioning_activation_resp_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_activation_resp_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
};
return cp;
}
/**
* @brief F1 positioning activation response equality check
*/
bool eq_positioning_activation_resp(const f1ap_positioning_activation_resp_t *a, const f1ap_positioning_activation_resp_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
return true;
}
/**
* @brief Free Allocated F1 positioning activation response
*/
void free_positioning_activation_resp(f1ap_positioning_activation_resp_t *msg)
{
// nothing to free
}
/**
* @brief Encode F1 positioning activation failure to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_activation_failure(const f1ap_positioning_activation_failure_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
asn1cCalloc(pdu->choice.unsuccessfulOutcome, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningActivation;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_PositioningActivationFailure;
F1AP_PositioningActivationFailure_t *out = &tmp->value.choice.PositioningActivationFailure;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationFailureIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningActivationFailureIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationFailureIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningActivationFailureIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* mandatory : Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningActivationFailureIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_Cause;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_PositioningActivationFailureIEs__value_PR_Cause;
ie3->value.choice.Cause = encode_f1ap_cause(msg->cause, msg->cause_value);
return pdu;
}
/**
* @brief Decode F1 positioning activation failure
*/
bool decode_positioning_activation_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_activation_failure_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningActivationFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.PositioningActivationFailure;
F1AP_PositioningActivationFailureIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningActivationFailureIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningActivationFailureIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningActivationFailureIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_Cause, true);
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationFailureIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationFailureIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningActivationFailureIEs__value_PR_Cause);
_F1_CHECK_EXP(decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value));
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 activation failure deep copy
*/
f1ap_positioning_activation_failure_t cp_positioning_activation_failure(const f1ap_positioning_activation_failure_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_activation_failure_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
.cause = orig->cause,
.cause_value = orig->cause_value,
};
return cp;
}
/**
* @brief F1 positioning activation failure equality check
*/
bool eq_positioning_activation_failure(const f1ap_positioning_activation_failure_t *a,
const f1ap_positioning_activation_failure_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
return true;
}
/**
* @brief Free Allocated F1 positioning activation failure
*/
void free_positioning_activation_failure(f1ap_positioning_activation_failure_t *msg)
{
// nothing to free
}
/**
* @brief Encode F1 positioning deactivation to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_deactivation(const f1ap_positioning_deactivation_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningDeactivation;
tmp->criticality = F1AP_Criticality_ignore;
tmp->value.present = F1AP_InitiatingMessage__value_PR_PositioningDeactivation;
F1AP_PositioningDeactivation_t *out = &tmp->value.choice.PositioningDeactivation;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningDeactivationIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningDeactivationIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningDeactivationIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningDeactivationIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* mandatory : CHOICE ABORT TRANSMISSION */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningDeactivationIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_AbortTransmission;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_PositioningDeactivationIEs__value_PR_AbortTransmission;
ie3->value.choice.AbortTransmission = encode_f1ap_abort_transmission(&msg->abort_transmission);
return pdu;
}
/**
* @brief Decode F1 positioning deactivation
*/
bool decode_positioning_deactivation(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_deactivation_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningDeactivation_t *in = &pdu->choice.initiatingMessage->value.choice.PositioningDeactivation;
F1AP_PositioningDeactivationIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningDeactivationIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
F1AP_LIB_FIND_IE(F1AP_PositioningDeactivationIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
F1AP_LIB_FIND_IE(F1AP_PositioningDeactivationIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_AbortTransmission, true);
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningDeactivationIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningDeactivationIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_AbortTransmission:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningDeactivationIEs__value_PR_AbortTransmission);
_F1_CHECK_EXP(decode_f1ap_abort_transmission(&ie->value.choice.AbortTransmission, &out->abort_transmission));
break;
default:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld unknown, skipping\n", ie->id);
break;
}
}
return true;
}
/**
* @brief F1 positioning deactivation deep copy
*/
f1ap_positioning_deactivation_t cp_positioning_deactivation(const f1ap_positioning_deactivation_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_deactivation_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
.abort_transmission.present = orig->abort_transmission.present,
};
// do this properly abort mission
switch (orig->abort_transmission.present) {
case F1AP_ABORT_TRANSMISSION_PR_NOTHING:
// nothing to copy
break;
case F1AP_ABORT_TRANSMISSION_PR_SRSRESOURCESETID:
cp.abort_transmission.choice.srs_resource_set_id = orig->abort_transmission.choice.srs_resource_set_id;
break;
case F1AP_ABORT_TRANSMISSION_PR_RELEASEALL:
cp.abort_transmission.choice.release_all = orig->abort_transmission.choice.release_all;
break;
default:
PRINT_ERROR("received illegal Abort Transmission value %d\n", orig->abort_transmission.present);
break;
}
return cp;
}
/**
* @brief F1 positioning deactivation equality check
*/
bool eq_positioning_deactivation(const f1ap_positioning_deactivation_t *a, const f1ap_positioning_deactivation_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
_F1_EQ_CHECK_INT(a->abort_transmission.present, b->abort_transmission.present);
switch (a->abort_transmission.present) {
case F1AP_ABORT_TRANSMISSION_PR_NOTHING:
// nothing to check
break;
case F1AP_ABORT_TRANSMISSION_PR_SRSRESOURCESETID:
_F1_EQ_CHECK_INT(a->abort_transmission.choice.srs_resource_set_id, b->abort_transmission.choice.srs_resource_set_id);
break;
case F1AP_ABORT_TRANSMISSION_PR_RELEASEALL:
_F1_EQ_CHECK_INT(a->abort_transmission.choice.release_all, b->abort_transmission.choice.release_all);
break;
default:
PRINT_ERROR("received illegal Abort Transmission value %d\n", a->abort_transmission.present);
break;
}
return true;
}
/**
* @brief Free Allocated F1 positioning activation failure
*/
void free_positioning_deactivation(f1ap_positioning_deactivation_t *msg)
{
// nothing to free
}
/**
* @brief Encode F1 positioning information update to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_information_update(const f1ap_positioning_information_update_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningInformationUpdate;
tmp->criticality = F1AP_Criticality_ignore;
tmp->value.present = F1AP_InitiatingMessage__value_PR_PositioningInformationUpdate;
F1AP_PositioningInformationUpdate_t *out = &tmp->value.choice.PositioningInformationUpdate;
/* mandatory : GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationUpdateIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningInformationUpdateIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id;
/* mandatory : GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationUpdateIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningInformationUpdateIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id;
/* optional : SRSConfiguration */
if (msg->srs_configuration) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningInformationUpdateIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_SRSConfiguration;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_PositioningInformationUpdateIEs__value_PR_SRSConfiguration;
f1ap_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list;
ie3->value.choice.SRSConfiguration.sRSCarrier_List = encode_srs_carrier_list(srs_carrier_list);
}
return pdu;
}
/**
* @brief Decode F1 positioning information update
*/
bool decode_positioning_information_update(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_information_update_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningInformationUpdate_t *in = &pdu->choice.initiatingMessage->value.choice.PositioningInformationUpdate;
F1AP_PositioningInformationUpdateIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningInformationUpdateIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationUpdateIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningInformationUpdateIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_SRSConfiguration,
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_gNB_CU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationUpdateIEs__value_PR_GNB_CU_UE_F1AP_ID);
out->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationUpdateIEs__value_PR_GNB_DU_UE_F1AP_ID);
out->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
break;
case F1AP_ProtocolIE_ID_id_SRSConfiguration:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningInformationUpdateIEs__value_PR_SRSConfiguration);
F1AP_SRSCarrier_List_t *f1_sRSCarrier_List = &ie->value.choice.SRSConfiguration.sRSCarrier_List;
out->srs_configuration = calloc_or_fail(1, sizeof(*out->srs_configuration));
f1ap_srs_carrier_list_t *srs_carrier_list = &out->srs_configuration->srs_carrier_list;
decode_srs_carrier_list(srs_carrier_list, f1_sRSCarrier_List);
break;
case F1AP_ProtocolIE_ID_id_SFNInitialisationTime:
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 information update deep copy
*/
f1ap_positioning_information_update_t cp_positioning_information_update(const f1ap_positioning_information_update_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_information_update_t cp = {
.gNB_CU_ue_id = orig->gNB_CU_ue_id,
.gNB_DU_ue_id = orig->gNB_DU_ue_id,
};
/* optional: SRS Configuration */
if (orig->srs_configuration) {
cp.srs_configuration = calloc_or_fail(1, sizeof(*cp.srs_configuration));
f1ap_srs_carrier_list_t *srs_carrier_list_cp = &cp.srs_configuration->srs_carrier_list;
f1ap_srs_carrier_list_t *srs_carrier_list = &orig->srs_configuration->srs_carrier_list;
*srs_carrier_list_cp = cp_srs_carrier_list(srs_carrier_list);
}
return cp;
}
/**
* @brief F1 positioning information update equality check
*/
bool eq_positioning_information_update(const f1ap_positioning_information_update_t *a,
const f1ap_positioning_information_update_t *b)
{
_F1_EQ_CHECK_INT(a->gNB_CU_ue_id, b->gNB_CU_ue_id);
_F1_EQ_CHECK_INT(a->gNB_DU_ue_id, b->gNB_DU_ue_id);
/* optional: SRS Configuration */
if ((a->srs_configuration == NULL) != (b->srs_configuration == NULL)) {
return false;
}
if (a->srs_configuration) {
f1ap_srs_carrier_list_t *srs_carrier_list_a = &a->srs_configuration->srs_carrier_list;
f1ap_srs_carrier_list_t *srs_carrier_list_b = &b->srs_configuration->srs_carrier_list;
_F1_CHECK_EXP(eq_srs_carrier_list(srs_carrier_list_a, srs_carrier_list_b));
}
return true;
}
/**
* @brief Free Allocated F1 positioning information update
*/
void free_positioning_information_update(f1ap_positioning_information_update_t *msg)
{
/* optional: SRS Configuration */
if (msg->srs_configuration) {
f1ap_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list;
free_srs_carrier_list(srs_carrier_list);
free(msg->srs_configuration);
}
}
/**
* @brief Encode F1 TRP information request to ASN.1
*/
F1AP_F1AP_PDU_t *encode_trp_information_req(const f1ap_trp_information_req_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_TRPInformationExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_InitiatingMessage__value_PR_TRPInformationRequest;
F1AP_TRPInformationRequest_t *out = &tmp->value.choice.TRPInformationRequest;
/* mandatory : TransactionID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationRequestIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_TRPInformationRequestIEs__value_PR_TransactionID;
ie1->value.choice.TransactionID = msg->transaction_id;
/* TRPList */
if (msg->has_trp_list) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_TRPList;
ie2->criticality = F1AP_Criticality_ignore;
ie2->value.present = F1AP_TRPInformationRequestIEs__value_PR_TRPList;
for (int i = 0; i < msg->trp_list.trp_list_length; i++) {
// mandatory : TRP List Item (M)
asn1cSequenceAdd(ie2->value.choice.TRPList.list, F1AP_TRPListItem_t, trplistitem);
trplistitem->tRPID = msg->trp_list.trp_list_item[i].trp_id;
}
}
/* mandatory : TRPInformationTypeList */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationRequestIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_TRPInformationTypeListTRPReq;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_TRPInformationRequestIEs__value_PR_TRPInformationTypeListTRPReq;
for (int i = 0; i < msg->trp_information_type_list.trp_information_type_list_length; i++) {
// TRPInformationTypeItem (M)
asn1cSequenceAdd(ie3->value.choice.TRPInformationTypeListTRPReq.list, F1AP_TRPInformationTypeItemTRPReq_t, trpinfotypeitem);
trpinfotypeitem->id = F1AP_ProtocolIE_ID_id_TRPInformationTypeItem;
trpinfotypeitem->criticality = F1AP_Criticality_reject;
trpinfotypeitem->value.present = F1AP_TRPInformationTypeItemTRPReq__value_PR_TRPInformationTypeItem;
trpinfotypeitem->value.choice.TRPInformationTypeItem = msg->trp_information_type_list.trp_information_type_item[i];
}
return pdu;
}
/**
* @brief Decode F1 TRP information request
*/
bool decode_trp_information_req(const F1AP_F1AP_PDU_t *pdu, f1ap_trp_information_req_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_TRPInformationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.TRPInformationRequest;
F1AP_TRPInformationRequestIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_TRPInformationRequestIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_LIB_FIND_IE(F1AP_TRPInformationRequestIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TRPList, true);
F1AP_LIB_FIND_IE(F1AP_TRPInformationRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_TRPInformationTypeListTRPReq,
true);
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_TRPInformationRequestIEs__value_PR_TransactionID);
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_TRPList:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_TRPInformationRequestIEs__value_PR_TRPList);
out->has_trp_list = true;
uint32_t trp_list_length = ie->value.choice.TRPList.list.count;
AssertError(trp_list_length > 0, return false, "at least 1 TRP must be present");
out->trp_list.trp_list_length = trp_list_length;
out->trp_list.trp_list_item = calloc_or_fail(trp_list_length, sizeof(*out->trp_list.trp_list_item));
F1AP_TRPList_t *TRPList = &ie->value.choice.TRPList;
for (int i = 0; i < trp_list_length; i++) {
out->trp_list.trp_list_item[i].trp_id = TRPList->list.array[i]->tRPID;
}
break;
case F1AP_ProtocolIE_ID_id_TRPInformationTypeListTRPReq:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_TRPInformationRequestIEs__value_PR_TRPInformationTypeListTRPReq);
uint8_t trp_info_type_list_length = ie->value.choice.TRPInformationTypeListTRPReq.list.count;
AssertError(trp_info_type_list_length > 0, return false, "at least 1 TRP Information Type must be present");
f1ap_trp_information_type_list_t *trp_information_type_list = &out->trp_information_type_list;
trp_information_type_list->trp_information_type_list_length = trp_info_type_list_length;
trp_information_type_list->trp_information_type_item =
calloc_or_fail(trp_info_type_list_length, sizeof(*trp_information_type_list->trp_information_type_item));
for (int i = 0; i < trp_info_type_list_length; i++) {
F1AP_TRPInformationTypeItemTRPReq_t *f1_trpinfotypeitem =
(F1AP_TRPInformationTypeItemTRPReq_t *)ie->value.choice.TRPInformationTypeListTRPReq.list.array[i];
_F1_EQ_CHECK_LONG(f1_trpinfotypeitem->id, F1AP_ProtocolIE_ID_id_TRPInformationTypeItem);
_F1_EQ_CHECK_INT(f1_trpinfotypeitem->value.present, F1AP_TRPInformationTypeItemTRPReq__value_PR_TRPInformationTypeItem);
trp_information_type_list->trp_information_type_item[i] = f1_trpinfotypeitem->value.choice.TRPInformationTypeItem;
}
break;
default:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld unknown, skipping\n", ie->id);
break;
}
}
return true;
}
/**
* @brief F1 TRP information request deep copy
*/
f1ap_trp_information_req_t cp_trp_information_req(const f1ap_trp_information_req_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_trp_information_req_t cp = {
.transaction_id = orig->transaction_id,
.has_trp_list = orig->has_trp_list,
};
if (orig->has_trp_list) {
uint32_t trp_list_length = orig->trp_list.trp_list_length;
cp.trp_list.trp_list_length = trp_list_length;
cp.trp_list.trp_list_item = calloc_or_fail(trp_list_length, sizeof(*cp.trp_list.trp_list_item));
for (int i = 0; i < trp_list_length; i++) {
cp.trp_list.trp_list_item[i].trp_id = orig->trp_list.trp_list_item[i].trp_id;
}
}
const f1ap_trp_information_type_list_t *trp_information_type_list = &orig->trp_information_type_list;
f1ap_trp_information_type_list_t *trp_information_type_list_cp = &cp.trp_information_type_list;
uint8_t trp_info_type_list_length = trp_information_type_list->trp_information_type_list_length;
trp_information_type_list_cp->trp_information_type_list_length = trp_info_type_list_length;
trp_information_type_list_cp->trp_information_type_item =
calloc_or_fail(trp_info_type_list_length, sizeof(*trp_information_type_list_cp->trp_information_type_item));
for (int i = 0; i < trp_info_type_list_length; i++) {
trp_information_type_list_cp->trp_information_type_item[i] = trp_information_type_list->trp_information_type_item[i];
}
return cp;
}
/**
* @brief F1 TRP information request equality check
*/
bool eq_trp_information_req(const f1ap_trp_information_req_t *a, const f1ap_trp_information_req_t *b)
{
_F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
_F1_EQ_CHECK_INT(a->has_trp_list, b->has_trp_list);
if (a->has_trp_list) {
_F1_EQ_CHECK_INT(a->trp_list.trp_list_length, b->trp_list.trp_list_length);
for (int i = 0; i < a->trp_list.trp_list_length; i++) {
_F1_EQ_CHECK_INT(a->trp_list.trp_list_item[i].trp_id, b->trp_list.trp_list_item[i].trp_id);
}
}
const f1ap_trp_information_type_list_t *trp_information_type_list_a = &a->trp_information_type_list;
const f1ap_trp_information_type_list_t *trp_information_type_list_b = &b->trp_information_type_list;
_F1_EQ_CHECK_INT(trp_information_type_list_a->trp_information_type_list_length,
trp_information_type_list_b->trp_information_type_list_length);
for (int i = 0; i < trp_information_type_list_a->trp_information_type_list_length; i++) {
_F1_EQ_CHECK_INT(trp_information_type_list_a->trp_information_type_item[i],
trp_information_type_list_b->trp_information_type_item[i]);
}
return true;
}
/**
* @brief Free Allocated F1 TRP information request
*/
void free_trp_information_req(f1ap_trp_information_req_t *msg)
{
if (msg->has_trp_list) {
free(msg->trp_list.trp_list_item);
}
free(msg->trp_information_type_list.trp_information_type_item);
}
/**
* @brief Encode F1 TRP information response to ASN.1
*/
F1AP_F1AP_PDU_t *encode_trp_information_resp(const f1ap_trp_information_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_TRPInformationExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_TRPInformationResponse;
F1AP_TRPInformationResponse_t *out = &tmp->value.choice.TRPInformationResponse;
/* mandatory : TransactionID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationResponseIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_TRPInformationResponseIEs__value_PR_TransactionID;
ie1->value.choice.TransactionID = msg->transaction_id;
/* mandatory : TRPInformationList */
// Supported : NR PCI, NG-RAN CGI, NR ARFCN, Geogarphical Coordinates
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationResponseIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_TRPInformationListTRPResp;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_TRPInformationResponseIEs__value_PR_TRPInformationListTRPResp;
uint32_t trp_info_item_len = msg->trp_information_list.trp_information_item_length;
for (int i = 0; i < trp_info_item_len; i++) {
// TRPInformationItem (M)
asn1cSequenceAdd(ie3->value.choice.TRPInformationListTRPResp.list, F1AP_TRPInformationItemTRPResp_t, trpinfolist);
trpinfolist->id = F1AP_ProtocolIE_ID_id_TRPInformationItem;
trpinfolist->criticality = F1AP_Criticality_ignore;
trpinfolist->value.present = F1AP_TRPInformationItemTRPResp__value_PR_TRPInformationItem;
F1AP_TRPInformationItem_t *trp_info_item = &trpinfolist->value.choice.TRPInformationItem;
F1AP_TRPInformation_t *trp_info = &trp_info_item->tRPInformation;
f1ap_trp_information_t *tRPInformation = &msg->trp_information_list.trp_information_item[i];
trp_info->tRPID = tRPInformation->trp_id;
f1ap_trp_information_type_response_list_t *tRPInformationTypeResponseList = &tRPInformation->trp_information_type_response_list;
uint8_t trp_item_len = tRPInformationTypeResponseList->trp_information_type_response_item_length;
for (int j = 0; j < trp_item_len; j++) {
asn1cSequenceAdd(trp_info->tRPInformationTypeResponseList, F1AP_TRPInformationTypeResponseItem_t, trp_resp_item);
*trp_resp_item = encode_trp_info_type_response_item(&tRPInformationTypeResponseList->trp_information_type_response_item[j]);
}
}
return pdu;
}
/**
* @brief Decode F1 TRP information response
*/
bool decode_trp_information_resp(const F1AP_F1AP_PDU_t *pdu, f1ap_trp_information_resp_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_TRPInformationResponse_t *in = &pdu->choice.successfulOutcome->value.choice.TRPInformationResponse;
F1AP_TRPInformationResponseIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_TRPInformationResponseIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_LIB_FIND_IE(F1AP_TRPInformationResponseIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_TRPInformationListTRPResp,
true);
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_TRPInformationResponseIEs__value_PR_TransactionID);
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_TRPInformationListTRPResp:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_TRPInformationResponseIEs__value_PR_TRPInformationListTRPResp);
uint32_t trp_info_item_length = ie->value.choice.TRPInformationListTRPResp.list.count;
AssertError(trp_info_item_length > 0, return false, "at least 1 TRP Information Item must be present");
out->trp_information_list.trp_information_item_length = trp_info_item_length;
f1ap_trp_information_t *trp_info_item = calloc_or_fail(trp_info_item_length, sizeof(*trp_info_item));
out->trp_information_list.trp_information_item = trp_info_item;
for (int i = 0; i < trp_info_item_length; i++) {
F1AP_TRPInformationItemTRPResp_t *f1_trpinfolist =
(F1AP_TRPInformationItemTRPResp_t *)ie->value.choice.TRPInformationListTRPResp.list.array[i];
_F1_EQ_CHECK_LONG(f1_trpinfolist->id, F1AP_ProtocolIE_ID_id_TRPInformationItem);
_F1_EQ_CHECK_INT(f1_trpinfolist->value.present, F1AP_TRPInformationItemTRPResp__value_PR_TRPInformationItem);
F1AP_TRPInformationItem_t *f1_trp_info_item = &f1_trpinfolist->value.choice.TRPInformationItem;
F1AP_TRPInformation_t *f1_trp_info = &f1_trp_info_item->tRPInformation;
trp_info_item[i].trp_id = f1_trp_info->tRPID;
F1AP_TRPInformationTypeResponseList_t *f1_trp_info_type_resp_list =
(F1AP_TRPInformationTypeResponseList_t *)&f1_trp_info->tRPInformationTypeResponseList;
uint8_t trp_info_type_resp_item_len = f1_trp_info_type_resp_list->list.count;
AssertError(trp_info_type_resp_item_len > 0,
return false,
"at least 1 TRP Information type response Item must be present");
f1ap_trp_information_type_response_list_t *trp_info_resp_list = &trp_info_item[i].trp_information_type_response_list;
trp_info_resp_list->trp_information_type_response_item_length = trp_info_type_resp_item_len;
trp_info_resp_list->trp_information_type_response_item =
calloc_or_fail(trp_info_type_resp_item_len, sizeof(*trp_info_resp_list->trp_information_type_response_item));
for (int j = 0; j < trp_info_type_resp_item_len; j++) {
f1ap_trp_information_type_response_item_t *trp_info_type_resp_item =
&trp_info_resp_list->trp_information_type_response_item[j];
decode_trp_info_type_response_item(f1_trp_info_type_resp_list->list.array[j], trp_info_type_resp_item);
}
}
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 TRP information response deep copy
*/
f1ap_trp_information_resp_t cp_trp_information_resp(const f1ap_trp_information_resp_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_trp_information_resp_t cp = {
.transaction_id = orig->transaction_id,
};
uint32_t trp_info_item_length = orig->trp_information_list.trp_information_item_length;
AssertFatal(trp_info_item_length > 0, "at least 1 TRP Information Item must be present\n");
cp.trp_information_list.trp_information_item_length = trp_info_item_length;
cp.trp_information_list.trp_information_item =
calloc_or_fail(trp_info_item_length, sizeof(*cp.trp_information_list.trp_information_item));
f1ap_trp_information_t *trp_information_item_cp = cp.trp_information_list.trp_information_item;
f1ap_trp_information_t *trp_information_item_orig = orig->trp_information_list.trp_information_item;
for (int i = 0; i < trp_info_item_length; i++) {
uint8_t trp_info_type_resp_item_len =
trp_information_item_orig[i].trp_information_type_response_list.trp_information_type_response_item_length;
AssertFatal(trp_info_type_resp_item_len > 0, "at least 1 TRP Information type response Item must be present\n");
trp_information_item_cp[i].trp_id = trp_information_item_orig[i].trp_id;
f1ap_trp_information_type_response_list_t *trp_info_type_resp_list_cp =
&trp_information_item_cp[i].trp_information_type_response_list;
f1ap_trp_information_type_response_list_t *trp_info_type_resp_list_orig =
&trp_information_item_orig[i].trp_information_type_response_list;
trp_info_type_resp_list_cp->trp_information_type_response_item_length = trp_info_type_resp_item_len;
trp_info_type_resp_list_cp->trp_information_type_response_item =
calloc_or_fail(trp_info_type_resp_item_len, sizeof(*trp_info_type_resp_list_cp->trp_information_type_response_item));
for (int j = 0; j < trp_info_type_resp_item_len; j++) {
trp_info_type_resp_list_cp->trp_information_type_response_item[j] =
cp_trp_info_type_response_item(&trp_info_type_resp_list_orig->trp_information_type_response_item[j]);
}
}
return cp;
}
/**
* @brief F1 TRP information response equality check
*/
bool eq_trp_information_resp(const f1ap_trp_information_resp_t *a, const f1ap_trp_information_resp_t *b)
{
_F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
_F1_EQ_CHECK_INT(a->trp_information_list.trp_information_item_length, b->trp_information_list.trp_information_item_length);
uint32_t trp_info_item_length = a->trp_information_list.trp_information_item_length;
AssertError(trp_info_item_length > 0, return false, "at least 1 TRP Information Item must be present\n");
f1ap_trp_information_t *trp_information_item_a = a->trp_information_list.trp_information_item;
f1ap_trp_information_t *trp_information_item_b = b->trp_information_list.trp_information_item;
for (int i = 0; i < trp_info_item_length; i++) {
f1ap_trp_information_type_response_list_t *trp_info_type_resp_list_a =
&trp_information_item_a[i].trp_information_type_response_list;
f1ap_trp_information_type_response_list_t *trp_info_type_resp_list_b =
&trp_information_item_b[i].trp_information_type_response_list;
_F1_EQ_CHECK_INT(trp_info_type_resp_list_a->trp_information_type_response_item_length,
trp_info_type_resp_list_b->trp_information_type_response_item_length);
uint8_t trp_info_type_resp_item_len = trp_info_type_resp_list_a->trp_information_type_response_item_length;
AssertError(trp_info_type_resp_item_len > 0, return false, "at least 1 TRP Information type response Item must be present\n");
_F1_EQ_CHECK_INT(trp_information_item_a[i].trp_id, trp_information_item_b[i].trp_id);
for (int j = 0; j < trp_info_type_resp_item_len; j++) {
_F1_CHECK_EXP(eq_trp_info_type_response_item(&trp_info_type_resp_list_a->trp_information_type_response_item[j],
&trp_info_type_resp_list_b->trp_information_type_response_item[j]));
}
}
return true;
}
/**
* @brief Free Allocated F1 TRP information response
*/
void free_trp_information_resp(f1ap_trp_information_resp_t *msg)
{
f1ap_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++) {
f1ap_trp_information_t *trp_information_item = &trp_information_list->trp_information_item[i];
f1ap_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);
}
/**
* @brief Encode F1 TRP information failure to ASN.1
*/
F1AP_F1AP_PDU_t *encode_trp_information_failure(const f1ap_trp_information_failure_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
asn1cCalloc(pdu->choice.unsuccessfulOutcome, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_TRPInformationExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_TRPInformationFailure;
F1AP_TRPInformationFailure_t *out = &tmp->value.choice.TRPInformationFailure;
/* mandatory : TransactionID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationFailureIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_TRPInformationFailureIEs__value_PR_TransactionID;
ie1->value.choice.TransactionID = msg->transaction_id;
/* mandatory : Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_TRPInformationFailureIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_Cause;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_TRPInformationFailureIEs__value_PR_Cause;
ie3->value.choice.Cause = encode_f1ap_cause(msg->cause, msg->cause_value);
return pdu;
}
/**
* @brief Decode F1 TRP information failure
*/
bool decode_trp_information_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_trp_information_failure_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_TRPInformationFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.TRPInformationFailure;
F1AP_TRPInformationFailureIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_TRPInformationFailureIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_LIB_FIND_IE(F1AP_TRPInformationFailureIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_Cause, true);
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_TRPInformationFailureIEs__value_PR_TransactionID);
out->transaction_id = ie->value.choice.TransactionID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_TRPInformationFailureIEs__value_PR_Cause);
_F1_CHECK_EXP(decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value));
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 trp information failure deep copy
*/
f1ap_trp_information_failure_t cp_trp_information_failure(const f1ap_trp_information_failure_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_trp_information_failure_t cp = {
.transaction_id = orig->transaction_id,
.cause = orig->cause,
.cause_value = orig->cause_value,
};
return cp;
}
/**
* @brief F1 trp information failure equality check
*/
bool eq_trp_information_failure(const f1ap_trp_information_failure_t *a, const f1ap_trp_information_failure_t *b)
{
_F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
return true;
}
/**
* @brief Free Allocated F1 trp information failure
*/
void free_trp_information_failure(f1ap_trp_information_failure_t *msg)
{
// nothing to free
}
/**
* @brief Encode F1 positioning measurement request to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_measurement_req(const f1ap_positioning_measurement_req_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu->choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningMeasurementExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_InitiatingMessage__value_PR_PositioningMeasurementRequest;
F1AP_PositioningMeasurementRequest_t *out = &tmp->value.choice.PositioningMeasurementRequest;
/* mandatory : TransactionID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_TransactionID;
ie1->value.choice.TransactionID = msg->transaction_id;
/* mandatory : LMF_MeasurementID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_LMF_MeasurementID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_LMF_MeasurementID;
ie2->value.choice.LMF_MeasurementID = msg->lmf_measurement_id;
/* mandatory : RAN_MeasurementID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_RAN_MeasurementID;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_RAN_MeasurementID;
ie3->value.choice.RAN_MeasurementID = msg->ran_measurement_id;
/* TRP Measurement Request List */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie4);
ie4->id = F1AP_ProtocolIE_ID_id_TRP_MeasurementRequestList;
ie4->criticality = F1AP_Criticality_reject;
ie4->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_TRP_MeasurementRequestList;
F1AP_TRP_MeasurementRequestList_t *f1_trp_meas_req_list = &ie4->value.choice.TRP_MeasurementRequestList;
const f1ap_trp_measurement_request_list_t *trp_meas_req_list = &msg->trp_measurement_request_list;
for (int i = 0; i < trp_meas_req_list->trp_measurement_request_list_length; i++) {
// mandatory : TRP List Item
asn1cSequenceAdd(f1_trp_meas_req_list->list, F1AP_TRP_MeasurementRequestItem_t, trp_meas_req_item);
trp_meas_req_item->tRPID = trp_meas_req_list->trp_measurement_request_item[i].tRPID;
}
/* mandatory : PosReportCharacteristics */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie5);
ie5->id = F1AP_ProtocolIE_ID_id_PosReportCharacteristics;
ie5->criticality = F1AP_Criticality_reject;
ie5->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_PosReportCharacteristics;
ie5->value.choice.PosReportCharacteristics = msg->pos_report_characteristics;
/* C : if ReportCharacteristicsPeriodic */
if (msg->pos_report_characteristics == F1AP_POSREPORTCHARACTERISTICS_PERIODIC) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie6);
ie6->id = F1AP_ProtocolIE_ID_id_PosMeasurementPeriodicity;
ie6->criticality = F1AP_Criticality_reject;
ie6->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_MeasurementPeriodicity;
ie6->value.choice.MeasurementPeriodicity = msg->measurement_periodicity;
}
/* mandatory : Positioning Measurement Periodicity */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie7);
ie7->id = F1AP_ProtocolIE_ID_id_PosMeasurementQuantities;
ie7->criticality = F1AP_Criticality_reject;
ie7->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_PosMeasurementQuantities;
F1AP_PosMeasurementQuantities_t *f1_pos_meas_quantities = &ie7->value.choice.PosMeasurementQuantities;
const f1ap_pos_measurement_quantities_t *pos_meas_quantities = &msg->pos_measurement_quantities;
for (int i = 0; i < pos_meas_quantities->pos_measurement_quantities_length; i++) {
// mandatory: PosMeasurementQuantitiesItem
asn1cSequenceAdd(f1_pos_meas_quantities->list, F1AP_PosMeasurementQuantities_Item_t, pos_meas_quantity_item);
pos_meas_quantity_item->posMeasurementType = pos_meas_quantities->pos_measurement_quantities_item[i].pos_measurement_type;
}
/* optional: SRS Configuration */
if (msg->srs_configuration) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementRequestIEs_t, ie8);
ie8->id = F1AP_ProtocolIE_ID_id_SRSConfiguration;
ie8->criticality = F1AP_Criticality_ignore;
ie8->value.present = F1AP_PositioningMeasurementRequestIEs__value_PR_SRSConfiguration;
f1ap_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list;
ie8->value.choice.SRSConfiguration.sRSCarrier_List = encode_srs_carrier_list(srs_carrier_list);
}
return pdu;
}
/**
* @brief Decode F1 Positioning Measurement request
*/
bool decode_positioning_measurement_req(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_measurement_req_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningMeasurementRequest_t *in = &pdu->choice.initiatingMessage->value.choice.PositioningMeasurementRequest;
F1AP_PositioningMeasurementRequestIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_LMF_MeasurementID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_RAN_MeasurementID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_TRP_MeasurementRequestList,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_PosReportCharacteristics,
true);
F1AP_PosReportCharacteristics_t *report_char = &ie->value.choice.PosReportCharacteristics;
if (*report_char == F1AP_PosReportCharacteristics_periodic) {
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_PosMeasurementPeriodicity,
true);
}
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_PosMeasurementQuantities,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementRequestIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_SRSConfiguration,
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_PositioningMeasurementRequestIEs__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_PositioningMeasurementRequestIEs__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_PositioningMeasurementRequestIEs__value_PR_RAN_MeasurementID);
out->ran_measurement_id = ie->value.choice.RAN_MeasurementID;
break;
case F1AP_ProtocolIE_ID_id_TRP_MeasurementRequestList:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementRequestIEs__value_PR_TRP_MeasurementRequestList);
F1AP_TRP_MeasurementRequestList_t *f1_trp_meas_req_list = &ie->value.choice.TRP_MeasurementRequestList;
f1ap_trp_measurement_request_list_t *trp_meas_req_list = &out->trp_measurement_request_list;
uint32_t trp_meas_req_list_len = f1_trp_meas_req_list->list.count;
AssertError(trp_meas_req_list_len > 0, return false, "at least 1 TRP must be present");
trp_meas_req_list->trp_measurement_request_list_length = trp_meas_req_list_len;
trp_meas_req_list->trp_measurement_request_item =
calloc_or_fail(trp_meas_req_list_len, sizeof(*trp_meas_req_list->trp_measurement_request_item));
for (int i = 0; i < trp_meas_req_list_len; i++) {
trp_meas_req_list->trp_measurement_request_item[i].tRPID = f1_trp_meas_req_list->list.array[i]->tRPID;
}
break;
case F1AP_ProtocolIE_ID_id_PosReportCharacteristics:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementRequestIEs__value_PR_PosReportCharacteristics);
out->pos_report_characteristics = ie->value.choice.PosReportCharacteristics;
break;
case F1AP_ProtocolIE_ID_id_PosMeasurementPeriodicity:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementRequestIEs__value_PR_MeasurementPeriodicity);
out->measurement_periodicity = ie->value.choice.MeasurementPeriodicity;
break;
case F1AP_ProtocolIE_ID_id_PosMeasurementQuantities:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementRequestIEs__value_PR_PosMeasurementQuantities);
F1AP_PosMeasurementQuantities_t *f1_pos_meas_quantities = &ie->value.choice.PosMeasurementQuantities;
f1ap_pos_measurement_quantities_t *pos_meas_quantities = &out->pos_measurement_quantities;
uint32_t pos_meas_quantities_len = f1_pos_meas_quantities->list.count;
AssertError(pos_meas_quantities_len > 0, return false, "at least 1 position measurement must be present");
pos_meas_quantities->pos_measurement_quantities_length = pos_meas_quantities_len;
pos_meas_quantities->pos_measurement_quantities_item =
calloc_or_fail(pos_meas_quantities_len, sizeof(*pos_meas_quantities->pos_measurement_quantities_item));
for (int i = 0; i < pos_meas_quantities_len; i++) {
f1ap_pos_measurement_quantities_item_t *pos_meas_quantities_item =
&pos_meas_quantities->pos_measurement_quantities_item[i];
F1AP_PosMeasurementQuantities_Item_t *f1_PosMeasurementQuantities_Item = f1_pos_meas_quantities->list.array[i];
pos_meas_quantities_item->pos_measurement_type = f1_PosMeasurementQuantities_Item->posMeasurementType;
}
break;
case F1AP_ProtocolIE_ID_id_SFNInitialisationTime:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not supported, skipping\n", ie->id);
break;
case F1AP_ProtocolIE_ID_id_SRSConfiguration:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementRequestIEs__value_PR_SRSConfiguration);
F1AP_SRSCarrier_List_t *f1_sRSCarrier_List = &ie->value.choice.SRSConfiguration.sRSCarrier_List;
out->srs_configuration = calloc_or_fail(1, sizeof(*out->srs_configuration));
f1ap_srs_carrier_list_t *srs_carrier_list = &out->srs_configuration->srs_carrier_list;
decode_srs_carrier_list(srs_carrier_list, f1_sRSCarrier_List);
break;
case F1AP_ProtocolIE_ID_id_MeasurementBeamInfoRequest:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not supported, skipping\n", ie->id);
break;
case F1AP_ProtocolIE_ID_id_SystemFrameNumber:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not supported, skipping\n", ie->id);
break;
case F1AP_ProtocolIE_ID_id_SlotNumber:
PRINT_ERROR("F1AP_ProtocolIE_ID_id %ld not supported, 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 request deep copy
*/
f1ap_positioning_measurement_req_t cp_positioning_measurement_req(const f1ap_positioning_measurement_req_t *orig)
{
// copy all mandatory fields that are not dynamic memory
f1ap_positioning_measurement_req_t cp = {
.transaction_id = orig->transaction_id,
.lmf_measurement_id = orig->lmf_measurement_id,
.ran_measurement_id = orig->ran_measurement_id,
};
f1ap_trp_measurement_request_list_t *trp_meas_req_list_cp = &cp.trp_measurement_request_list;
const f1ap_trp_measurement_request_list_t *trp_meas_req_list_orig = &orig->trp_measurement_request_list;
uint32_t trp_meas_req_list_len = trp_meas_req_list_orig->trp_measurement_request_list_length;
AssertFatal(trp_meas_req_list_len > 0, "at least 1 TRP must be present");
trp_meas_req_list_cp->trp_measurement_request_list_length = trp_meas_req_list_len;
trp_meas_req_list_cp->trp_measurement_request_item =
calloc_or_fail(trp_meas_req_list_len, sizeof(*trp_meas_req_list_cp->trp_measurement_request_item));
for (int i = 0; i < trp_meas_req_list_len; i++) {
trp_meas_req_list_cp->trp_measurement_request_item[i].tRPID = trp_meas_req_list_orig->trp_measurement_request_item[i].tRPID;
}
cp.pos_report_characteristics = orig->pos_report_characteristics;
if (orig->pos_report_characteristics == F1AP_POSREPORTCHARACTERISTICS_PERIODIC) {
cp.measurement_periodicity = orig->measurement_periodicity;
}
f1ap_pos_measurement_quantities_t *q_out = &cp.pos_measurement_quantities;
const f1ap_pos_measurement_quantities_t *q_in = &orig->pos_measurement_quantities;
uint32_t q_len = q_in->pos_measurement_quantities_length;
AssertFatal(q_len > 0, "at least 1 position measurement must be present");
q_out->pos_measurement_quantities_length = q_len;
q_out->pos_measurement_quantities_item = calloc_or_fail(q_len, sizeof(*q_out->pos_measurement_quantities_item));
for (int i = 0; i < q_len; i++) {
f1ap_pos_measurement_quantities_item_t *q_item_in = &q_in->pos_measurement_quantities_item[i];
f1ap_pos_measurement_quantities_item_t *q_item_out = &q_out->pos_measurement_quantities_item[i];
q_item_out->pos_measurement_type = q_item_in->pos_measurement_type;
}
/* optional: SRS Configuration */
if (orig->srs_configuration) {
cp.srs_configuration = calloc_or_fail(1, sizeof(*cp.srs_configuration));
f1ap_srs_carrier_list_t *srs_carrier_list_cp = &cp.srs_configuration->srs_carrier_list;
f1ap_srs_carrier_list_t *srs_carrier_list = &orig->srs_configuration->srs_carrier_list;
*srs_carrier_list_cp = cp_srs_carrier_list(srs_carrier_list);
}
return cp;
}
/**
* @brief F1 Positioning Measurement request equality check
*/
bool eq_positioning_measurement_req(const f1ap_positioning_measurement_req_t *a, const f1ap_positioning_measurement_req_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);
const f1ap_trp_measurement_request_list_t *trp_meas_req_list_a = &a->trp_measurement_request_list;
const f1ap_trp_measurement_request_list_t *trp_meas_req_list_b = &b->trp_measurement_request_list;
uint32_t trp_meas_req_list_len = trp_meas_req_list_a->trp_measurement_request_list_length;
AssertFatal(trp_meas_req_list_len > 0, "at least 1 TRP must be present");
_F1_EQ_CHECK_INT(trp_meas_req_list_b->trp_measurement_request_list_length, trp_meas_req_list_len);
for (int i = 0; i < trp_meas_req_list_len; i++) {
_F1_EQ_CHECK_INT(trp_meas_req_list_a->trp_measurement_request_item[i].tRPID,
trp_meas_req_list_b->trp_measurement_request_item[i].tRPID);
}
_F1_EQ_CHECK_INT(a->pos_report_characteristics, b->pos_report_characteristics);
if (a->pos_report_characteristics == F1AP_POSREPORTCHARACTERISTICS_PERIODIC) {
_F1_EQ_CHECK_INT(a->measurement_periodicity, b->measurement_periodicity);
}
const f1ap_pos_measurement_quantities_t *pos_meas_quantities_a = &a->pos_measurement_quantities;
const f1ap_pos_measurement_quantities_t *pos_meas_quantities_b = &b->pos_measurement_quantities;
uint32_t pos_meas_quantities_len = pos_meas_quantities_a->pos_measurement_quantities_length;
AssertFatal(pos_meas_quantities_len > 0, "at least 1 position measurement must be present");
_F1_EQ_CHECK_INT(pos_meas_quantities_b->pos_measurement_quantities_length, pos_meas_quantities_len);
for (int i = 0; i < pos_meas_quantities_len; i++) {
f1ap_pos_measurement_quantities_item_t *a_pos_meas_quantities_item = &pos_meas_quantities_a->pos_measurement_quantities_item[i];
f1ap_pos_measurement_quantities_item_t *b_pos_meas_quantities_item = &pos_meas_quantities_b->pos_measurement_quantities_item[i];
_F1_EQ_CHECK_INT(a_pos_meas_quantities_item->pos_measurement_type, b_pos_meas_quantities_item->pos_measurement_type);
}
/* optional: SRS Configuration */
if ((a->srs_configuration == NULL) != (b->srs_configuration == NULL)) {
return false;
}
if (a->srs_configuration) {
f1ap_srs_carrier_list_t *srs_carrier_list_a = &a->srs_configuration->srs_carrier_list;
f1ap_srs_carrier_list_t *srs_carrier_list_b = &b->srs_configuration->srs_carrier_list;
_F1_CHECK_EXP(eq_srs_carrier_list(srs_carrier_list_a, srs_carrier_list_b));
}
return true;
}
/**
* @brief Free Allocated F1 Positioning Measurement request
*/
void free_positioning_measurement_req(f1ap_positioning_measurement_req_t *msg)
{
free(msg->trp_measurement_request_list.trp_measurement_request_item);
free(msg->pos_measurement_quantities.pos_measurement_quantities_item);
/* optional: SRS Configuration */
if (msg->srs_configuration) {
f1ap_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list;
free_srs_carrier_list(srs_carrier_list);
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);
}
}
/**
* @brief Encode F1 positioning measurement failure to ASN.1
*/
F1AP_F1AP_PDU_t *encode_positioning_measurement_failure(const f1ap_positioning_measurement_failure_t *msg)
{
F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
/* Message Type */
pdu->present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
asn1cCalloc(pdu->choice.unsuccessfulOutcome, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_PositioningMeasurementExchange;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_PositioningMeasurementFailure;
F1AP_PositioningMeasurementFailure_t *out = &tmp->value.choice.PositioningMeasurementFailure;
/* mandatory : TransactionID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementFailureIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_PositioningMeasurementFailureIEs__value_PR_TransactionID;
ie1->value.choice.TransactionID = msg->transaction_id;
/* mandatory : LMF_MeasurementID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementFailureIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_LMF_MeasurementID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_PositioningMeasurementFailureIEs__value_PR_LMF_MeasurementID;
ie2->value.choice.LMF_MeasurementID = msg->lmf_measurement_id;
/* mandatory : RAN_MeasurementID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementFailureIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_RAN_MeasurementID;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_PositioningMeasurementFailureIEs__value_PR_RAN_MeasurementID;
ie3->value.choice.RAN_MeasurementID = msg->ran_measurement_id;
/* mandatory : Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_PositioningMeasurementFailureIEs_t, ie4);
ie4->id = F1AP_ProtocolIE_ID_id_Cause;
ie4->criticality = F1AP_Criticality_ignore;
ie4->value.present = F1AP_PositioningMeasurementFailureIEs__value_PR_Cause;
ie4->value.choice.Cause = encode_f1ap_cause(msg->cause, msg->cause_value);
return pdu;
}
/**
* @brief Decode F1 positioning measurement failure
*/
bool decode_positioning_measurement_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_positioning_measurement_failure_t *out)
{
DevAssert(out != NULL);
memset(out, 0, sizeof(*out));
F1AP_PositioningMeasurementFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.PositioningMeasurementFailure;
F1AP_PositioningMeasurementFailureIEs_t *ie;
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementFailureIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_TransactionID, true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementFailureIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_LMF_MeasurementID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementFailureIEs_t,
ie,
&in->protocolIEs.list,
F1AP_ProtocolIE_ID_id_RAN_MeasurementID,
true);
F1AP_LIB_FIND_IE(F1AP_PositioningMeasurementFailureIEs_t, ie, &in->protocolIEs.list, F1AP_ProtocolIE_ID_id_Cause, true);
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_PositioningMeasurementFailureIEs__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_PositioningMeasurementFailureIEs__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_PositioningMeasurementFailureIEs__value_PR_RAN_MeasurementID);
out->ran_measurement_id = ie->value.choice.RAN_MeasurementID;
break;
case F1AP_ProtocolIE_ID_id_Cause:
_F1_EQ_CHECK_INT(ie->value.present, F1AP_PositioningMeasurementFailureIEs__value_PR_Cause);
_F1_CHECK_EXP(decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value));
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 failure deep copy
*/
f1ap_positioning_measurement_failure_t cp_positioning_measurement_failure(const f1ap_positioning_measurement_failure_t *orig)
{
/* copy all mandatory fields that are not dynamic memory */
f1ap_positioning_measurement_failure_t cp = {
.transaction_id = orig->transaction_id,
.lmf_measurement_id = orig->lmf_measurement_id,
.ran_measurement_id = orig->ran_measurement_id,
.cause = orig->cause,
.cause_value = orig->cause_value,
};
return cp;
}
/**
* @brief F1 positioning measurement failure equality check
*/
bool eq_positioning_measurement_failure(const f1ap_positioning_measurement_failure_t *a,
const f1ap_positioning_measurement_failure_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);
_F1_EQ_CHECK_INT(a->cause, b->cause);
_F1_EQ_CHECK_LONG(a->cause_value, b->cause_value);
return true;
}
/**
* @brief Free Allocated F1 positioning measurement failure
*/
void free_positioning_measurement_failure(f1ap_positioning_measurement_failure_t *msg)
{
// nothing to free
}