pespin submitted this change.

View Change

Approvals: Jenkins Builder: Verified osmith: Looks good to me, approved laforge: Looks good to me, but someone else must approve
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(-)

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;
+}

To view, visit change 38550. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I2c38b2d8104e728dda234c36ea284266b4c55ab1
Gerrit-Change-Number: 38550
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: osmith <osmith@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>