paging: Introduce a GSM_PAGING_BUSY event for a special timeout

Start counting the attempts of each paging request and call
the callback with the PAGING_BUSY type when the paging request
timed out but the subscriber was not paged at all. This can
only happen with a huge paging backlog.
In case the system has so many pending paging
This commit is contained in:
Holger Hans Peter Freyther 2010-12-23 18:19:17 +01:00
parent ee139e7253
commit d3baf415b1
8 changed files with 19 additions and 2 deletions

View File

@ -83,6 +83,7 @@ enum gsm_paging_event {
GSM_PAGING_SUCCEEDED, GSM_PAGING_SUCCEEDED,
GSM_PAGING_EXPIRED, GSM_PAGING_EXPIRED,
GSM_PAGING_OOM, GSM_PAGING_OOM,
GSM_PAGING_BUSY,
}; };
enum bts_gprs_mode { enum bts_gprs_mode {

View File

@ -46,6 +46,9 @@ struct gsm_paging_request {
/* Timer 3113: how long do we try to page? */ /* Timer 3113: how long do we try to page? */
struct timer_list T3113; struct timer_list T3113;
/* How often did we ask the BTS to page? */
int attempts;
/* callback to be called in case paging completes */ /* callback to be called in case paging completes */
gsm_cbfn *cbfn; gsm_cbfn *cbfn;
void *cbfn_param; void *cbfn_param;

View File

@ -140,6 +140,8 @@ struct paging_signal_data {
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
struct gsm_bts *bts; struct gsm_bts *bts;
int paging_result;
/* NULL in case the paging didn't work */ /* NULL in case the paging didn't work */
struct gsm_subscriber_connection *conn; struct gsm_subscriber_connection *conn;
}; };

View File

@ -1409,6 +1409,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
gsm48_cc_tx_setup(transt, &transt->cc.msg); gsm48_cc_tx_setup(transt, &transt->cc.msg);
break; break;
case GSM_PAGING_EXPIRED: case GSM_PAGING_EXPIRED:
case GSM_PAGING_BUSY:
DEBUGP(DCC, "Paging subscr %s expired!\n", DEBUGP(DCC, "Paging subscr %s expired!\n",
subscr->extension); subscr->extension);
/* Temporarily out of order */ /* Temporarily out of order */

View File

@ -1126,6 +1126,7 @@ static int paging_cb_send_sms(unsigned int hooknum, unsigned int event,
break; break;
case GSM_PAGING_EXPIRED: case GSM_PAGING_EXPIRED:
case GSM_PAGING_OOM: case GSM_PAGING_OOM:
case GSM_PAGING_BUSY:
sms_free(sms); sms_free(sms);
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
break; break;

View File

@ -84,6 +84,7 @@ static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
sig_data.subscr = subscr; sig_data.subscr = subscr;
sig_data.bts = conn ? conn->bts : NULL; sig_data.bts = conn ? conn->bts : NULL;
sig_data.conn = conn; sig_data.conn = conn;
sig_data.paging_result = event;
dispatch_signal( dispatch_signal(
SS_PAGING, SS_PAGING,
event == GSM_PAGING_SUCCEEDED ? event == GSM_PAGING_SUCCEEDED ?
@ -169,7 +170,7 @@ static void subscr_send_paging_request(struct gsm_subscriber *subscr)
/* paging failed, quit now */ /* paging failed, quit now */
if (rc <= 0) { if (rc <= 0) {
subscr_paging_cb(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, subscr_paging_cb(GSM_HOOK_RR_PAGING, GSM_PAGING_BUSY,
NULL, NULL, subscr); NULL, NULL, subscr);
} }
} }

View File

@ -209,6 +209,7 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
/* handle the paging request now */ /* handle the paging request now */
page_ms(request); page_ms(request);
paging_bts->available_slots--; paging_bts->available_slots--;
request->attempts++;
/* take the current and add it to the back */ /* take the current and add it to the back */
llist_del(&request->entry); llist_del(&request->entry);
@ -253,6 +254,7 @@ static void paging_T3113_expired(void *data)
struct gsm_paging_request *req = (struct gsm_paging_request *)data; struct gsm_paging_request *req = (struct gsm_paging_request *)data;
void *cbfn_param; void *cbfn_param;
gsm_cbfn *cbfn; gsm_cbfn *cbfn;
int msg;
LOGP(DPAG, LOGL_INFO, "T3113 expired for request %p (%s)\n", LOGP(DPAG, LOGL_INFO, "T3113 expired for request %p (%s)\n",
req, req->subscr->imsi); req, req->subscr->imsi);
@ -261,10 +263,15 @@ static void paging_T3113_expired(void *data)
counter_inc(req->bts->network->stats.paging.expired); counter_inc(req->bts->network->stats.paging.expired);
cbfn_param = req->cbfn_param; cbfn_param = req->cbfn_param;
cbfn = req->cbfn; cbfn = req->cbfn;
/* did we ever manage to page the subscriber */
msg = req->attempts > 0 ? GSM_PAGING_EXPIRED : GSM_PAGING_BUSY;
/* destroy it now. Do not access req afterwards */
paging_remove_request(&req->bts->paging, req); paging_remove_request(&req->bts->paging, req);
if (cbfn) if (cbfn)
cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL, cbfn(GSM_HOOK_RR_PAGING, msg, NULL, NULL,
cbfn_param); cbfn_param);
} }

View File

@ -60,6 +60,7 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event,
dispatch_signal(SS_SCALL, S_SCALL_SUCCESS, &sigdata); dispatch_signal(SS_SCALL, S_SCALL_SUCCESS, &sigdata);
break; break;
case GSM_PAGING_EXPIRED: case GSM_PAGING_EXPIRED:
case GSM_PAGING_BUSY:
DEBUGP(DSMS, "expired\n"); DEBUGP(DSMS, "expired\n");
dispatch_signal(SS_SCALL, S_SCALL_EXPIRED, &sigdata); dispatch_signal(SS_SCALL, S_SCALL_EXPIRED, &sigdata);
break; break;