diff options
-rw-r--r-- | include/osmocom/msc/gsm_04_80.h | 6 | ||||
-rw-r--r-- | src/libmsc/gsm_04_80.c | 33 | ||||
-rw-r--r-- | src/libmsc/ussd.c | 10 |
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; |