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
This commit is contained in:
Jacob Erlbeck 2015-01-27 14:56:40 +01:00 committed by Holger Hans Peter Freyther
parent 929acdf6bf
commit 8000e0ea50
3 changed files with 25 additions and 5 deletions

View File

@ -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;

View File

@ -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",

View File

@ -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', ['']))