diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2017-12-15 03:02:27 +0100 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2017-12-20 23:07:10 +0100 |
commit | 2ff5bcdc387a7eb5135e5a54d55027502952c86b (patch) | |
tree | 602296791799e12d7f1aab0f635694d211c69ac8 /src/libmsc/gsm_subscriber.c | |
parent | c1d69256f61e6bc7bdcbbd1b4df6a779c7883891 (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.c | 14 |
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)); |