aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmsc/gsm_subscriber.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-12-15 03:02:27 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2017-12-20 23:07:10 +0100
commit2ff5bcdc387a7eb5135e5a54d55027502952c86b (patch)
tree602296791799e12d7f1aab0f635694d211c69ac8 /src/libmsc/gsm_subscriber.c
parentc1d69256f61e6bc7bdcbbd1b4df6a779c7883891 (diff)
fix paging: add timeout to discard unsuccessful paging
Currently, if there is no reply from the BSS / RNC, a subscriber will remain as "already paged" forever, and is never going to be paged again. Even on IMSI Detach, the pending request will keep a ref count on the vlr_subscr. Add a paging timeout, as gsm_network->paging_timeout and in the VTY on the 'msc' node as 'paging timeout (default|<1-65535>'. (There is a 'network' / 'T3113' in OsmoBSC, but to not confuse the two, give this a different name.) Add test_ms_timeout_paging() test to verify the timeout works. I hit this while testing Paging across multiple hNodeB, when a UE lost connection to the hNodeB. I noticed that no matter how long I wait, no Paging is sent out anymore, and found this embarrassing issue. Good grief... The choice of 10 seconds is taken from https://osmocom.org/issues/2756 Change-Id: I2db6f1e2ad341cf9c2cc7a21ec2fca0bae5b2db5
Diffstat (limited to 'src/libmsc/gsm_subscriber.c')
-rw-r--r--src/libmsc/gsm_subscriber.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/libmsc/gsm_subscriber.c b/src/libmsc/gsm_subscriber.c
index a013e0eb6..b3d38d1e8 100644
--- a/src/libmsc/gsm_subscriber.c
+++ b/src/libmsc/gsm_subscriber.c
@@ -76,7 +76,10 @@ int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
return -EINVAL;
}
- if (event == GSM_PAGING_SUCCEEDED)
+ osmo_timer_del(&vsub->cs.paging_response_timer);
+
+ if (event == GSM_PAGING_SUCCEEDED
+ || event == GSM_PAGING_EXPIRED)
msc_stop_paging(vsub);
/* Inform parts of the system we don't know */
@@ -126,6 +129,12 @@ int msc_paging_request(struct vlr_subscr *vsub)
return -EINVAL;
}
+static void paging_response_timer_cb(void *data)
+{
+ struct vlr_subscr *vsub = data;
+ subscr_paging_dispatch(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL, vsub);
+}
+
/*! \brief Start a paging request for vsub, call cbfn(param) when done.
* \param vsub subscriber to page.
* \param cbfn function to call when the conn is established.
@@ -138,6 +147,7 @@ struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
{
int rc;
struct subscr_request *request;
+ struct gsm_network *net = vsub->vlr->user_ctx;
/* Start paging.. we know it is async so we can do it before */
if (!vsub->cs.is_paging) {
@@ -152,6 +162,8 @@ struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
/* reduced on the first paging callback */
vlr_subscr_get(vsub);
vsub->cs.is_paging = true;
+ osmo_timer_setup(&vsub->cs.paging_response_timer, paging_response_timer_cb, vsub);
+ osmo_timer_schedule(&vsub->cs.paging_response_timer, net->paging_response_timer, 0);
} else {
LOGP(DMM, LOGL_DEBUG, "Subscriber %s already paged.\n",
vlr_subscr_name(vsub));