From e903edf5801eb63f65138408c7b5d7c2fa22a231 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 15 Aug 2009 03:16:17 +0200 Subject: [PATCH] provide return code from paging_request() function this enables the caller to detect if the paging request was rejected by the paging layer, especially in case it is already paging this very subscriber. In the case of SMS / 04.11, we used to have a memory leak of struct gsm_sms's, since we would only free them from the paging succeeded/expired callbacks. --- openbsc/include/openbsc/paging.h | 4 ++-- openbsc/src/gsm_04_11.c | 7 +++++-- openbsc/src/paging.c | 19 +++++++++++++------ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/openbsc/include/openbsc/paging.h b/openbsc/include/openbsc/paging.h index 2f17e243e..ab6a27494 100644 --- a/openbsc/include/openbsc/paging.h +++ b/openbsc/include/openbsc/paging.h @@ -33,8 +33,8 @@ void paging_init(struct gsm_bts *bts); /* schedule paging request */ -void paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, - int type, gsm_cbfn *cbfn, void *data); +int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, + int type, gsm_cbfn *cbfn, void *data); /* stop paging requests */ void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr, diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c index 2994d7207..8ac596d7e 100644 --- a/openbsc/src/gsm_04_11.c +++ b/openbsc/src/gsm_04_11.c @@ -1025,6 +1025,7 @@ int gsm411_send_sms_subscr(struct gsm_subscriber *subscr, struct gsm_sms *sms) { struct gsm_lchan *lchan; + int rc; /* check if we already have an open lchan to the subscriber. * if yes, send the SMS this way */ @@ -1034,8 +1035,10 @@ int gsm411_send_sms_subscr(struct gsm_subscriber *subscr, rll_ind_cb, sms); /* if not, we have to start paging */ - paging_request(subscr->net, subscr, RSL_CHANNEED_SDCCH, - paging_cb_send_sms, sms); + rc = paging_request(subscr->net, subscr, RSL_CHANNEED_SDCCH, + paging_cb_send_sms, sms); + if (rc < 0) + sms_free(sms); return 0; } diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index dd2215005..062eca80c 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -213,7 +213,7 @@ static void paging_T3113_expired(void *data) paging_remove_request(&req->bts->paging, req); } -static void _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, +static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, int type, gsm_cbfn *cbfn, void *data) { struct gsm_bts_paging_state *bts_entry = &bts->paging; @@ -221,7 +221,7 @@ static void _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, if (paging_pending_request(bts_entry, subscr)) { DEBUGP(DPAG, "Paging request already pending\n"); - return; + return -EEXIST; } DEBUGP(DPAG, "Start paging of subscriber %llu on bts %d.\n", @@ -239,12 +239,15 @@ static void _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, if (!bsc_timer_pending(&bts_entry->work_timer)) bsc_schedule_timer(&bts_entry->work_timer, 1, 0); + + return 0; } -void paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, - int type, gsm_cbfn *cbfn, void *data) +int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, + int type, gsm_cbfn *cbfn, void *data) { struct gsm_bts *bts = NULL; + int rc; /* start paging subscriber on all BTS within Location Area */ do { @@ -252,9 +255,13 @@ void paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, if (!bts) break; - /* Trigger paging */ - _paging_request(bts, subscr, type, cbfn, data); + /* Trigger paging, pass any error to caller */ + rc = _paging_request(bts, subscr, type, cbfn, data); + if (rc < 0) + return rc; } while (1); + + return 0; }