Signed-off-by: Max <[email protected]>
---
 openbsc/include/openbsc/Makefile.am |   2 +-
 openbsc/include/openbsc/db.h        |   4 +
 openbsc/include/openbsc/gsm_04_80.h |  36 ++++++--
 openbsc/include/openbsc/ss.h        |  10 +++
 openbsc/include/openbsc/ussd.h      |  10 ---
 openbsc/src/libmsc/Makefile.am      |   2 +-
 openbsc/src/libmsc/db.c             |  89 +++++++++++++++++++
 openbsc/src/libmsc/gsm_04_08.c      |   4 +-
 openbsc/src/libmsc/gsm_04_80.c      |  65 ++++++++------
 openbsc/src/libmsc/ss.c             | 173 ++++++++++++++++++++++++++++++++++++
 openbsc/src/libmsc/ussd.c           |  87 ------------------
 11 files changed, 349 insertions(+), 133 deletions(-)
 create mode 100644 openbsc/include/openbsc/ss.h
 delete mode 100644 openbsc/include/openbsc/ussd.h
 create mode 100644 openbsc/src/libmsc/ss.c
 delete mode 100644 openbsc/src/libmsc/ussd.c

diff --git a/openbsc/include/openbsc/Makefile.am 
b/openbsc/include/openbsc/Makefile.am
index 254f43d..b19c413 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -2,7 +2,7 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h 
gsm_data.h \
                 gsm_subscriber.h gsm_04_11.h debug.h signal.h \
                 misdn.h chan_alloc.h paging.h ctrl.h \
                 trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \
-                bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
+                bsc_rll.h mncc.h transaction.h ss.h gsm_04_80.h \
                 silent_call.h mgcp.h meas_rep.h rest_octets.h \
                 system_information.h handover.h mgcp_internal.h \
                 vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h
index 6699a86..73c061b 100644
--- a/openbsc/include/openbsc/db.h
+++ b/openbsc/include/openbsc/db.h
@@ -79,4 +79,8 @@ int db_store_counter(struct osmo_counter *ctr);
 struct rate_ctr_group;
 int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);

+/* Supplementary Services */
+int db_ss_interrogate_status(struct gsm_subscriber *subscr, uint8_t ss_code, 
uint8_t bs_code, uint8_t *ss_status);
+int db_ss_set_status(struct gsm_subscriber *subscr, uint8_t ss_code, uint8_t 
bs_code, uint8_t ss_status);
+
 #endif /* _DB_H */
diff --git a/openbsc/include/openbsc/gsm_04_80.h 
b/openbsc/include/openbsc/gsm_04_80.h
index 0a60652..7139f95 100644
--- a/openbsc/include/openbsc/gsm_04_80.h
+++ b/openbsc/include/openbsc/gsm_04_80.h
@@ -3,16 +3,42 @@

 #include <osmocom/core/msgb.h>
 #include <osmocom/gsm/protocol/gsm_04_80.h>
+#include <osmocom/gsm/protocol/gsm_09_02.h>
 #include <osmocom/gsm/gsm0480.h>

 struct gsm_subscriber_connection;

+/* FIXME: replace with libosmocore functions */
+static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag)
+{
+       uint8_t *data = msgb_push(msgb, 2);
+
+       data[0] = tag;
+       data[1] = msgb->len - 2;
+       return data;
+}
+
+static inline unsigned char *msgb_push_TLV1(struct msgb *msgb, uint8_t tag,
+                                           uint8_t value)
+{
+       uint8_t *data = msgb_push(msgb, 3);
+
+       data[0] = tag;
+       data[1] = 1;
+       data[2] = value;
+       return data;
+}
+
 int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
-                              const struct msgb *in_msg, const char* 
response_text, 
-                              const struct ussd_request *req);
-int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
-                            const struct msgb *msg, 
-                            const struct ussd_request *request);
+                              const char* response_text,
+                              const struct ss_request *req);
+int gsm0480_send_ss_return_result(struct gsm_subscriber_connection *conn,
+                                 const struct ss_request *req,
+                                 struct msgb *msg);
+int gsm0480_send_ss_reject(struct gsm_subscriber_connection *conn,
+                          const struct ss_request *request,
+                          uint8_t problem_category,
+                          uint8_t problem_code);

 int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, 
const char *text);
 int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);
diff --git a/openbsc/include/openbsc/ss.h b/openbsc/include/openbsc/ss.h
new file mode 100644
index 0000000..92ce913
--- /dev/null
+++ b/openbsc/include/openbsc/ss.h
@@ -0,0 +1,10 @@
+#ifndef _SS_H
+#define _SS_H
+
+/* Handler function for mobile-originated SS messages */
+
+#include <osmocom/core/msgb.h>
+
+int handle_rcv_ss(struct gsm_subscriber_connection *conn, struct msgb *msg);
+
+#endif
diff --git a/openbsc/include/openbsc/ussd.h b/openbsc/include/openbsc/ussd.h
deleted file mode 100644
index 2665468..0000000
--- a/openbsc/include/openbsc/ussd.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _USSD_H
-#define _USSD_H
-
-/* Handler function for mobile-originated USSD messages */
-
-#include <osmocom/core/msgb.h>
-
-int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg);
-
-#endif
diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am
index aa7d8ae..de0ce66 100644
--- a/openbsc/src/libmsc/Makefile.am
+++ b/openbsc/src/libmsc/Makefile.am
@@ -16,7 +16,7 @@ libmsc_a_SOURCES =    auth.c \
                        silent_call.c \
                        sms_queue.c \
                        token_auth.c \
-                       ussd.c \
+                       ss.c \
                        vty_interface_layer3.c \
                        transaction.c \
                        osmo_msc.c ctrl_commands.c meas_feed.c
diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c
index 428f99b..25dd00e 100644
--- a/openbsc/src/libmsc/db.c
+++ b/openbsc/src/libmsc/db.c
@@ -41,6 +41,8 @@
 /* Semi-Private-Interface (SPI) for the subscriber code */
 void subscr_direct_free(struct gsm_subscriber *subscr);

+#include <osmocom/gsm/protocol/gsm_09_02.h>
+
 static char *db_basename = NULL;
 static char *db_dirname = NULL;
 static dbi_conn conn;
@@ -174,6 +176,15 @@ static const char *create_stmts[] = {
                "sres BLOB NOT NULL, "
                "kc BLOB NOT NULL "
                ")",
+       "CREATE TABLE IF NOT EXISTS SS_Status ("
+               "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
+               "subscriber INTEGER NOT NULL, "
+               "ss_code TINYINT UNSIGNED NOT NULL, "
+               "bs_code TINYINT UNSIGNED, "
+               "ss_status TINYINT UNSIGNED NOT NULL, "
+               "UNIQUE(subscriber, ss_code, bs_code), "
+               "FOREIGN KEY(subscriber) REFERENCES Subscriber (id) ON DELETE 
CASCADE ON UPDATE CASCADE "
+               ")",
 };

 void db_error_func(dbi_conn conn, void *data)
@@ -1724,3 +1735,81 @@ int db_store_rate_ctr_group(struct rate_ctr_group *ctrg)

        return 0;
 }
+
+int db_ss_interrogate_status(struct gsm_subscriber *subscr, uint8_t ss_code, 
uint8_t bs_code, uint8_t *ss_status)
+{
+       char buf[32];
+       dbi_result result;
+
+       /* Copy the id to a string as queryf with %llu is failing */
+       sprintf(buf, "%llu", subscr->id);
+       result = dbi_conn_queryf(conn,
+                                "SELECT ss_status FROM SS_Status "
+                                "WHERE subscriber = %s "
+                                "AND ss_code = %i AND bs_code = %i",
+                                buf, ss_code, bs_code);
+
+       if (!result) {
+               LOGP(DDB,
+                    LOGL_ERROR,
+                    "Failed to query ss_status for subscriber %llu, "
+                    "ss code 0x%02X, bs code 0x%02X\n",
+                    subscr->id, ss_code, bs_code);
+               return -EIO;
+       }
+       if (!dbi_result_next_row(result)) {
+               DEBUGP(DDB,
+                      "Failed to find ss_status for subscriber %llu, "
+                      "ss code 0x%02X, bs code 0x%02X\n",
+                      subscr->id, ss_code, bs_code);
+               dbi_result_free(result);
+               return -ENOENT;
+       }
+
+       *ss_status = dbi_result_get_uint(result, "ss_status");
+       DEBUGP(DDB,
+              "Found ss_status for subscriber %llu, "
+              "ss code 0x%02X, bs code 0x%02X: P:%d R:%d A:%d Q:%d\n",
+              subscr->id, ss_code, bs_code,
+              (*ss_status & GSM0902_SS_STATUS_P_BIT) && 1,
+              (*ss_status & GSM0902_SS_STATUS_R_BIT) && 1,
+              (*ss_status & GSM0902_SS_STATUS_A_BIT) && 1,
+              (*ss_status & GSM0902_SS_STATUS_Q_BIT) && 1);
+
+       dbi_result_free(result);
+       return 0;
+}
+
+int db_ss_set_status(struct gsm_subscriber *subscr, uint8_t ss_code, uint8_t 
bs_code, uint8_t ss_status)
+{
+       char buf[32];
+       dbi_result result;
+
+       /* Copy the id to a string as queryf with %llu is failing */
+       sprintf(buf, "%llu", subscr->id);
+
+       result = dbi_conn_queryf(conn,
+                                "UPDATE SS_Status SET ss_status = %i "
+                                "WHERE subscriber = %s AND "
+                                "ss_code = %i AND bs_code = %i",
+                                ss_status, buf, ss_code, bs_code);
+
+       if (!result) {
+               LOGP(DDB, LOGL_ERROR,
+                    "Failed to set ss_status for subscriber %llu\n",
+                    subscr->id);
+               return -EIO;
+       }
+
+       DEBUGP(DDB,
+              "Set ss_status for subscriber %llu, "
+              "ss code 0x%02X, bs code 0x%02X: P:%d R:%d A:%d Q:%d\n",
+              subscr->id, ss_code, bs_code,
+              (ss_status & GSM0902_SS_STATUS_P_BIT) && 1,
+              (ss_status & GSM0902_SS_STATUS_R_BIT) && 1,
+              (ss_status & GSM0902_SS_STATUS_A_BIT) && 1,
+              (ss_status & GSM0902_SS_STATUS_Q_BIT) && 1);
+
+       dbi_result_free(result);
+       return 0;
+}
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 29ab2ba..01f8f32 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -47,7 +47,7 @@
 #include <openbsc/trau_mux.h>
 #include <openbsc/rtp_proxy.h>
 #include <openbsc/transaction.h>
-#include <openbsc/ussd.h>
+#include <openbsc/ss.h>
 #include <openbsc/silent_call.h>
 #include <openbsc/bsc_api.h>
 #include <openbsc/osmo_msc.h>
@@ -3340,7 +3340,7 @@ int gsm0408_dispatch(struct gsm_subscriber_connection 
*conn, struct msgb *msg)
                break;
        case GSM48_PDISC_NC_SS:
                release_anchor(conn);
-               rc = handle_rcv_ussd(conn, msg);
+               rc = handle_rcv_ss(conn, msg);
                break;
        default:
                LOGP(DRLL, LOGL_NOTICE, "Unknown "
diff --git a/openbsc/src/libmsc/gsm_04_80.c b/openbsc/src/libmsc/gsm_04_80.c
index b30f9ee..b20521a 100644
--- a/openbsc/src/libmsc/gsm_04_80.c
+++ b/openbsc/src/libmsc/gsm_04_80.c
@@ -39,31 +39,11 @@
 #include <osmocom/core/msgb.h>
 #include <osmocom/gsm/tlv.h>

-static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag)
-{
-       uint8_t *data = msgb_push(msgb, 2);
-
-       data[0] = tag;
-       data[1] = msgb->len - 2;
-       return data;
-}
-
-static inline unsigned char *msgb_push_TLV1(struct msgb *msgb, uint8_t tag,
-                                           uint8_t value)
-{
-       uint8_t *data = msgb_push(msgb, 3);
-
-       data[0] = tag;
-       data[1] = 1;
-       data[2] = value;
-       return data;
-}
-

 /* Send response to a mobile-originated ProcessUnstructuredSS-Request */
 int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
-                              const struct msgb *in_msg, const char 
*response_text,
-                              const struct ussd_request *req)
+                              const char *response_text,
+                              const struct ss_request *req)
 {
        struct msgb *msg = gsm48_msgb_alloc();
        struct gsm48_hdr *gh;
@@ -109,16 +89,47 @@ int gsm0480_send_ussd_response(struct 
gsm_subscriber_connection *conn,
        return gsm0808_submit_dtap(conn, msg, 0, 0);
 }

-int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
-                            const struct msgb *in_msg,
-                            const struct ussd_request *req)
+/* Send response to a mobile-originated Invoke */
+int gsm0480_send_ss_return_result(struct gsm_subscriber_connection *conn,
+                                  const struct ss_request *req,
+                                  struct msgb *msg)
+{
+       struct gsm48_hdr *gh;
+
+       /* Pre-pend the operation code */
+       msgb_push_TLV1(msg, GSM0480_OPERATION_CODE, req->opcode);
+
+       /* Wrap the contents as a sequence */
+       msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG);
+
+       /* Pre-pend the invoke ID */
+       msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);
+
+       /* Wrap this up as a Return Result component */
+       msgb_wrap_with_TL(msg, GSM0480_CTYPE_RETURN_RESULT);
+
+       /* 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 | req->transaction_id
+                                       | (1<<7);  /* TI direction = 1 */
+       gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
+
+       return gsm0808_submit_dtap(conn, msg, 0, 0);
+}
+
+int gsm0480_send_ss_reject(struct gsm_subscriber_connection *conn,
+                          const struct ss_request *req,
+                          uint8_t problem_category,
+                          uint8_t problem_code)
 {
        struct msgb *msg = gsm48_msgb_alloc();
        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, problem_category, problem_code);

        /* Before it insert the invoke ID */
        msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);
diff --git a/openbsc/src/libmsc/ss.c b/openbsc/src/libmsc/ss.c
new file mode 100644
index 0000000..44a01ec
--- /dev/null
+++ b/openbsc/src/libmsc/ss.c
@@ -0,0 +1,173 @@
+/* Network-specific handling of mobile-originated SSs. */
+
+/* (C) 2008-2009 by Harald Welte <[email protected]>
+ * (C) 2008, 2009 by Holger Hans Peter Freyther <[email protected]>
+ * (C) 2009 by Mike Haben <[email protected]>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* This module defines the network-specific handling of mobile-originated
+   SS messages. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <openbsc/db.h>
+#include <openbsc/gsm_04_80.h>
+#include <openbsc/gsm_subscriber.h>
+#include <openbsc/debug.h>
+#include <openbsc/osmo_msc.h>
+
+/* Declarations of USSD strings to be recognised */
+const char USSD_TEXT_OWN_NUMBER[] = "*#100#";
+
+/* Forward declarations of network-specific handler functions */
+static int send_own_number(struct gsm_subscriber_connection *conn, const 
struct msgb *msg, const struct ss_request *req);
+static int change_ss_activation(struct gsm_subscriber_connection *conn, 
uint8_t activate, const struct ss_request *req);
+static int interrogate_ss(struct gsm_subscriber_connection *conn, const struct 
ss_request *req);
+
+/* Entrypoint - handler function common to all mobile-originated SS */
+int handle_rcv_ss(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+       int rc;
+       struct ss_request req;
+       struct gsm48_hdr *gh;
+       uint8_t activate;
+
+       memset(&req, 0, sizeof(req));
+       gh = msgb_l3(msg);
+       rc = gsm0480_decode_ss_request(gh, msgb_l3len(msg), &req);
+
+       if (rc == 1) {
+
+               switch (req.opcode) {
+               case GSM0480_OP_CODE_PROCESS_USS_REQ:
+
+                       if (req.ussd_text[0] == 0xFF)  /* Release-Complete */
+                               return 0;
+
+                       if (!strcmp(USSD_TEXT_OWN_NUMBER,
+                                  (const char *)req.ussd_text)) {
+                               DEBUGP(DMM, "USSD: Own number requested\n");
+                               rc = send_own_number(conn, msg, &req);
+                       } else {
+                               DEBUGP(DMM, "Unhandled USSD %s\n", 
req.ussd_text);
+                               rc = gsm0480_send_ss_reject(conn, &req,
+                                                           
GSM_0480_PROBLEM_CODE_TAG_INVOKE,
+                                                           
GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION);
+                       }
+
+                       break;
+
+               case GSM0480_OP_CODE_ACTIVATE_SS:
+               case GSM0480_OP_CODE_DEACTIVATE_SS:
+                       activate = (req.opcode == GSM0480_OP_CODE_ACTIVATE_SS);
+                       rc = change_ss_activation(conn, activate, &req);
+                       break;
+               case GSM0480_OP_CODE_INTERROGATE_SS:
+                       rc = interrogate_ss(conn, &req);
+                       break;
+               default:
+                       DEBUGP(DMM, "Unhandled SS opcode %d\n", req.opcode);
+                       rc = gsm0480_send_ss_reject(conn, &req,
+                                                   
GSM_0480_PROBLEM_CODE_TAG_GENERAL,
+                                                   
GSM_0480_GEN_PROB_CODE_UNRECOGNISED);
+                       break;
+               }
+
+       } else {
+               rc = gsm0480_send_ss_reject(conn, &req,
+                                           GSM_0480_PROBLEM_CODE_TAG_GENERAL,
+                                           
GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE);
+       }
+
+       /* check if we can release it */
+       msc_release_connection(conn);
+       return rc;
+}
+
+/* A network-specific handler function */
+static int send_own_number(struct gsm_subscriber_connection *conn, const 
struct msgb *msg, const struct ss_request *req)
+{
+       char *own_number = conn->subscr->extension;
+       char response_string[GSM_EXTENSION_LENGTH + 20];
+
+       /* Need trailing CR as EOT character */
+       snprintf(response_string, sizeof(response_string), "Your extension is 
%s\r", own_number);
+       return gsm0480_send_ussd_response(conn, response_string, req);
+}
+
+static int change_ss_activation(struct gsm_subscriber_connection *conn, 
uint8_t activate, const struct ss_request *req)
+{
+       struct msgb *msg;
+       uint8_t ss_status;
+       int rc = db_ss_interrogate_status(conn->subscr,
+                                         req->ss_code,
+                                         GSM0902_TS_CODE_TELEPHONY,
+                                         &ss_status);
+
+       if(rc < 0 || !(ss_status & GSM0902_SS_STATUS_P_BIT)) {
+               DEBUGP(DMM, "SS 0x%02X not provisioned\n", req->ss_code);
+               return gsm0480_send_ss_reject(conn, req,
+                                             GSM_0480_PROBLEM_CODE_TAG_INVOKE,
+                                             
GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION);
+       }
+
+       ss_status &= ~GSM0902_SS_STATUS_A_BIT;
+       ss_status |= (activate ? GSM0902_SS_STATUS_A_BIT : 0);
+
+       rc = db_ss_set_status(conn->subscr, req->ss_code,
+                             GSM0902_TS_CODE_TELEPHONY, ss_status);
+       if(rc < 0)
+               return gsm0480_send_ss_reject(conn, req,
+                                             GSM_0480_PROBLEM_CODE_TAG_INVOKE,
+                                             
GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION);
+
+       msg = gsm48_msgb_alloc();
+       /* First put the payload into the message */
+       msgb_push_TLV1(msg, GSM0902_SS_DATA_SS_STATUS_TAG, ss_status);
+       /* Then wrap it as a Sequence of type SS-Data */
+       msgb_wrap_with_TL(msg, GSM0902_SS_INFO_SS_DATA_TAG);
+
+       return gsm0480_send_ss_return_result(conn, req, msg);
+}
+
+static int interrogate_ss(struct gsm_subscriber_connection *conn, const struct 
ss_request *req)
+{
+       struct msgb *msg;
+       uint8_t ss_status;
+       int rc = db_ss_interrogate_status(conn->subscr,
+                                         req->ss_code,
+                                         GSM0902_TS_CODE_TELEPHONY,
+                                         &ss_status);
+
+       if(rc < 0 || !(ss_status & GSM0902_SS_STATUS_P_BIT)) {
+               DEBUGP(DMM, "SS 0x%02X not provisioned\n", req->ss_code);
+               return gsm0480_send_ss_reject(conn, req,
+                                             GSM_0480_PROBLEM_CODE_TAG_INVOKE,
+                                             
GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION);
+       }
+
+       msg = gsm48_msgb_alloc();
+       /* Put the payload into the message */
+       msgb_push_TLV1(msg, GSM0902_SS_INTERR_SS_RES_SS_STATUS_TAG, ss_status);
+
+       return gsm0480_send_ss_return_result(conn, req, msg);
+}
diff --git a/openbsc/src/libmsc/ussd.c b/openbsc/src/libmsc/ussd.c
deleted file mode 100644
index 7f01eae..0000000
--- a/openbsc/src/libmsc/ussd.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Network-specific handling of mobile-originated USSDs. */
-
-/* (C) 2008-2009 by Harald Welte <[email protected]>
- * (C) 2008, 2009 by Holger Hans Peter Freyther <[email protected]>
- * (C) 2009 by Mike Haben <[email protected]>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* This module defines the network-specific handling of mobile-originated
-   USSD messages. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include <openbsc/gsm_04_80.h>
-#include <openbsc/gsm_subscriber.h>
-#include <openbsc/debug.h>
-#include <openbsc/osmo_msc.h>
-
-/* Declarations of USSD strings to be recognised */
-const char USSD_TEXT_OWN_NUMBER[] = "*#100#";
-
-/* Forward declarations of network-specific handler functions */
-static int send_own_number(struct gsm_subscriber_connection *conn, const 
struct msgb *msg, const struct ussd_request *req);
-
-
-/* Entrypoint - handler function common to all mobile-originated USSDs */
-int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
-{
-       int rc;
-       struct ussd_request req;
-       struct gsm48_hdr *gh;
-
-       memset(&req, 0, sizeof(req));
-       gh = msgb_l3(msg);
-       rc = gsm0480_decode_ussd_request(gh, msgb_l3len(msg), &req);
-       if (!rc) {
-               DEBUGP(DMM, "Unhandled SS\n");
-               rc = gsm0480_send_ussd_reject(conn, msg, &req);
-               msc_release_connection(conn);
-               return rc;
-       }
-
-       /* Release-Complete */
-       if (req.text[0] == '\0')
-               return 0;
-
-       if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.text)) {
-               DEBUGP(DMM, "USSD: Own number requested\n");
-               rc = send_own_number(conn, msg, &req);
-       } else {
-               DEBUGP(DMM, "Unhandled USSD %s\n", req.text);
-               rc = gsm0480_send_ussd_reject(conn, msg, &req);
-       }
-
-       /* check if we can release it */
-       msc_release_connection(conn);
-       return rc;
-}
-
-/* A network-specific handler function */
-static int send_own_number(struct gsm_subscriber_connection *conn, const 
struct msgb *msg, const struct ussd_request *req)
-{
-       char *own_number = conn->subscr->extension;
-       char response_string[GSM_EXTENSION_LENGTH + 20];
-
-       /* Need trailing CR as EOT character */
-       snprintf(response_string, sizeof(response_string), "Your extension is 
%s\r", own_number);
-       return gsm0480_send_ussd_response(conn, msg, response_string, req);
-}
-- 
2.1.4

Reply via email to