diff --git a/openair2/COMMON/xnap_messages_types.h b/openair2/COMMON/xnap_messages_types.h index fc360d2558..bca8bc80f4 100644 --- a/openair2/COMMON/xnap_messages_types.h +++ b/openair2/COMMON/xnap_messages_types.h @@ -72,4 +72,109 @@ typedef struct { xnap_tai_support_t *tai_support; } xnap_setup_resp_t; +typedef enum xnap_cause_radio_network_e { + XNAP_CAUSE_RADIO_NETWORK_LAYER_CELL_NOT_AVAILABLE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_HANDOVER_DESIRABLE_FOR_RADIO_REASONS, + XNAP_CAUSE_RADIO_NETWORK_LAYER_HANDOVER_TARGET_NOT_ALLOWED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_INVALID_AMF_SET_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_NO_RADIO_RESOURCES_AVAILABLE_IN_TARGET_CELL, + XNAP_CAUSE_RADIO_NETWORK_LAYER_PARTIAL_HANDOVER, + XNAP_CAUSE_RADIO_NETWORK_LAYER_REDUCE_LOAD_IN_SERVING_CELL, + XNAP_CAUSE_RADIO_NETWORK_LAYER_RESOURCE_OPTIMISATION_HANDOVER, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TIME_CRITICAL_HANDOVER, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_RELOCOVERALL_EXPIRY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_RELOCPREP_EXPIRY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_GUAMI_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_LOCAL_NG_RAN_NODE_UE_XNAP_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_INCONSISTENT_REMOTE_NG_RAN_NODE_UE_XNAP_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_ENCRYPTION_AND_OR_INTEGRITY_PROTECTION_ALGORITHMS_NOT_SUPPORTED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_PROTECTION_ALGORITHMS_NOT_SUPPORTED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_MULTIPLE_PDU_SESSION_ID_INSTANCES, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_PDU_SESSION_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_QOS_FLOW_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_MULTIPLE_QOS_FLOW_ID_INSTANCES, + XNAP_CAUSE_RADIO_NETWORK_LAYER_SWITCH_OFF_ONGOING, + XNAP_CAUSE_RADIO_NETWORK_LAYER_NOT_SUPPORTED_5QI_VALUE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_DCOVERALL_EXPIRY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TXN_DCPREP_EXPIRY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_ACTION_DESIRABLE_FOR_RADIO_REASONS, + XNAP_CAUSE_RADIO_NETWORK_LAYER_REDUCE_LOAD, + XNAP_CAUSE_RADIO_NETWORK_LAYER_RESOURCE_OPTIMISATION, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TIME_CRITICAL_ACTION, + XNAP_CAUSE_RADIO_NETWORK_LAYER_TARGET_NOT_ALLOWED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_NO_RADIO_RESOURCES_AVAILABLE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_INVALID_QOS_COMBINATION, + XNAP_CAUSE_RADIO_NETWORK_LAYER_ENCRYPTION_ALGORITHMS_NOT_SUPPORTED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_PROCEDURE_CANCELLED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_RRM_PURPOSE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_IMPROVE_USER_BIT_RATE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_USER_INACTIVITY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_RADIO_CONNECTION_WITH_UE_LOST, + XNAP_CAUSE_RADIO_NETWORK_LAYER_FAILURE_IN_THE_RADIO_INTERFACE_PROCEDURE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_BEARER_OPTION_NOT_SUPPORTED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UP_INTEGRITY_PROTECTION_NOT_POSSIBLE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UP_CONFIDENTIALITY_PROTECTION_NOT_POSSIBLE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_RESOURCES_NOT_AVAILABLE_FOR_THE_SLICE_S, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UE_MAX_IP_DATA_RATE_REASON, + XNAP_CAUSE_RADIO_NETWORK_LAYER_CP_INTEGRITY_PROTECTION_FAILURE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UP_INTEGRITY_PROTECTION_FAILURE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_SLICE_NOT_SUPPORTED_BY_NG_RAN, + XNAP_CAUSE_RADIO_NETWORK_LAYER_MN_MOBILITY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_SN_MOBILITY, + XNAP_CAUSE_RADIO_NETWORK_LAYER_COUNT_REACHES_MAX_VALUE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UNKNOWN_OLD_NG_RAN_NODE_UE_XNAP_ID, + XNAP_CAUSE_RADIO_NETWORK_LAYER_PDCP_OVERLOAD, + XNAP_CAUSE_RADIO_NETWORK_LAYER_DRB_ID_NOT_AVAILABLE, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UNSPECIFIED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_UE_CONTEXT_ID_NOT_KNOWN, + XNAP_CAUSE_RADIO_NETWORK_LAYER_NON_RELOCATION_OF_CONTEXT, + XNAP_CAUSE_RADIO_NETWORK_LAYER_CHO_CPC_RESOURCES_TOBECHANGED, + XNAP_CAUSE_RADIO_NETWORK_LAYER_RSN_NOT_AVAILABLE_FOR_THE_UP, + XNAP_CAUSE_RADIO_NETWORK_LAYER_NPN_ACCESS_DENIED +} xnap_cause_radio_network_t; + +typedef enum xnap_cause_transport_layer_e { + XNAP_CAUSE_TRANSPORT_LAYER_TRANSPORT_RESOURCE_UNAVAILABLE, + XNAP_CAUSE_TRANSPORT_LAYER_UNSPECIFIED +} xnap_cause_transport_layer_t; + +typedef enum xnap_cause_protocol_e { + XNAP_CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR, + XNAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT, + XNAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE_AND_NOTIFY, + XNAP_CAUSE_PROTOCOL_MESSAGE_NOT_COMPATIBLE_WITH_RECEIVER_STATE, + XNAP_CAUSE_PROTOCOL_SEMANTIC_ERROR, + XNAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED, + XNAP_CAUSE_PROTOCOL_UNSPECIFIED +} xnap_cause_protocol_t; + +typedef enum xnap_cause_misc_e { + XNAP_CAUSE_MISC_CONTROL_PROCESSING_OVERLOAD, + XNAP_CAUSE_MISC_HARDWARE_FAILURE, + XNAP_CAUSE_MISC_O_AND_M_INTERVENTION, + XNAP_CAUSE_MISC_NOT_ENOUGH_USER_PLANE_PROCESSING_RESOURCES, + XNAP_CAUSE_MISC_UNSPECIFIED +} xnap_cause_misc_t; + +typedef enum xnap_cause_group_e { + XNAP_CAUSE_NOTHING, + XNAP_CAUSE_RADIO_NETWORK, + XNAP_CAUSE_TRANSPORT, + XNAP_CAUSE_PROTOCOL, + XNAP_CAUSE_MISC, +} xnap_cause_group_t; + +typedef struct xnap_cause_s { + /* Cause group (e.g. radioNetwork, transport, protocol, misc) */ + xnap_cause_group_t type; + /* Specific cause value within the selected cause group */ + uint8_t value; +} xnap_cause_t; + +/* 3GPP TS 38.423 9.1.3.3 – Xn Setup Failure */ +typedef struct { + // Cause (M) + xnap_cause_t cause; +} xnap_setup_failure_t; + #endif /* XNAP_MESSAGES_TYPES_H_ */ diff --git a/openair2/XNAP/lib/xnap_gNB_interface_management.c b/openair2/XNAP/lib/xnap_gNB_interface_management.c index 409ce7b967..f77543504d 100644 --- a/openair2/XNAP/lib/xnap_gNB_interface_management.c +++ b/openair2/XNAP/lib/xnap_gNB_interface_management.c @@ -403,3 +403,69 @@ void free_xnap_setup_response(const xnap_setup_resp_t *msg) free_xnap_tai_support(msg->tai_support, msg->num_tai); } +/** + * @brief XnAP Setup Failure encoding + */ +XNAP_XnAP_PDU_t *encode_xn_setup_failure(const xnap_setup_failure_t *fail) +{ + XNAP_XnAP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + + /* Message type */ + pdu->present = XNAP_XnAP_PDU_PR_unsuccessfulOutcome; + asn1cCalloc(pdu->choice.unsuccessfulOutcome, failMsg); + failMsg->procedureCode = XNAP_ProcedureCode_id_xnSetup; + failMsg->criticality = XNAP_Criticality_reject; + failMsg->value.present = XNAP_UnsuccessfulOutcome__value_PR_XnSetupFailure; + + XNAP_XnSetupFailure_t *out = &failMsg->value.choice.XnSetupFailure; + + /* Cause (M) */ + asn1cSequenceAdd(out->protocolIEs.list, XNAP_XnSetupFailure_IEs_t, ie1); + ie1->id = XNAP_ProtocolIE_ID_id_Cause; + ie1->criticality = XNAP_Criticality_ignore; + ie1->value.present = XNAP_XnSetupFailure_IEs__value_PR_Cause; + xnap_gNB_set_cause(&ie1->value.choice.Cause, &fail->cause); + + return pdu; +} + +/** + * @brief XnAP Setup Failure decoding + */ +bool decode_xn_setup_failure(xnap_setup_failure_t *out, const XNAP_XnAP_PDU_t *pdu) +{ + /* Check message type */ + _EQ_CHECK_INT(pdu->present, XNAP_XnAP_PDU_PR_unsuccessfulOutcome); + AssertError(pdu->choice.unsuccessfulOutcome != NULL, return false, "unsuccessfulOutcome is NULL"); + _EQ_CHECK_LONG(pdu->choice.unsuccessfulOutcome->procedureCode, XNAP_ProcedureCode_id_xnSetup); + _EQ_CHECK_INT(pdu->choice.unsuccessfulOutcome->value.present, XNAP_UnsuccessfulOutcome__value_PR_XnSetupFailure); + + /* XnSetupFailure container */ + XNAP_XnSetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.XnSetupFailure; + XNAP_XnSetupFailure_IEs_t *ie; + + /* Check presence of mandatory IE */ + XNAP_LIB_FIND_IE(XNAP_XnSetupFailure_IEs_t, ie, &in->protocolIEs.list, XNAP_ProtocolIE_ID_id_Cause, true); + + /* Decode Cause */ + _EQ_CHECK_INT(ie->value.present, XNAP_XnSetupFailure_IEs__value_PR_Cause); + out->cause = decode_xnap_cause(&ie->value.choice.Cause); + + return true; +} + +/** + * @brief XnAP Setup Failure equality check + */ +bool eq_xnap_setup_failure(const xnap_setup_failure_t *a, const xnap_setup_failure_t *b) +{ + return eq_xnap_cause(&a->cause, &b->cause); +} + +/** + * @brief XnAP Setup Failure memory management + */ +void free_xnap_setup_failure(xnap_setup_failure_t *msg) +{ + // nothing to free +} diff --git a/openair2/XNAP/lib/xnap_gNB_interface_management.h b/openair2/XNAP/lib/xnap_gNB_interface_management.h index aab6f777e2..f1ffb8811c 100644 --- a/openair2/XNAP/lib/xnap_gNB_interface_management.h +++ b/openair2/XNAP/lib/xnap_gNB_interface_management.h @@ -28,14 +28,18 @@ typedef struct XNAP_XnAP_PDU XNAP_XnAP_PDU_t; XNAP_XnAP_PDU_t *encode_xn_setup_request(const xnap_setup_req_t *req); XNAP_XnAP_PDU_t *encode_xn_setup_response(const xnap_setup_resp_t *resp); +XNAP_XnAP_PDU_t *encode_xn_setup_failure(const xnap_setup_failure_t *fail); bool decode_xn_setup_request(xnap_setup_req_t *req, const XNAP_XnAP_PDU_t *pdu); bool decode_xn_setup_response(xnap_setup_resp_t *out, const XNAP_XnAP_PDU_t *pdu); +bool decode_xn_setup_failure(xnap_setup_failure_t *out, const XNAP_XnAP_PDU_t *pdu); bool eq_xnap_setup_request(const xnap_setup_req_t *a, const xnap_setup_req_t *b); bool eq_xnap_setup_response(const xnap_setup_resp_t *a, const xnap_setup_resp_t *b); +bool eq_xnap_setup_failure(const xnap_setup_failure_t *a, const xnap_setup_failure_t *b); void free_xnap_setup_request(const xnap_setup_req_t *msg); void free_xnap_setup_response(const xnap_setup_resp_t *msg); +void free_xnap_setup_failure(xnap_setup_failure_t *msg); #endif /* XNAP_GNB_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/XNAP/lib/xnap_lib_common.c b/openair2/XNAP/lib/xnap_lib_common.c index 9c6a09c80c..0d9b047ea9 100644 --- a/openair2/XNAP/lib/xnap_lib_common.c +++ b/openair2/XNAP/lib/xnap_lib_common.c @@ -23,6 +23,72 @@ #include "common/utils/assertions.h" #include "common/utils/utils.h" +int xnap_gNB_set_cause(XNAP_Cause_t *cause_p,const xnap_cause_t *in) +{ + DevAssert(cause_p != NULL); + switch (in->type) { + case XNAP_CAUSE_RADIO_NETWORK: + cause_p->present = XNAP_Cause_PR_radioNetwork; + cause_p->choice.radioNetwork = in->value; + break; + case XNAP_CAUSE_TRANSPORT: + cause_p->present = XNAP_Cause_PR_transport; + cause_p->choice.transport = in->value; + break; + case XNAP_CAUSE_PROTOCOL: + cause_p->present = XNAP_Cause_PR_protocol; + cause_p->choice.protocol = in->value; + break; + case XNAP_CAUSE_MISC: + cause_p->present = XNAP_Cause_PR_misc; + cause_p->choice.misc = in->value; + break; + case XNAP_CAUSE_NOTHING: + default: + AssertFatal(false, "unknown cause value %d\n", in->type); + break; + } + return 0; +} + +xnap_cause_t decode_xnap_cause(const XNAP_Cause_t *in) +{ + xnap_cause_t out = {0}; + switch (in->present) { + case XNAP_Cause_PR_radioNetwork: + out.type = XNAP_CAUSE_RADIO_NETWORK; + out.value = in->choice.radioNetwork; + break; + + case XNAP_Cause_PR_transport: + out.type = XNAP_CAUSE_TRANSPORT; + out.value = in->choice.transport; + break; + + case XNAP_Cause_PR_protocol: + out.type = XNAP_CAUSE_PROTOCOL; + out.value = in->choice.protocol; + break; + + case XNAP_Cause_PR_misc: + out.type = XNAP_CAUSE_MISC; + out.value = in->choice.misc; + break; + case XNAP_Cause_PR_NOTHING: + default: + PRINT_ERROR("received illegal XNAP cause %d\n", in->present); + break; + } + return out; +} + +bool eq_xnap_cause(const xnap_cause_t *a, const xnap_cause_t *b) +{ + _EQ_CHECK_INT(a->type, b->type); + _EQ_CHECK_INT(a->value, b->value); + return true; +} + bool eq_xnap_plmn(const plmn_id_t *a, const plmn_id_t *b) { _EQ_CHECK_INT(a->mcc, b->mcc); diff --git a/openair2/XNAP/lib/xnap_lib_common.h b/openair2/XNAP/lib/xnap_lib_common.h index cde0accd88..6186f55471 100644 --- a/openair2/XNAP/lib/xnap_lib_common.h +++ b/openair2/XNAP/lib/xnap_lib_common.h @@ -56,5 +56,9 @@ bool eq_xnap_plmn(const plmn_id_t *a, const plmn_id_t *b); bool eq_xnap_snssai(const nssai_t *a, const nssai_t *b); bool eq_xnap_tai_support(const xnap_tai_support_t *a, const xnap_tai_support_t *b); bool eq_xnap_plmn_support(const xnap_plmn_support_t *a, const xnap_plmn_support_t *b); +bool eq_xnap_cause(const xnap_cause_t *a, const xnap_cause_t *b); + +int xnap_gNB_set_cause(XNAP_Cause_t *cause_p,const xnap_cause_t *in); +xnap_cause_t decode_xnap_cause(const XNAP_Cause_t *in); #endif /* XNAP_LIB_COMMON_H_ */ diff --git a/openair2/XNAP/lib/xnap_lib_includes.h b/openair2/XNAP/lib/xnap_lib_includes.h index c45d9cf605..5e90adbea6 100644 --- a/openair2/XNAP/lib/xnap_lib_includes.h +++ b/openair2/XNAP/lib/xnap_lib_includes.h @@ -30,6 +30,7 @@ #include "XNAP_ProtocolIE-Field.h" #include "XNAP_InitiatingMessage.h" #include "XNAP_SuccessfulOutcome.h" +#include "XNAP_UnsuccessfulOutcome.h" #include "XNAP_GlobalgNB-ID.h" #include "XNAP_GlobalNG-RANNode-ID.h" @@ -37,6 +38,7 @@ #include "XNAP_TAISupport-Item.h" #include "XNAP_S-NSSAI.h" #include "XNAP_BroadcastPLMNinTAISupport-Item.h" +#include "XNAP_Cause.h" #endif // XNAP_LIB_INCLUDES_H diff --git a/openair2/XNAP/tests/xnap_lib_test.c b/openair2/XNAP/tests/xnap_lib_test.c index 610dc7d744..3c1ec3375a 100644 --- a/openair2/XNAP/tests/xnap_lib_test.c +++ b/openair2/XNAP/tests/xnap_lib_test.c @@ -249,12 +249,43 @@ static void test_xn_setup_response(void) printf("%s() successful \n", __func__); } +/** + * 3. Xn Setup Failure + */ +static void test_xn_setup_failure(void) +{ + /* ---------- create message ---------- */ + xnap_setup_failure_t orig = { + .cause.type = XNAP_CAUSE_TRANSPORT, + .cause.value = XNAP_CAUSE_TRANSPORT_LAYER_TRANSPORT_RESOURCE_UNAVAILABLE, + }; + + /* ---------- encode ---------- */ + XNAP_XnAP_PDU_t *xnenc = encode_xn_setup_failure(&orig); + XNAP_XnAP_PDU_t *xndec = xnap_encode_decode(xnenc); + xnap_msg_free(xnenc); + + /* ---------- decode ---------- */ + xnap_setup_failure_t decoded = {0}; + bool ret = decode_xn_setup_failure(&decoded, xndec); + AssertFatal(ret, "decode_xn_setup_failure failed"); + xnap_msg_free(xndec); + + /* ---------- equality ---------- */ + ret = eq_xnap_setup_failure(&orig, &decoded); + AssertFatal(ret, "Xn Setup Failure mismatch\n"); + free_xnap_setup_failure(&decoded); + free_xnap_setup_failure(&orig); + printf("%s() successful \n", __func__); +} + int main() { printf("Starting XnAP Library Unit Tests...\n"); /* Xn Interface Testing */ test_xn_setup_request(); test_xn_setup_response(); + test_xn_setup_failure(); printf("All XnAP tests passed!\n"); return 0;