From 9157e22c7c7072f45c5d9fa8cf5ba190c17cd9ad Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 10 Feb 2025 11:37:06 +0100 Subject: [PATCH] Add F1 Reset enc/dec/cp/eq/free library and test --- openair2/COMMON/f1ap_messages_types.h | 11 +- openair2/F1AP/lib/f1ap_interface_management.c | 220 ++++++++++++++++++ openair2/F1AP/lib/f1ap_interface_management.h | 7 + openair2/F1AP/lib/f1ap_lib_common.c | 55 +++++ openair2/F1AP/lib/f1ap_lib_common.h | 6 + openair2/F1AP/lib/f1ap_lib_includes.h | 1 + openair2/F1AP/tests/f1ap_lib_test.c | 66 ++++++ 7 files changed, 362 insertions(+), 4 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 36c3ad4f76..e72741f6ed 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -563,15 +563,18 @@ typedef enum F1AP_ResetType_e { F1AP_RESET_PART_OF_F1_INTERFACE } f1ap_ResetType_t; +typedef struct f1ap_ue_to_reset_t { + uint32_t *gNB_CU_ue_id; + uint32_t *gNB_DU_ue_id; +} f1ap_ue_to_reset_t; + typedef struct f1ap_reset_t { uint64_t transaction_id; f1ap_Cause_t cause; long cause_value; f1ap_ResetType_t reset_type; - struct { - uint32_t gNB_CU_ue_id; - uint32_t gNB_DU_ue_id; - } ue_to_reset[F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET]; + int num_ue_to_reset; + f1ap_ue_to_reset_t *ue_to_reset; // array of num_ue_to_reset elements } f1ap_reset_t; typedef struct f1ap_reset_ack_t { diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index 182f40952d..ce7ece3c11 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -32,6 +32,226 @@ #include "f1ap_messages_types.h" #include "f1ap_lib_extern.h" +F1AP_UE_associatedLogicalF1_ConnectionItem_t encode_f1ap_ue_to_reset(const f1ap_ue_to_reset_t *to_reset) +{ + F1AP_UE_associatedLogicalF1_ConnectionItem_t conn_it = {0}; + + if (to_reset->gNB_CU_ue_id) + asn1cCallocOne(conn_it.gNB_CU_UE_F1AP_ID, *to_reset->gNB_CU_ue_id); + if (to_reset->gNB_DU_ue_id) + asn1cCallocOne(conn_it.gNB_DU_UE_F1AP_ID, *to_reset->gNB_DU_ue_id); + + return conn_it; +} + +f1ap_ue_to_reset_t decode_f1ap_ue_to_reset(const F1AP_UE_associatedLogicalF1_ConnectionItem_t *conn_it) +{ + f1ap_ue_to_reset_t to_reset = {0}; + if (conn_it->gNB_CU_UE_F1AP_ID) { + to_reset.gNB_CU_ue_id = malloc_or_fail(sizeof(*to_reset.gNB_CU_ue_id)); + *to_reset.gNB_CU_ue_id = *conn_it->gNB_CU_UE_F1AP_ID; + } + if (conn_it->gNB_DU_UE_F1AP_ID) { + to_reset.gNB_DU_ue_id = malloc_or_fail(sizeof(*to_reset.gNB_DU_ue_id)); + *to_reset.gNB_DU_ue_id = *conn_it->gNB_DU_UE_F1AP_ID; + } + return to_reset; +} + +void free_f1ap_ue_to_reset(const f1ap_ue_to_reset_t *to_reset) +{ + free(to_reset->gNB_CU_ue_id); + free(to_reset->gNB_DU_ue_id); +} + +bool eq_f1ap_ue_to_reset(const f1ap_ue_to_reset_t *a, const f1ap_ue_to_reset_t *b) +{ + if ((!a->gNB_CU_ue_id) ^ (!b->gNB_CU_ue_id)) + return false; + if (a->gNB_CU_ue_id) + _F1_EQ_CHECK_INT(*a->gNB_CU_ue_id, *b->gNB_CU_ue_id); + if ((!a->gNB_DU_ue_id) ^ (!b->gNB_DU_ue_id)) + return false; + if (a->gNB_DU_ue_id) + _F1_EQ_CHECK_INT(*a->gNB_DU_ue_id, *b->gNB_DU_ue_id); + return true; +} + +f1ap_ue_to_reset_t cp_f1ap_ue_to_reset(const f1ap_ue_to_reset_t *orig) +{ + f1ap_ue_to_reset_t cp = {0}; + if (orig->gNB_CU_ue_id) { + cp.gNB_CU_ue_id = malloc_or_fail(sizeof(*cp.gNB_CU_ue_id)); + *cp.gNB_CU_ue_id = *orig->gNB_CU_ue_id; + } + if (orig->gNB_DU_ue_id) { + cp.gNB_DU_ue_id = malloc_or_fail(sizeof(*cp.gNB_DU_ue_id)); + *cp.gNB_DU_ue_id = *orig->gNB_DU_ue_id; + } + return cp; +} + +/* @brief encode F1 Reset (9.2.1.1 in TS 38.473) */ +F1AP_F1AP_PDU_t *encode_f1ap_reset(const f1ap_reset_t *msg) +{ + F1AP_F1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + /* Create Message Type */ + pdu->present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu->choice.initiatingMessage, initMsg); + initMsg->procedureCode = F1AP_ProcedureCode_id_Reset; + initMsg->criticality = F1AP_Criticality_reject; + initMsg->value.present = F1AP_InitiatingMessage__value_PR_Reset; + F1AP_Reset_t *reset = &initMsg->value.choice.Reset; + + /* (M) Transaction ID */ + asn1cSequenceAdd(reset->protocolIEs.list, F1AP_ResetIEs_t, ieC1); + ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = F1AP_Criticality_reject; + ieC1->value.present = F1AP_ResetIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = msg->transaction_id; + + /* (M) Cause */ + asn1cSequenceAdd(reset->protocolIEs.list, F1AP_ResetIEs_t, ieC2); + ieC2->id = F1AP_ProtocolIE_ID_id_Cause; + ieC2->criticality = F1AP_Criticality_ignore; + ieC2->value.present = F1AP_ResetIEs__value_PR_Cause; + ieC2->value.choice.Cause = encode_f1ap_cause(msg->cause, msg->cause_value); + + /* (M) Reset type */ + asn1cSequenceAdd(reset->protocolIEs.list, F1AP_ResetIEs_t, ieC3); + ieC3->id = F1AP_ProtocolIE_ID_id_ResetType; + ieC3->criticality = F1AP_Criticality_reject; + ieC3->value.present = F1AP_ResetIEs__value_PR_ResetType; + if (msg->reset_type == F1AP_RESET_ALL) { + ieC3->value.choice.ResetType.present = F1AP_ResetType_PR_f1_Interface; + ieC3->value.choice.ResetType.choice.f1_Interface = F1AP_ResetAll_reset_all; + AssertFatal(msg->num_ue_to_reset == 0, "cannot have F1AP_RESET_ALL and %d UEs to reset\n", msg->num_ue_to_reset); + } else if (msg->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE) { + F1AP_UE_associatedLogicalF1_ConnectionListRes_t *con_list = calloc_or_fail(1, sizeof(*con_list)); + ieC3->value.choice.ResetType.present = F1AP_ResetType_PR_partOfF1_Interface; + ieC3->value.choice.ResetType.choice.partOfF1_Interface = con_list; + AssertFatal(msg->num_ue_to_reset > 0, "at least one UE to reset required\n"); + for (int i = 0; i < msg->num_ue_to_reset; ++i) { + asn1cSequenceAdd(con_list->list, F1AP_UE_associatedLogicalF1_ConnectionItemRes_t, conn_it_res); + conn_it_res->id = F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem; + conn_it_res->criticality = F1AP_Criticality_reject; + conn_it_res->value.present = F1AP_UE_associatedLogicalF1_ConnectionItemRes__value_PR_UE_associatedLogicalF1_ConnectionItem; + conn_it_res->value.choice.UE_associatedLogicalF1_ConnectionItem = encode_f1ap_ue_to_reset(&msg->ue_to_reset[i]); + } + } else { + AssertFatal(false, "illegal reset_type %d\n", msg->reset_type); + } + + return pdu; +} + +/* @brief decode F1 Reset (9.2.1.1 in TS 38.473) */ +bool decode_f1ap_reset(const F1AP_F1AP_PDU_t *pdu, f1ap_reset_t *out) +{ + _F1_EQ_CHECK_INT(pdu->present, F1AP_F1AP_PDU_PR_initiatingMessage); + AssertError(pdu->choice.initiatingMessage != NULL, return false, "pdu->choice.initiatingMessage is NULL"); + _F1_EQ_CHECK_LONG(pdu->choice.initiatingMessage->procedureCode, F1AP_ProcedureCode_id_Reset); + _F1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, F1AP_InitiatingMessage__value_PR_Reset); + + /* Check presence of mandatory IEs */ + F1AP_Reset_t *in = &pdu->choice.initiatingMessage->value.choice.Reset; + F1AP_ResetIEs_t *ie; + F1AP_LIB_FIND_IE(F1AP_ResetIEs_t, ie, in, F1AP_ProtocolIE_ID_id_TransactionID, true); + F1AP_LIB_FIND_IE(F1AP_ResetIEs_t, ie, in, F1AP_ProtocolIE_ID_id_Cause, true); + F1AP_LIB_FIND_IE(F1AP_ResetIEs_t, ie, in, F1AP_ProtocolIE_ID_id_ResetType, true); + + /* Loop over all IEs */ + for (int i = 0; i < in->protocolIEs.list.count; i++) { + AssertError(in->protocolIEs.list.array[i] != NULL, return false, "in->protocolIEs.list.array[i] is NULL"); + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + // (M) Transaction ID + _F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_TransactionID); + out->transaction_id = ie->value.choice.TransactionID; + break; + case F1AP_ProtocolIE_ID_id_Cause: + // (M) Cause + _F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_Cause); + if (!decode_f1ap_cause(ie->value.choice.Cause, &out->cause, &out->cause_value)) { + PRINT_ERROR("could not decode F1AP Cause\n"); + return false; + } + break; + case F1AP_ProtocolIE_ID_id_ResetType: + // (M) Reset type + _F1_EQ_CHECK_INT(ie->value.present, F1AP_ResetIEs__value_PR_ResetType); + if (ie->value.choice.ResetType.present == F1AP_ResetType_PR_f1_Interface) { + out->reset_type = F1AP_RESET_ALL; + } else if (ie->value.choice.ResetType.present == F1AP_ResetType_PR_partOfF1_Interface) { + out->reset_type = F1AP_RESET_PART_OF_F1_INTERFACE; + const F1AP_UE_associatedLogicalF1_ConnectionListRes_t *con_list = ie->value.choice.ResetType.choice.partOfF1_Interface; + AssertError(con_list->list.count > 0, return false, "no UEs for partially reset F1 interface\n"); + out->num_ue_to_reset = con_list->list.count; + out->ue_to_reset = calloc_or_fail(out->num_ue_to_reset, sizeof(*out->ue_to_reset)); + for (int i = 0; i < out->num_ue_to_reset; ++i) { + const F1AP_UE_associatedLogicalF1_ConnectionItemRes_t *it_res = + (const F1AP_UE_associatedLogicalF1_ConnectionItemRes_t *)con_list->list.array[i]; + _F1_EQ_CHECK_LONG(it_res->id, F1AP_ProtocolIE_ID_id_UE_associatedLogicalF1_ConnectionItem); + _F1_EQ_CHECK_INT(it_res->value.present, + F1AP_UE_associatedLogicalF1_ConnectionItemRes__value_PR_UE_associatedLogicalF1_ConnectionItem); + out->ue_to_reset[i] = decode_f1ap_ue_to_reset(&it_res->value.choice.UE_associatedLogicalF1_ConnectionItem); + } + } else { + PRINT_ERROR("unrecognized Reset type %d\n", ie->value.choice.ResetType.present); + return false; + } + } + } + return true; +} + +void free_f1ap_reset(f1ap_reset_t *msg) +{ + DevAssert(msg->reset_type == F1AP_RESET_ALL || msg->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE); + if (msg->reset_type == F1AP_RESET_ALL) { + DevAssert(msg->ue_to_reset == NULL); + return; /* nothing to be freed in this case */ + } + for (int i = 0; i < msg->num_ue_to_reset; ++i) + free_f1ap_ue_to_reset(&msg->ue_to_reset[i]); + free(msg->ue_to_reset); +} + +bool eq_f1ap_reset(const f1ap_reset_t *a, const f1ap_reset_t *b) +{ + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); + _F1_EQ_CHECK_INT(a->cause, b->cause); + _F1_EQ_CHECK_LONG(a->cause_value, b->cause_value); + _F1_EQ_CHECK_INT(a->reset_type, b->reset_type); + if (a->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE) { + _F1_EQ_CHECK_INT(a->num_ue_to_reset, b->num_ue_to_reset); + for (int i = 0; i < a->num_ue_to_reset; ++i) + if (!eq_f1ap_ue_to_reset(&a->ue_to_reset[i], &b->ue_to_reset[i])) + return false; + } + return true; +} + +f1ap_reset_t cp_f1ap_reset(const f1ap_reset_t *orig) +{ + DevAssert(orig->reset_type == F1AP_RESET_ALL || orig->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE); + f1ap_reset_t cp = { + .transaction_id = orig->transaction_id, + .cause = orig->cause, + .cause_value = orig->cause_value, + .reset_type = orig->reset_type, + }; + if (orig->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE) { + DevAssert(orig->num_ue_to_reset > 0); + cp.num_ue_to_reset = orig->num_ue_to_reset; + cp.ue_to_reset = calloc_or_fail(cp.num_ue_to_reset, sizeof(*cp.ue_to_reset)); + for (int i = 0; i < cp.num_ue_to_reset; ++i) + cp.ue_to_reset[i] = cp_f1ap_ue_to_reset(&orig->ue_to_reset[i]); + } + return cp; +} + static const int nrb_lut[29] = {11, 18, 24, 25, 31, 32, 38, 51, 52, 65, 66, 78, 79, 93, 106, 107, 121, 132, 133, 135, 160, 162, 189, 216, 217, 245, 264, 270, 273}; diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index 6fd79b4007..b3769eabfe 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -27,6 +27,13 @@ struct F1AP_F1AP_PDU; +/* F1 Reset */ +struct F1AP_F1AP_PDU *encode_f1ap_reset(const f1ap_reset_t *msg); +bool decode_f1ap_reset(const struct F1AP_F1AP_PDU *pdu, f1ap_reset_t *out); +void free_f1ap_reset(f1ap_reset_t *msg); +bool eq_f1ap_reset(const f1ap_reset_t *a, const f1ap_reset_t *b); +f1ap_reset_t cp_f1ap_reset(const f1ap_reset_t *orig); + struct F1AP_F1AP_PDU *encode_f1ap_setup_request(const f1ap_setup_req_t *msg); bool decode_f1ap_setup_request(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_req_t *out); f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg); diff --git a/openair2/F1AP/lib/f1ap_lib_common.c b/openair2/F1AP/lib/f1ap_lib_common.c index a569146815..c49a87c57c 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.c +++ b/openair2/F1AP/lib/f1ap_lib_common.c @@ -109,3 +109,58 @@ uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) *len = os->size; return buf; } + +F1AP_Cause_t encode_f1ap_cause(f1ap_Cause_t cause, long cause_value) +{ + F1AP_Cause_t f1_cause = {0}; + switch (cause) { + case F1AP_CAUSE_RADIO_NETWORK: + f1_cause.present = F1AP_Cause_PR_radioNetwork; + f1_cause.choice.radioNetwork = cause_value; + break; + case F1AP_CAUSE_TRANSPORT: + f1_cause.present = F1AP_Cause_PR_transport; + f1_cause.choice.transport = cause_value; + break; + case F1AP_CAUSE_PROTOCOL: + f1_cause.present = F1AP_Cause_PR_protocol; + f1_cause.choice.protocol = cause_value; + break; + case F1AP_CAUSE_MISC: + f1_cause.present = F1AP_Cause_PR_misc; + f1_cause.choice.misc = cause_value; + break; + case F1AP_CAUSE_NOTHING: + default: + AssertFatal(false, "unknown cause value %d\n", cause); + break; + } + return f1_cause; +} + +bool decode_f1ap_cause(F1AP_Cause_t f1_cause, f1ap_Cause_t *cause, long *cause_value) +{ + switch (f1_cause.present) { + case F1AP_Cause_PR_radioNetwork: + *cause = F1AP_CAUSE_RADIO_NETWORK; + *cause_value = f1_cause.choice.radioNetwork; + break; + case F1AP_Cause_PR_transport: + *cause = F1AP_CAUSE_TRANSPORT; + *cause_value = f1_cause.choice.transport; + break; + case F1AP_Cause_PR_protocol: + *cause = F1AP_CAUSE_PROTOCOL; + *cause_value = f1_cause.choice.protocol; + break; + case F1AP_Cause_PR_misc: + *cause = F1AP_CAUSE_MISC; + *cause_value = f1_cause.choice.radioNetwork; + break; + case F1AP_Cause_PR_NOTHING: + default: + PRINT_ERROR("received illegal F1AP cause %d\n", f1_cause.present); + return false; + } + return true; +} diff --git a/openair2/F1AP/lib/f1ap_lib_common.h b/openair2/F1AP/lib/f1ap_lib_common.h index 2380a2da87..502200d9df 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.h +++ b/openair2/F1AP/lib/f1ap_lib_common.h @@ -27,6 +27,9 @@ #include #include "openair3/UTILS/conversions.h" +#include "F1AP_Cause.h" +#include "f1ap_messages_types.h" + #ifdef ENABLE_TESTS #define PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__) #else @@ -82,4 +85,7 @@ bool eq_f1ap_tx_bandwidth(const struct f1ap_transmission_bandwidth_t *a, const s struct OCTET_STRING; uint8_t *cp_octet_string(const struct OCTET_STRING *os, int *len); +F1AP_Cause_t encode_f1ap_cause(f1ap_Cause_t cause, long cause_value); +bool decode_f1ap_cause(F1AP_Cause_t f1_cause, f1ap_Cause_t *cause, long *cause_value); + #endif /* F1AP_LIB_COMMON_H_ */ diff --git a/openair2/F1AP/lib/f1ap_lib_includes.h b/openair2/F1AP/lib/f1ap_lib_includes.h index 6ff60a4897..267e7243e7 100644 --- a/openair2/F1AP/lib/f1ap_lib_includes.h +++ b/openair2/F1AP/lib/f1ap_lib_includes.h @@ -40,5 +40,6 @@ #include "F1AP_SuccessfulOutcome.h" #include "F1AP_SibtypetobeupdatedListItem.h" #include "F1AP_UnsuccessfulOutcome.h" +#include "F1AP_UE-associatedLogicalF1-ConnectionListRes.h" #endif /* F1AP_LIB_INCLUDES_H_ */ diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 5d153f1aea..2e516a5607 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -383,6 +383,70 @@ static void test_f1ap_setup_failure(void) AssertFatal(ret, "eq_f1ap_setup_failure(): copied message doesn't match\n"); } +static void _test_f1ap_reset_msg(const f1ap_reset_t *orig) +{ + F1AP_F1AP_PDU_t *f1enc = encode_f1ap_reset(orig); + F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc); + f1ap_msg_free(f1enc); + + f1ap_reset_t decoded = {0}; + bool ret = decode_f1ap_reset(f1dec, &decoded); + AssertFatal(ret, "decode_f1ap_reset(): could not decode message\n"); + f1ap_msg_free(f1dec); + + ret = eq_f1ap_reset(orig, &decoded); + AssertFatal(ret, "eq_f1ap_reset(): decoded message doesn't match original\n"); + free_f1ap_reset(&decoded); + + f1ap_reset_t cp = cp_f1ap_reset(orig); + ret = eq_f1ap_reset(orig, &cp); + AssertFatal(ret, "eq_f1ap_reset(): copied message doesn't match original\n"); + free_f1ap_reset(&cp); + + printf("f1ap_reset successful\n"); +} + +/** + * @brief Test F1AP Reset message where the entire F1 interface is reset + */ +static void test_f1ap_reset_all(void) +{ + f1ap_reset_t orig = { + .transaction_id = 2, + .cause = F1AP_CAUSE_TRANSPORT, + .cause_value = 3, /* no type -> whatever */ + .reset_type = F1AP_RESET_ALL, + }; + _test_f1ap_reset_msg(&orig); + free_f1ap_reset(&orig); +} + +/** + * @brief Test F1AP Reset message where only some UEs are marked to reset + */ +static void test_f1ap_reset_part(void) +{ + f1ap_reset_t orig = { + .transaction_id = 3, + .cause = F1AP_CAUSE_MISC, + .cause_value = 3, /* no type -> whatever */ + .reset_type = F1AP_RESET_PART_OF_F1_INTERFACE, + .num_ue_to_reset = 4, + }; + orig.ue_to_reset = calloc_or_fail(orig.num_ue_to_reset, sizeof(*orig.ue_to_reset)); + orig.ue_to_reset[0].gNB_CU_ue_id = malloc_or_fail(sizeof(*orig.ue_to_reset[0].gNB_CU_ue_id)); + *orig.ue_to_reset[0].gNB_CU_ue_id = 10; + orig.ue_to_reset[1].gNB_DU_ue_id = malloc_or_fail(sizeof(*orig.ue_to_reset[1].gNB_DU_ue_id)); + *orig.ue_to_reset[1].gNB_DU_ue_id = 11; + orig.ue_to_reset[2].gNB_CU_ue_id = malloc_or_fail(sizeof(*orig.ue_to_reset[2].gNB_CU_ue_id)); + *orig.ue_to_reset[2].gNB_CU_ue_id = 12; + orig.ue_to_reset[2].gNB_DU_ue_id = malloc_or_fail(sizeof(*orig.ue_to_reset[2].gNB_DU_ue_id)); + *orig.ue_to_reset[2].gNB_DU_ue_id = 13; + // orig.ue_to_reset[3] intentionally empty (because it is allowed, both IDs are optional) + _test_f1ap_reset_msg(&orig); + free_f1ap_reset(&orig); +} + /** * @brief Test F1 gNB-DU Configuration Update */ @@ -605,6 +669,8 @@ int main() test_f1ap_setup_request(); test_f1ap_setup_response(); test_f1ap_setup_failure(); + test_f1ap_reset_all(); + test_f1ap_reset_part(); test_f1ap_du_configuration_update(); test_f1ap_cu_configuration_update(); test_f1ap_cu_configuration_update_acknowledge();