summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-01-27 14:56:40 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-01-30 21:27:07 +0100
commit8000e0ea509c5a4488a5d1878f465418d32b7fdb (patch)
treebd7bd991708784412b11f11774ae094ee8c2eece
parent929acdf6bf4ef25c8cc587a6aa48651696348881 (diff)
gprs: Support cancellation type
The cancellation type that is part of the UpdateCancellation message is currently ignored. This patch adds the missing glue between the existing GSUP and GMM support. If the type is not present or has the value updateProcedure the subcriber and MM context are siliently removed. Otherwise, a message with cause 'implicitly detached' is sent to the MS. Since the real cause is not known (the specification neither added a cause IE nor defined a static cause value), the MS may get the real cause in the following AttachRej. Added VTY commands: - update-subscriber imsi IMSI cancel update-procedure - update-subscriber imsi IMSI cancel subscription-withdraw the old form without the cause is no longer supported. Sponsored-by: On-Waves ehf
-rw-r--r--openbsc/src/gprs/gprs_subscriber.c15
-rw-r--r--openbsc/src/gprs/sgsn_vty.c13
-rw-r--r--openbsc/tests/vty_test_runner.py2
3 files changed, 25 insertions, 5 deletions
diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c
index 54a61611e..e4dda9c46 100644
--- a/openbsc/src/gprs/gprs_subscriber.c
+++ b/openbsc/src/gprs/gprs_subscriber.c
@@ -439,13 +439,24 @@ static int gprs_subscr_handle_loc_cancel_req(struct gsm_subscriber *subscr,
struct gprs_gsup_message *gsup_msg)
{
struct gprs_gsup_message gsup_reply = {0};
+ int is_update_procedure = !gsup_msg->cancel_type || gsup_msg->cancel_type;
- LOGGSUBSCRP(LOGL_INFO, subscr, "purging MS subscriber\n");
+ LOGGSUBSCRP(LOGL_INFO, subscr, "Cancelling MS subscriber (%s)\n",
+ is_update_procedure ?
+ "update procedure" : "subscription withdraw");
gsup_reply.message_type = GPRS_GSUP_MSGT_LOCATION_CANCEL_RESULT;
gprs_subscr_tx_gsup_message(subscr, &gsup_reply);
- subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE;
+ if (is_update_procedure)
+ subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE;
+ else
+ /* Since a withdraw cause is not specified, just abort the
+ * current attachment. The following re-attachment should then
+ * be rejected with a proper cause value.
+ */
+ subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED;
+
gprs_subscr_cancel(subscr);
return 0;
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
index 1ecb2eae3..ba71555ec 100644
--- a/openbsc/src/gprs/sgsn_vty.c
+++ b/openbsc/src/gprs/sgsn_vty.c
@@ -545,11 +545,14 @@ failed:
}
DEFUN(update_subscr_cancel, update_subscr_cancel_cmd,
- UPDATE_SUBSCR_STR "cancel",
+ UPDATE_SUBSCR_STR "cancel (update-procedure|subscription-withdraw)",
UPDATE_SUBSCR_HELP
- "Cancel (remove) subscriber record\n")
+ "Cancel (remove) subscriber record\n"
+ "The MS moved to another SGSN\n"
+ "The subscription is no longer valid\n")
{
const char *imsi = argv[0];
+ const char *cancel_type = argv[1];
struct gsm_subscriber *subscr;
@@ -560,6 +563,11 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd,
return CMD_WARNING;
}
+ if (strcmp(cancel_type, "update-procedure") == 0)
+ subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE;
+ else
+ subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED;
+
gprs_subscr_cancel(subscr);
subscr_put(subscr);
@@ -606,6 +614,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd,
}
subscr->keep_in_ram = 0;
+ subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE;
gprs_subscr_cancel(subscr);
if (subscr->use_count > 1)
vty_out(vty, "%% subscriber is still in use%s",
diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py
index de6a708c3..4adc8e8e2 100644
--- a/openbsc/tests/vty_test_runner.py
+++ b/openbsc/tests/vty_test_runner.py
@@ -768,7 +768,7 @@ class TestVTYSGSN(TestVTYGenericBSC):
res = self.vty.command('show subscriber cache')
self.assert_(res.find('1234567890') >= 0)
self.assert_(res.find('Authorized: 1') >= 0)
- self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 cancel', ['']))
+ self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 cancel update-procedure', ['']))
res = self.vty.command('show subscriber cache')
self.assert_(res.find('1234567890') >= 0)
self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 destroy', ['']))