aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-06-08 17:13:44 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2018-06-08 17:13:44 +0700
commit635f98cf31d20008b9726ef82ba87e172c49f264 (patch)
treeb3a845c0984e0f159d935643243edd230bcd0149
parent5046db98b106a3c583d7fe296e0748f1bde34629 (diff)
libmsc/ussd.c: FIX: properly indicate errors
There are error and problem codes defined by GSM TS 04.80: - Error codes are used when a message is structured correctly, but something is wrong in context of the current operation. Usually they are carried by 'Return Error' component. - Problem codes are used when something is wrong with the message structure, or with carried values. They are carried by 'Reject' component. There are three groups of them (see table 3.13): - General Problem Codes (table 3.14), - Invoke Problem Codes (table 3.15), - Return Result Problem Codes (table 3.16), - Return Error Problem Codes (table 3.17). The first group is general purpose, and can be sent in response to any kind of message, excluding 'Reject' itself. Other ones are bound to specific component types, such as 'Invoke', 'Return Result' and 'Return Error'. For some reason, a 'Reject' component with the general problem code 'GSM_0480_GEN_PROB_CODE_UNRECOGNISED' was always used in OsmoMSC. Even when the message structure is correct. Let's properly indicate errors in the following way: - 'Reject' with GSM_0480_GEN_PROB_CODE_UNRECOGNISED when the gsm0480_decode_ss_request() fails to decode a message. It can only return 0 or 1, so it's hard to guess which exact part of message caused the error. - 'Return Error' with GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION when the operation code is not related to USSD. - 'Return Error' with GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE when the requested USSD code is unhandled (not supported). There is a TTCN-3 testcase for this: https://gerrit.osmocom.org/9470/ Change-Id: I800e7ec98dc9d0bca2d45a8b8255d60253d63e14
-rw-r--r--include/osmocom/msc/gsm_04_80.h6
-rw-r--r--src/libmsc/gsm_04_80.c33
-rw-r--r--src/libmsc/ussd.c10
3 files changed, 41 insertions, 8 deletions
diff --git a/include/osmocom/msc/gsm_04_80.h b/include/osmocom/msc/gsm_04_80.h
index dedf2438a..fb057c8db 100644
--- a/include/osmocom/msc/gsm_04_80.h
+++ b/include/osmocom/msc/gsm_04_80.h
@@ -9,8 +9,12 @@ struct gsm_subscriber_connection;
int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
const char* response_text,
const struct ss_request *req);
+int gsm0480_send_ussd_return_error(struct gsm_subscriber_connection *conn,
+ const struct ss_request *req,
+ uint8_t error_code);
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
- const struct ss_request *request);
+ const struct ss_request *req,
+ uint8_t error_tag, uint8_t error_code);
int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,
const char *text);
diff --git a/src/libmsc/gsm_04_80.c b/src/libmsc/gsm_04_80.c
index 12b41a19d..8799fcbdc 100644
--- a/src/libmsc/gsm_04_80.c
+++ b/src/libmsc/gsm_04_80.c
@@ -108,15 +108,42 @@ int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
return msc_tx_dtap(conn, msg);
}
+int gsm0480_send_ussd_return_error(struct gsm_subscriber_connection *conn,
+ const struct ss_request *req, uint8_t error_code)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD ERR");
+ struct gsm48_hdr *gh;
+
+ /* First insert the problem code */
+ msgb_push_TLV1(msg, GSM_0480_ERROR_CODE_TAG, error_code);
+
+ /* Before it insert the invoke ID */
+ msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);
+
+ /* Wrap this up as a Reject component */
+ msgb_wrap_with_TL(msg, GSM0480_CTYPE_RETURN_ERROR);
+
+ /* Wrap the component in a Facility message */
+ msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY);
+
+ /* And finally pre-pend the L3 header */
+ gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_NC_SS;
+ gh->proto_discr |= req->transaction_id | (1<<7); /* TI direction = 1 */
+ gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
+
+ return msc_tx_dtap(conn, msg);
+}
+
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
- const struct ss_request *req)
+ const struct ss_request *req,
+ uint8_t error_tag, uint8_t error_code)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD REJ");
struct gsm48_hdr *gh;
/* First insert the problem code */
- msgb_push_TLV1(msg, GSM_0480_PROBLEM_CODE_TAG_GENERAL,
- GSM_0480_GEN_PROB_CODE_UNRECOGNISED);
+ msgb_push_TLV1(msg, error_tag, error_code);
/* Before it insert the invoke ID */
msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);
diff --git a/src/libmsc/ussd.c b/src/libmsc/ussd.c
index fe1610f44..f285fcf8a 100644
--- a/src/libmsc/ussd.c
+++ b/src/libmsc/ussd.c
@@ -74,7 +74,8 @@ int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
if (!rc) {
LOGP(DMM, LOGL_ERROR, "SS/USSD message parsing error, "
"rejecting request...\n");
- gsm0480_send_ussd_reject(conn, &req);
+ gsm0480_send_ussd_reject(conn, &req, GSM_0480_PROBLEM_CODE_TAG_GENERAL,
+ GSM_0480_GEN_PROB_CODE_UNRECOGNISED);
/* The GSM 04.80 API uses inverted codes (0 means error) */
return -EPROTO;
}
@@ -83,8 +84,8 @@ int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
if (req.ussd_text[0] == '\0' || req.ussd_text[0] == 0xFF) {
if (req.ss_code > 0) {
/* Assume interrogateSS or modification of it and reject */
- rc = gsm0480_send_ussd_reject(conn, &req);
- return rc;
+ return gsm0480_send_ussd_return_error(conn, &req,
+ GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION);
}
/* Still assuming a Release-Complete and returning */
return 0;
@@ -96,7 +97,8 @@ int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
rc = send_own_number(conn, &req);
} else {
DEBUGP(DMM, "Unhandled USSD %s\n", req.ussd_text);
- rc = gsm0480_send_ussd_reject(conn, &req);
+ rc = gsm0480_send_ussd_return_error(conn, &req,
+ GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE);
}
return rc;