diff options
Diffstat (limited to 'openbsc/src/gprs/gprs_subscriber.c')
-rw-r--r-- | openbsc/src/gprs/gprs_subscriber.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 8399ea137..88e037e9d 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -76,6 +76,23 @@ static int gsup_read_cb(struct gprs_gsup_client *gsupc, struct msgb *msg) return rc; } +static int check_blocking( + struct gsm_subscriber *subscr, + enum sgsn_subscriber_proc what) +{ + if (subscr->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_NONE || + subscr->sgsn_data->blocked_by == what) + return 1; + + return 0; +} + +static void abort_blocking_procedure(struct gsm_subscriber *subscr) +{ + /* Best effort, stop retries at least */ + subscr->sgsn_data->retries = SGSN_SUBSCR_MAX_RETRIES; +} + static void sgsn_subscriber_timeout_cb(void *subscr_); int gprs_subscr_purge(struct gsm_subscriber *subscr); @@ -132,6 +149,10 @@ static void sgsn_subscriber_timeout_cb(void *subscr_) return; force_cleanup: + /* Make sure to clear blocking */ + if (check_blocking(subscr, SGSN_SUBSCR_PROC_PURGE)) + subscr->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE; + /* Make sure, the timer is cleaned up */ subscr->keep_in_ram = 0; gprs_subscr_stop_timer(subscr); @@ -544,17 +565,42 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg) int gprs_subscr_purge(struct gsm_subscriber *subscr) { struct gprs_gsup_message gsup_msg = {0}; + int rc; + + if (!check_blocking(subscr, SGSN_SUBSCR_PROC_PURGE)) { + LOGGSUBSCRP( + LOGL_NOTICE, subscr, + "Cannot purge MS subscriber, blocked\n"); + return -EAGAIN; + } + + /* GSM 09.02, 19.4.1.4 requires other MAP requests to be blocked until + * this procedure is completed + */ + subscr->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_PURGE; LOGGSUBSCRP(LOGL_INFO, subscr, "purging MS subscriber\n"); gsup_msg.message_type = GPRS_GSUP_MSGT_PURGE_MS_REQUEST; - return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); + rc = gprs_subscr_tx_gsup_message(subscr, &gsup_msg); + if (rc < 0) + subscr->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE; + + return rc; } int gprs_subscr_query_auth_info(struct gsm_subscriber *subscr) { struct gprs_gsup_message gsup_msg = {0}; + if (!check_blocking(subscr, SGSN_SUBSCR_PROC_UPD_AUTH)) { + LOGGSUBSCRP( + LOGL_NOTICE, subscr, + "Cannot start update auth info request procedure, blocked\n"); + abort_blocking_procedure(subscr); + return -EAGAIN; + } + LOGGSUBSCRP(LOGL_INFO, subscr, "subscriber auth info is not available\n"); @@ -566,6 +612,14 @@ int gprs_subscr_location_update(struct gsm_subscriber *subscr) { struct gprs_gsup_message gsup_msg = {0}; + if (!check_blocking(subscr, SGSN_SUBSCR_PROC_UPD_LOC)) { + LOGGSUBSCRP( + LOGL_NOTICE, subscr, + "Cannot start update location procedure, blocked\n"); + abort_blocking_procedure(subscr); + return -EAGAIN; + } + LOGGSUBSCRP(LOGL_INFO, subscr, "subscriber data is not available\n"); |