pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/38550?usp=email )
Change subject: sua, sccp: Add APIs to get cause string description ......................................................................
sua, sccp: Add APIs to get cause string description
Change-Id: I2c38b2d8104e728dda234c36ea284266b4c55ab1 --- M TODO-RELEASE M include/osmocom/sccp/sccp_types.h M include/osmocom/sigtran/protocol/sua.h M src/sccp_types.c M src/sua.c 5 files changed, 166 insertions(+), 0 deletions(-)
Approvals: Jenkins Builder: Verified osmith: Looks good to me, approved laforge: Looks good to me, but someone else must approve
diff --git a/TODO-RELEASE b/TODO-RELEASE index 935cda8..6d8cb80 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -8,3 +8,4 @@ # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line libosmo-sigtran API change struct osmo_ss7_instance has new member 'secondary_pc' +libosmo-sigtran add API osmo_sccp_{release,return,reset,error,refusal}_cause_name(s), osmo_sua_sccp_cause_name diff --git a/include/osmocom/sccp/sccp_types.h b/include/osmocom/sccp/sccp_types.h index bc11258..5be0392 100644 --- a/include/osmocom/sccp/sccp_types.h +++ b/include/osmocom/sccp/sccp_types.h @@ -209,6 +209,9 @@ SCCP_RELEASE_CAUSE_UNQUALIFIED = 15, SCCP_RELEASE_CAUSE_SCCP_FAILURE = 16, }; +extern const struct value_string osmo_sccp_release_cause_names[]; +static inline const char *osmo_sccp_release_cause_name(enum sccp_release_cause val) +{ return get_value_string(osmo_sccp_release_cause_names, val); }
/* ITU-T Q.713, Section 3.12 Return cause */ enum sccp_return_cause { @@ -228,6 +231,9 @@ SCCP_RETURN_CAUSE_SEGMENTATION_NOT_SUPPORTED= 13, SCCP_RETURN_CAUSE_SEGMENTATION_FAILURE = 14 }; +extern const struct value_string osmo_sccp_return_cause_names[]; +static inline const char *osmo_sccp_return_cause_name(enum sccp_return_cause val) +{ return get_value_string(osmo_sccp_return_cause_names, val); }
/* ITU-T Q.713, Section 3.13 Reset cause */ enum sccp_reset_cause { @@ -243,7 +249,11 @@ SCCP_RESET_CAUSE_ACCESS_OPERATIONAL = 9, SCCP_RESET_CAUSE_NETWORK_CONGESTION = 10, SCCP_RESET_CAUSE_RESERVED = 11, + SCCP_RESET_CAUSE_UNQUALIFIED = 12, }; +extern const struct value_string osmo_sccp_reset_cause_names[]; +static inline const char *osmo_sccp_reset_cause_name(enum sccp_reset_cause val) +{ return get_value_string(osmo_sccp_reset_cause_names, val); }
/* ITU-T Q.713, Section 3.14 Error cause */ enum sccp_error_cause { @@ -253,6 +263,9 @@ SCCP_ERROR_SERVICE_CLASS_MISMATCH = 3, SCCP_ERROR_UNQUALIFIED = 4, }; +extern const struct value_string osmo_sccp_error_cause_names[]; +static inline const char *osmo_sccp_error_cause_name(enum sccp_error_cause val) +{ return get_value_string(osmo_sccp_error_cause_names, val); }
/* ITU-T Q.713 Section 3.15 Refusal cause */ enum sccp_refusal_cause { @@ -277,6 +290,9 @@ SCCP_REFUSAL_NO_TRANS_FOR_ADDRESS_NATURE = 18, SCCP_REFUSAL_UNEQUIPPED_USER = 19, }; +extern const struct value_string osmo_sccp_refusal_cause_names[]; +static inline const char *osmo_sccp_refusal_cause_name(enum sccp_refusal_cause val) +{ return get_value_string(osmo_sccp_refusal_cause_names, val); }
/* * messages... as of Q.713 Chapter 4 diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index 4ce88f9..6fed2bc 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -19,6 +19,7 @@ */
#pragma once +#include <stddef.h> #include <stdint.h>
#include <osmocom/sigtran/protocol/m3ua.h> @@ -138,6 +139,8 @@ #define SUA_CAUSE_T_RESET 0x0400 #define SUA_CAUSE_T_ERROR 0x0500
+const char *osmo_sua_sccp_cause_name(uint32_t sccp_cause, char *out_buf, size_t out_buf_len); + /* 3.9.12 Error: Identical to M3UA, extended by two at the bottom */ #define SUA_ERR_INVALID_VERSION M3UA_ERR_INVALID_VERSION #define SUA_ERR_UNSUPP_MSG_CLASS M3UA_ERR_UNSUPP_MSG_CLASS diff --git a/src/sccp_types.c b/src/sccp_types.c index 98b3fa4..a923aa2 100644 --- a/src/sccp_types.c +++ b/src/sccp_types.c @@ -49,3 +49,98 @@ { SCCP_PNC_LONG_DATA, "Long data" }, {} }; + +/* ITU-T Q.713, Section 3.11 Release cause */ +const struct value_string osmo_sccp_release_cause_names[] = { + { SCCP_RELEASE_CAUSE_END_USER_ORIGINATED, "end user originated" }, + { SCCP_RELEASE_CAUSE_END_USER_CONGESTION, "end user congestion" }, + { SCCP_RELEASE_CAUSE_END_USER_FAILURE, "end user failure" }, + { SCCP_RELEASE_CAUSE_SCCP_USER_ORIGINATED, "SCCP user originated" }, + { SCCP_RELEASE_CAUSE_REMOTE_PROCEDURE_ERROR, "remote procedure error" }, + { SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA, "inconsistent connection data" }, + { SCCP_RELEASE_CAUSE_ACCESS_FAILURE, "access failure" }, + { SCCP_RELEASE_CAUSE_ACCESS_CONGESTION, "access congestion" }, + { SCCP_RELEASE_CAUSE_SUBSYSTEM_FAILURE, "subsystem failure" }, + { SCCP_RELEASE_CAUSE_SUBSYSTEM_CONGESTION, "subsystem congestion" }, + { SCCP_RELEASE_CAUSE_MTP_FAILURE, "MTP failure" }, + { SCCP_RELEASE_CAUSE_NETWORK_CONGESTION, "network congestion" }, + { SCCP_RELEASE_CAUSE_EXPIRATION_RESET, "expiration of reset timer" }, + { SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE, "expiration of receive inactivity timer" }, + { SCCP_RELEASE_CAUSE_RESERVED, "reserved" }, + { SCCP_RELEASE_CAUSE_UNQUALIFIED, "unqualified" }, + { SCCP_RELEASE_CAUSE_SCCP_FAILURE, "SCCP failure" }, + {} +}; + +/* ITU-T Q.713, Section 3.12 Return cause */ +const struct value_string osmo_sccp_return_cause_names[] = { + { SCCP_RETURN_CAUSE_NO_TRANSLATION_NATURE, "no translation for an address of such nature" }, + { SCCP_RETURN_CAUSE_NO_TRANSLATION, "no translation for this specific address" }, + { SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION, "subsystem congestion" }, + { SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE, "subsystem failure" }, + { SCCP_RETURN_CAUSE_UNEQUIPPED_USER, "unequipped user" }, + { SCCP_RETURN_CAUSE_MTP_FAILURE, "MTP failure" }, + { SCCP_RETURN_CAUSE_NETWORK_CONGESTION, "network congestion" }, + { SCCP_RETURN_CAUSE_UNQUALIFIED, "unqualified" }, + { SCCP_RETURN_CAUSE_ERROR_IN_MSG_TRANSPORT, "error in message transport" }, + { SCCP_RETURN_CAUSE_ERROR_IN_LOCAL_PROCESSING, "error in local processing" }, + { SCCP_RETURN_CAUSE_DEST_CANNOT_PERFORM_REASSEMBLY, "destination cannot perform reassembly" }, + { SCCP_RETURN_CAUSE_SCCP_FAILURE, "SCCP failure" }, + { SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION, "hop counter violation" }, + { SCCP_RETURN_CAUSE_SEGMENTATION_NOT_SUPPORTED, "segmentation not supported" }, + { SCCP_RETURN_CAUSE_SEGMENTATION_FAILURE, "segmentation failure" }, + {} +}; + +/* ITU-T Q.713, Section 3.13 Reset cause */ +const struct value_string osmo_sccp_reset_cause_names[] = { + { SCCP_RESET_CAUSE_END_USER_ORIGINATED, "end user originated" }, + { SCCP_RESET_CAUSE_SCCP_USER_ORIGINATED, "SCCP user originated" }, + { SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PS, "message out of order - incorrect P(S)" }, + { SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PR, "message out of order - incorrect P(R)" }, + { SCCP_RESET_CAUSE_RPC_OUT_OF_WINDOW, "remote procedure error - message out of window" }, + { SCCP_RESET_CAUSE_RPC_INCORRECT_PS, "remote procedure error - incorrect P(S) after (re)initialization" }, + { SCCP_RESET_CAUSE_RPC_GENERAL, "remote procedure error - general" }, + { SCCP_RESET_CAUSE_REMOTE_END_USER_OPERATIONAL, "remote end user operational" }, + { SCCP_RESET_CAUSE_NETWORK_OPERATIONAL, "network operational" }, + { SCCP_RESET_CAUSE_ACCESS_OPERATIONAL, "access operational" }, + { SCCP_RESET_CAUSE_NETWORK_CONGESTION, "network congestion" }, + { SCCP_RESET_CAUSE_RESERVED, "reserved" }, + { SCCP_RESET_CAUSE_UNQUALIFIED, "unqualified"}, + {} +}; + +/* ITU-T Q.713, Section 3.14 Error cause */ +const struct value_string osmo_sccp_error_cause_names[] = { + { SCCP_ERROR_LRN_MISMATCH_UNASSIGNED, "local reference number (LRN) mismatch - unassigned destination LRN" }, + { SCCP_ERROR_LRN_MISMATCH_INCONSISTENT, "local reference number (LRN) mismatch - inconsistent source LRN" }, + { SCCP_ERROR_POINT_CODE_MISMATCH, "point code mismatch" }, + { SCCP_ERROR_SERVICE_CLASS_MISMATCH, "service class mismatch" }, + { SCCP_ERROR_UNQUALIFIED, "unqualified" }, + {} +}; + +/* ITU-T Q.713 Section 3.15 Refusal cause */ +const struct value_string osmo_sccp_refusal_cause_names[] = { + { SCCP_REFUSAL_END_USER_ORIGINATED, "end user originated" }, + { SCCP_REFUSAL_END_USER_CONGESTION, "end user congestion" }, + { SCCP_REFUSAL_END_USER_FAILURE, "end user failure" }, + { SCCP_REFUSAL_SCCP_USER_ORIGINATED, "SCCP user originated" }, + { SCCP_REFUSAL_DESTINATION_ADDRESS_UKNOWN, "destination address unknown" }, + { SCCP_REFUSAL_DESTINATION_INACCESSIBLE, "destination inaccessible" }, + { SCCP_REFUSAL_NET_QOS_NON_TRANSIENT, "network resource - QoS not available/non-transient" }, + { SCCP_REFUSAL_NET_QOS_TRANSIENT, "network resource - QoS not available/transient" }, + { SCCP_REFUSAL_ACCESS_FAILURE, "access failure" }, + { SCCP_REFUSAL_ACCESS_CONGESTION, "access congestion" }, + { SCCP_REFUSAL_SUBSYSTEM_FAILURE, "subsystem failure" }, + { SCCP_REFUSAL_SUBSYTEM_CONGESTION, "subsystem congestion" }, + { SCCP_REFUSAL_EXPIRATION, "expiration of the connection establishment timer" }, + { SCCP_REFUSAL_INCOMPATIBLE_USER_DATA, "incompatible user data" }, + { SCCP_REFUSAL_RESERVED, "reserved" }, + { SCCP_REFUSAL_UNQUALIFIED, "unqualified" }, + { SCCP_REFUSAL_HOP_COUNTER_VIOLATION, "hop counter violation" }, + { SCCP_REFUSAL_SCCP_FAILURE, "SCCP failure" }, + { SCCP_REFUSAL_NO_TRANS_FOR_ADDRESS_NATURE, "no translation for an address of such nature" }, + { SCCP_REFUSAL_UNEQUIPPED_USER, "unequipped user" }, + {} +}; diff --git a/src/sua.c b/src/sua.c index 2753cfe..d8eb9e5 100644 --- a/src/sua.c +++ b/src/sua.c @@ -41,6 +41,7 @@ #include <osmocom/sigtran/protocol/sua.h> #include <osmocom/sigtran/protocol/m3ua.h> #include <osmocom/sigtran/osmo_ss7.h> +#include <osmocom/sccp/sccp_types.h>
#include "xua_as_fsm.h" #include "xua_asp_fsm.h" @@ -1008,3 +1009,53 @@ return SUA_ERR_UNSUPP_MSG_CLASS; } } + +/* RFC 3868 3.10.6. SCCP Cause */ +const struct value_string sua_cause_type_names[] = { + { SUA_CAUSE_T_RETURN, "Return Cause" }, + { SUA_CAUSE_T_REFUSAL, "Refusal Cause" }, + { SUA_CAUSE_T_RELEASE, "Release Cause" }, + { SUA_CAUSE_T_RESET, "Reset Cause" }, + { SUA_CAUSE_T_ERROR, "Error Cause" }, + {} +}; +const char *osmo_sua_sccp_cause_name(uint32_t sccp_cause, char *out_buf, size_t out_buf_len) +{ + uint16_t cause_type = sccp_cause & SUA_CAUSE_T_MASK; + uint8_t cause_val = sccp_cause & 0xff; + const char *cause_type_str = get_value_string_or_null(sua_cause_type_names, cause_type); + const char *cause_str = NULL; + + if (!out_buf || out_buf_len == 0) + return NULL; + + if (!cause_type_str) + goto ret_unknown_cause_type; + + switch (cause_type) { + case SUA_CAUSE_T_RETURN: + cause_str = osmo_sccp_return_cause_name(cause_val); + break; + case SUA_CAUSE_T_REFUSAL: + cause_str = osmo_sccp_refusal_cause_name(cause_val); + break; + case SUA_CAUSE_T_RELEASE: + cause_str = osmo_sccp_release_cause_name(cause_val); + break; + case SUA_CAUSE_T_RESET: + cause_str = osmo_sccp_reset_cause_name(cause_val); + break; + case SUA_CAUSE_T_ERROR: + cause_str = osmo_sccp_error_cause_name(cause_val); + break; + default: + goto ret_unknown_cause_type; + } + + snprintf(out_buf, out_buf_len, "%s <%s>", cause_type_str, cause_str); + return out_buf; + +ret_unknown_cause_type: + snprintf(out_buf, out_buf_len, "Unknown SUA SCCP Cause 0x%08x\n", sccp_cause); + return out_buf; +}