aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-08-28 10:16:54 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-08-28 11:10:44 +0200
commit1b894022fd168d7b9a3e8cafaef1622c3a24885b (patch)
tree9fdaa9f2a1b853c265a0a4bed85d9838e11d3b11
parent0c0e1c308f0d13cf366315bd9f35df6e8bb9038c (diff)
bsc/ussd: Optionally send USSD message on MSC disconnection
Send an USSD message on each MS connection if the connection to the MSC has been lost. Add a vty config command 'bsc-msc-loss-txt' in 'config-msc' to set the notification string and to enable the feature. Ticket: OW#957
-rw-r--r--openbsc/include/openbsc/osmo_msc_data.h3
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sccp.c30
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_vty.c35
-rw-r--r--openbsc/tests/vty_test_runner.py41
4 files changed, 105 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h
index ba93a089d..86b4a8455 100644
--- a/openbsc/include/openbsc/osmo_msc_data.h
+++ b/openbsc/include/openbsc/osmo_msc_data.h
@@ -83,6 +83,9 @@ struct osmo_msc_data {
struct osmo_wqueue mgcp_agent;
int nr;
+
+ /* ussd msc connection lost text */
+ char *ussd_msc_lost_txt;
};
/*
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
index 3533d6df0..ad554e82a 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
@@ -262,13 +262,35 @@ int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp)
return 0;
}
-static void bsc_close_connections(struct bsc_msc_connection *msc_con)
+static void bsc_notify_msc_lost(struct osmo_bsc_sccp_con *con)
+{
+ struct gsm_subscriber_connection *conn = con->conn;
+
+ /* send USSD notification if string configured and con->data is set */
+ if (!conn)
+ return;
+
+ /* check for config string */
+ if (!con->msc->ussd_msc_lost_txt)
+ return;
+ if (con->msc->ussd_msc_lost_txt[0] == '\0')
+ return;
+
+ /* send USSD notification */
+ gsm0480_send_ussdNotify(conn, 1, conn->sccp_con->msc->ussd_welcome_txt);
+ gsm0480_send_releaseComplete(conn);
+}
+
+static void bsc_notify_and_close_conns(struct bsc_msc_connection *msc_con)
{
struct osmo_bsc_sccp_con *con, *tmp;
llist_for_each_entry_safe(con, tmp, &active_connections, entry) {
- if (con->msc->msc_con == msc_con)
- bsc_sccp_force_free(con);
+ if (con->msc->msc_con != msc_con)
+ continue;
+
+ bsc_notify_msc_lost(con);
+ bsc_sccp_force_free(con);
}
}
@@ -282,7 +304,7 @@ static int handle_msc_signal(unsigned int subsys, unsigned int signal,
msc = signal_data;
if (signal == S_MSC_LOST)
- bsc_close_connections(msc->data->msc_con);
+ bsc_notify_and_close_conns(msc->data->msc_con);
return 0;
}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_vty.c b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
index 49ae665a6..501d9f51b 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_vty.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_vty.c
@@ -114,6 +114,11 @@ static void write_msc(struct vty *vty, struct osmo_msc_data *msc)
if (msc->ussd_welcome_txt)
vty_out(vty, " bsc-welcome-text %s%s", msc->ussd_welcome_txt, VTY_NEWLINE);
+ if (msc->ussd_msc_lost_txt && msc->ussd_msc_lost_txt[0])
+ vty_out(vty, " bsc-msc-lost-text %s%s", msc->ussd_msc_lost_txt, VTY_NEWLINE);
+ else
+ vty_out(vty, " no bsc-msc-lost-text%s", VTY_NEWLINE);
+
if (msc->audio_length != 0) {
int i;
@@ -368,6 +373,34 @@ DEFUN(cfg_net_msc_welcome_ussd,
return CMD_SUCCESS;
}
+DEFUN(cfg_net_msc_lost_ussd,
+ cfg_net_msc_lost_ussd_cmd,
+ "bsc-msc-lost-text .TEXT",
+ "Set the USSD notification to be sent on MSC connection loss\n" "Text to be sent\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+ char *str = argv_concat(argv, argc, 0);
+ if (!str)
+ return CMD_WARNING;
+
+ bsc_replace_string(osmo_bsc_data(vty), &data->ussd_msc_lost_txt, str);
+ talloc_free(str);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_msc_no_lost_ussd,
+ cfg_net_msc_no_lost_ussd_cmd,
+ "no bsc-msc-lost-text",
+ NO_STR "Clear the USSD notification to be sent on MSC connection loss\n")
+{
+ struct osmo_msc_data *data = osmo_msc_data(vty);
+
+ talloc_free(data->ussd_msc_lost_txt);
+ data->ussd_msc_lost_txt = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_net_msc_type,
cfg_net_msc_type_cmd,
"type (normal|local)",
@@ -579,6 +612,8 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_msc_ping_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_pong_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_lost_ussd_cmd);
+ install_element(MSC_NODE, &cfg_net_msc_no_lost_ussd_cmd);
install_element(MSC_NODE, &cfg_net_msc_type_cmd);
install_element(MSC_NODE, &cfg_net_msc_emerg_cmd);
install_element(MSC_NODE, &cfg_net_msc_local_prefix_cmd);
diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py
index a7a7b3fb8..fd200c850 100644
--- a/openbsc/tests/vty_test_runner.py
+++ b/openbsc/tests/vty_test_runner.py
@@ -88,6 +88,39 @@ class TestVTYNITB(TestVTYBase):
self.assertEquals(res.find('periodic location update 60'), -1)
self.assert_(res.find('no periodic location update') > 0)
+class TestVTYBSC(TestVTYBase):
+
+ def vty_command(self):
+ return ["./src/osmo-bsc/osmo-bsc", "-c",
+ "doc/examples/osmo-bsc/osmo-bsc.cfg"]
+
+ def vty_app(self):
+ return (4242, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")
+
+ def testUssdNotifications(self):
+ self.vty.enable()
+ self.vty.command("configure terminal")
+ self.vty.command("msc")
+
+ # Test invalid input
+ self.vty.verify("bsc-msc-lost-text", ['% Command incomplete.'])
+
+ # Enable USSD notifications
+ self.vty.verify("bsc-msc-lost-text MSC disconnected", [''])
+
+ # Verify settings
+ res = self.vty.command("write terminal")
+ self.assert_(res.find('bsc-msc-lost-text MSC disconnected') > 0)
+ self.assertEquals(res.find('no bsc-msc-lost-text'), -1)
+
+ # Now disable it..
+ self.vty.verify("no bsc-msc-lost-text", [''])
+
+ # Verify settings
+ res = self.vty.command("write terminal")
+ self.assertEquals(res.find('bsc-msc-lost-text MSC disconnected'), -1)
+ self.assert_(res.find('no bsc-msc-lost-text') > 0)
+
class TestVTYNAT(TestVTYBase):
def vty_command(self):
@@ -189,6 +222,13 @@ def add_nat_test(suite, workdir):
test = unittest.TestLoader().loadTestsFromTestCase(TestVTYNAT)
suite.addTest(test)
+def add_bsc_test(suite, workdir):
+ if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
+ print("Skipping the BSC test")
+ return
+ test = unittest.TestLoader().loadTestsFromTestCase(TestVTYBSC)
+ suite.addTest(test)
+
if __name__ == '__main__':
import argparse
import sys
@@ -219,6 +259,7 @@ if __name__ == '__main__':
print "Running tests for specific VTY commands"
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYNITB))
+ add_bsc_test(suite, workdir)
add_nat_test(suite, workdir)
res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
sys.exit(len(res.errors) + len(res.failures))