aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;