[PATCH] osmo-msc[master]: VTY: add USSD processing back-end configuration

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Mon Apr 9 16:53:24 UTC 2018


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/7677

to look at the new patch set (#2).

VTY: add USSD processing back-end configuration

This change is a preparation for the upcoming remote USSD
processing back-end support. It extends the VTY in order
to allow one to choose preferred USSD handler.

At the moment, the following handlers are available:

OsmoMSC# configure terminal
OsmoMSC(config)# ussd
OsmoMSC(config-ussd)# handler <TAB>
  none      Do not handle USSD requests
  internal  Built-in USSD handlers (e.g. *#100#)

Please note that the internal back-end (good old *#100#)
is still used by default due to the compatibility reasons.

Change-Id: I0b3c5ccea4054113e8e23109b1ab68d9f0e18497
---
M doc/examples/osmo-msc/osmo-msc.cfg
M doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
M doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
M include/osmocom/msc/gsm_data.h
M include/osmocom/msc/ussd.h
M include/osmocom/msc/vty.h
M src/libmsc/msc_vty.c
M src/libmsc/ussd.c
M src/osmo-msc/msc_main.c
M tests/msc_vlr/msc_vlr_tests.c
10 files changed, 176 insertions(+), 19 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/77/7677/2

diff --git a/doc/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg
index 91c9eee..9fa2977 100644
--- a/doc/examples/osmo-msc/osmo-msc.cfg
+++ b/doc/examples/osmo-msc/osmo-msc.cfg
@@ -17,3 +17,5 @@
  assign-tmsi
  auth-tuple-max-reuse-count 3
  auth-tuple-reuse-on-error 1
+ussd
+ handler internal
diff --git a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
index 0b9fd2a..d012f16 100644
--- a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
+++ b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
@@ -23,3 +23,5 @@
  cs7-instance-iu 0
  mgw remote-ip 10.23.24.1
  assign-tmsi
+ussd
+ handler internal
diff --git a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
index 44ac3f8..b2c0c1d 100644
--- a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
+++ b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
@@ -25,3 +25,5 @@
  cs7-instance-iu 1
  mgw remote-ip 10.23.24.1
  assign-tmsi
+ussd
+ handler internal
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index f3e1b94..1ba03e3 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -14,6 +14,7 @@
 #include <osmocom/crypt/auth.h>
 #include <osmocom/sigtran/sccp_sap.h>
 
+#include <osmocom/msc/ussd.h>
 #include <osmocom/msc/common.h>
 #include <osmocom/msc/common_cs.h>
 #include <osmocom/mgcp_client/mgcp_client.h>
@@ -321,6 +322,11 @@
 		/* MSISDN to which to route MO emergency calls */
 		char *route_to_msisdn;
 	} emergency;
+
+	struct {
+		/* USSD handler, e.g. internal */
+		enum ussd_handler_type handler;
+	} ussd;
 };
 
 struct osmo_esme;
diff --git a/include/osmocom/msc/ussd.h b/include/osmocom/msc/ussd.h
index bc4227b..6c821b1 100644
--- a/include/osmocom/msc/ussd.h
+++ b/include/osmocom/msc/ussd.h
@@ -2,4 +2,18 @@
 
 #include <osmocom/core/msgb.h>
 
+enum ussd_handler_type {
+	/* Do not handle USSD requests */
+	USSD_HANDLER_NONE = 0,
+	/* Built-in USSD handlers (e.g. *#100#) */
+	USSD_HANDLER_INTERNAL,
+};
+
+/* Forward declarations to avoid mutual include */
+struct gsm_subscriber_connection;
+struct gsm_network;
+
+int ussd_init(struct gsm_network *net);
+void ussd_shutdown(struct gsm_network *net);
+
 int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg);
diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h
index 6a55df7..068683f 100644
--- a/include/osmocom/msc/vty.h
+++ b/include/osmocom/msc/vty.h
@@ -23,6 +23,7 @@
 	SMPP_NODE,
 	SMPP_ESME_NODE,
 	HLR_NODE,
+	USSD_NODE,
 };
 
 int bsc_vty_init_extra(void);
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 33613e9..e5887fe 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -47,6 +47,7 @@
 #include <osmocom/msc/vlr.h>
 #include <osmocom/msc/transaction.h>
 #include <osmocom/msc/db.h>
+#include <osmocom/msc/ussd.h>
 #include <osmocom/msc/sms_queue.h>
 #include <osmocom/msc/silent_call.h>
 #include <osmocom/msc/gsm_04_80.h>
@@ -1380,6 +1381,61 @@
 	return CMD_SUCCESS;
 }
 
+static struct cmd_node ussd_node = {
+	USSD_NODE,
+	"%s(config-ussd)# ",
+	1,
+};
+
+DEFUN(cfg_ussd, cfg_ussd_cmd,
+      "ussd", "Configure USSD handling")
+{
+	vty->node = USSD_NODE;
+	return CMD_SUCCESS;
+}
+
+#define USSD_HANDLERS "(none|internal)"
+#define USSD_HANDLERS_HELP \
+	"Do not handle USSD requests\n" \
+	"Built-in USSD handlers (e.g. *#100#)\n"
+
+DEFUN(cfg_ussd_handler, cfg_ussd_handler_cmd,
+      "handler " USSD_HANDLERS,
+      "USSD processing back-end\n"
+      USSD_HANDLERS_HELP)
+{
+	const char *handler_str = argv[0];
+
+	/* Parse handler type */
+	if (!strcasecmp(handler_str, "none"))
+		gsmnet->ussd.handler = USSD_HANDLER_NONE;
+	else if (!strcasecmp(handler_str, "internal"))
+		gsmnet->ussd.handler = USSD_HANDLER_INTERNAL;
+	else {
+		vty_out(vty, "Incorrect USSD handler%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	return CMD_SUCCESS;
+}
+
+static int config_write_ussd(struct vty *vty)
+{
+	vty_out(vty, "ussd%s", VTY_NEWLINE);
+
+	vty_out(vty, " handler ");
+	switch (gsmnet->ussd.handler) {
+	case USSD_HANDLER_NONE:
+		vty_out(vty, "none%s", VTY_NEWLINE);
+		break;
+	case USSD_HANDLER_INTERNAL:
+		vty_out(vty, "internal%s", VTY_NEWLINE);
+		break;
+	}
+
+	return CMD_SUCCESS;
+}
+
 void msc_vty_init(struct gsm_network *msc_network)
 {
 	OSMO_ASSERT(gsmnet == NULL);
@@ -1461,4 +1517,8 @@
 	install_node(&hlr_node, config_write_hlr);
 	install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
 	install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
+
+	install_element(CONFIG_NODE, &cfg_ussd_cmd);
+	install_node(&ussd_node, config_write_ussd);
+	install_element(USSD_NODE, &cfg_ussd_handler_cmd);
 }
diff --git a/src/libmsc/ussd.c b/src/libmsc/ussd.c
index e7f7e5d..9b929d0 100644
--- a/src/libmsc/ussd.c
+++ b/src/libmsc/ussd.c
@@ -34,7 +34,11 @@
 #include <osmocom/msc/debug.h>
 #include <osmocom/msc/osmo_msc.h>
 #include <osmocom/msc/vlr.h>
+#include <osmocom/msc/ussd.h>
 #include <osmocom/msc/gsm_04_08.h>
+
+static int (*ussd_handler)(struct gsm_subscriber_connection *conn,
+	const struct ss_request *req) = NULL;
 
 /* Declarations of USSD strings to be recognised */
 const char USSD_TEXT_OWN_NUMBER[] = "*#100#";
@@ -52,6 +56,43 @@
 	/* 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 ussd_handler_internal(struct gsm_subscriber_connection *conn,
+	const struct ss_request *req)
+{
+	int rc;
+
+	/* Interrogation or releaseComplete? */
+	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;
+		}
+		/* Still assuming a Release-Complete and returning */
+		return 0;
+	}
+
+	msc_subscr_conn_communicating(conn);
+	if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req->ussd_text)) {
+		DEBUGP(DMM, "USSD: Own number requested\n");
+		rc = send_own_number(conn, req);
+	} else {
+		DEBUGP(DMM, "Unhandled USSD %s\n", req->ussd_text);
+		rc = gsm0480_send_ussd_reject(conn, req);
+	}
+
+	return rc;
+}
+
+static int ussd_handler_dummy(struct gsm_subscriber_connection *conn,
+	const struct ss_request *req)
+{
+	DEBUGP(DMM, "USSD support disabled, rejecting request\n");
+
+	/* FIXME: use a proper problem code */
+	return gsm0480_send_ussd_reject(conn, req);
 }
 
 /* Entrypoint - handler function common to all mobile-originated USSDs */
@@ -77,25 +118,31 @@
 		return rc;
 	}
 
-	/* Interrogation or releaseComplete? */
-	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;
-		}
-		/* Still assuming a Release-Complete and returning */
-		return 0;
+	OSMO_ASSERT(ussd_handler);
+	return ussd_handler(conn, &req);
+}
+
+int ussd_init(struct gsm_network *net)
+{
+	/* Choose USSD connection handler */
+	switch (net->ussd.handler) {
+	case USSD_HANDLER_INTERNAL:
+		ussd_handler = ussd_handler_internal;
+		break;
+	case USSD_HANDLER_NONE:
+	default:
+		ussd_handler = ussd_handler_dummy;
+		break;
 	}
 
-	msc_subscr_conn_communicating(conn);
-	if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.ussd_text)) {
-		DEBUGP(DMM, "USSD: Own number requested\n");
-		rc = send_own_number(conn, &req);
-	} else {
-		DEBUGP(DMM, "Unhandled USSD %s\n", req.ussd_text);
-		rc = gsm0480_send_ussd_reject(conn, &req);
-	}
+	return 0;
+}
 
-	return rc;
+void ussd_shutdown(struct gsm_network *net)
+{
+	/**
+	 * Do nothing for now
+	 * TODO: close connection with external USSD gateway
+	 * TODO: close all active USSD connections
+	 */
 }
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index 85a8fe1..4e8e275 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -55,6 +55,7 @@
 #include <osmocom/msc/vty.h>
 #include <osmocom/msc/mncc.h>
 #include <osmocom/msc/rrlp.h>
+#include <osmocom/msc/ussd.h>
 #include <osmocom/ctrl/control_if.h>
 #include <osmocom/ctrl/control_vty.h>
 #include <osmocom/ctrl/ports.h>
@@ -215,12 +216,22 @@
 
 	mgcp_client_conf_init(&net->mgw.conf);
 
+	/* USSD: let's keep *#100# available by default */
+	net->ussd.handler = USSD_HANDLER_INTERNAL;
+
 	return net;
 }
 
 void msc_network_shutdown(struct gsm_network *net)
 {
-	/* nothing here yet */
+	/**
+	 * Prevent NULL pointer dereference,
+	 * e.g. when called before initialization...
+	 */
+	OSMO_ASSERT(net);
+
+	/* Shutdown USSD */
+	ussd_shutdown(net);
 }
 
 static struct gsm_network *msc_network = NULL;
@@ -620,6 +631,13 @@
 		return -1;
 	}
 
+	/* Initialize USSD */
+	rc = ussd_init(msc_network);
+	if (rc) {
+		printf("Failed to initialize USSD.\n");
+		return -1;
+	}
+
 	/* seed the PRNG */
 	srand(time(NULL));
 	/* TODO: is this used for crypto?? Improve randomness, at least we
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index 7c54057..a19ab3b 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -926,6 +926,9 @@
 	net->vlr->ops.tx_auth_rej = fake_vlr_tx_auth_rej;
 	net->vlr->ops.set_ciph_mode = fake_vlr_tx_ciph_mode_cmd;
 
+	/* USSD: let's keep *#100# available by default */
+	net->ussd.handler = USSD_HANDLER_INTERNAL;
+
 	return net;
 }
 
@@ -954,6 +957,8 @@
 
 	msc_subscr_conn_init();
 
+	ussd_init(net);
+
 	clear_vlr();
 
 	if (optind >= argc)

-- 
To view, visit https://gerrit.osmocom.org/7677
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I0b3c5ccea4054113e8e23109b1ab68d9f0e18497
Gerrit-PatchSet: 2
Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list