From 6d804b1a7e375213cb4b3e437c2b9b8c68872164 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sat, 18 Feb 2017 22:20:46 +0100 Subject: add struct bsc_subscr, separating libbsc from gsm_subscriber In a future commit, gsm_subscriber will be replaced by vlr_subscr, and it will not make sense to use vlr_subscr in libbsc. Thus we need a dedicated BSC subscriber: struct bsc_subscr. Add rf_policy arg to bsc_grace_paging_request() because the bsc_subscr will no longer have a backpointer to gsm_network (used to be via subscr->group). Create a separate logging filter for the new BSC subscriber. The implementation of adjusting the filter context is added in libbsc to not introduce bsc_subscr_get/_put() dependencies to libcommon. During Paging Response, fetch a bsc_subscr from the mobile identity, like we do for the gsm_subscriber. It looks like a duplication now, but will make sense for the VLR as well as for future MSC split patches. Naming: it was requested to not name the new struct bsc_sub, because 'sub' is too ambiguous. At the same time it would be fine to have 'bsc_sub_' as function prefix. Instead of struct bsc_subscriber and bsc_sub_ prefix, I decided to match both up as struct bsc_subscr and bsc_subscr_ function prefix. It's fast to type, relatively short, unambiguous, and the naming is consistent. Add bsc_subscr unit test. Related: OS#1592, OS#1594 Change-Id: Ia61cc00e8bb186b976939a4fc8f7cf9ce6aa3d8e --- openbsc/src/libbsc/paging.c | 88 +++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 42 deletions(-) (limited to 'openbsc/src/libbsc/paging.c') diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c index eb37a33d7..bd23d89de 100644 --- a/openbsc/src/libbsc/paging.c +++ b/openbsc/src/libbsc/paging.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -58,11 +59,11 @@ void *tall_paging_ctx; * Kill one paging request update the internal list... */ static void paging_remove_request(struct gsm_bts_paging_state *paging_bts, - struct gsm_paging_request *to_be_deleted) + struct gsm_paging_request *to_be_deleted) { osmo_timer_del(&to_be_deleted->T3113); llist_del(&to_be_deleted->entry); - subscr_put(to_be_deleted->subscr); + bsc_subscr_put(to_be_deleted->bsub); talloc_free(to_be_deleted); } @@ -77,21 +78,21 @@ static void page_ms(struct gsm_paging_request *request) if (!bts->oml_link) return; - log_set_context(LOG_CTX_VLR_SUBSCR, request->subscr); + log_set_context(LOG_CTX_BSC_SUBSCR, request->bsub); LOGP(DPAG, LOGL_INFO, "Going to send paging commands: imsi: %s tmsi: " - "0x%x for ch. type %d (attempt %d)\n", request->subscr->imsi, - request->subscr->tmsi, request->chan_type, request->attempts); + "0x%08x for ch. type %d (attempt %d)\n", request->bsub->imsi, + request->bsub->tmsi, request->chan_type, request->attempts); - if (request->subscr->tmsi == GSM_RESERVED_TMSI) - mi_len = gsm48_generate_mid_from_imsi(mi, request->subscr->imsi); + if (request->bsub->tmsi == GSM_RESERVED_TMSI) + mi_len = gsm48_generate_mid_from_imsi(mi, request->bsub->imsi); else - mi_len = gsm48_generate_mid_from_tmsi(mi, request->subscr->tmsi); + mi_len = gsm48_generate_mid_from_tmsi(mi, request->bsub->tmsi); page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc, - str_to_imsi(request->subscr->imsi)); + str_to_imsi(request->bsub->imsi)); gsm0808_page(bts, page_group, mi_len, mi, request->chan_type); - log_set_context(LOG_CTX_VLR_SUBSCR, NULL); + log_set_context(LOG_CTX_BSC_SUBSCR, NULL); } static void paging_schedule_if_needed(struct gsm_bts_paging_state *paging_bts) @@ -237,11 +238,12 @@ static void paging_init_if_needed(struct gsm_bts *bts) } static int paging_pending_request(struct gsm_bts_paging_state *bts, - struct gsm_subscriber *subscr) { + struct bsc_subscr *bsub) +{ struct gsm_paging_request *req; llist_for_each_entry(req, &bts->pending_requests, entry) { - if (subscr == req->subscr) + if (bsub == req->bsub) return 1; } @@ -255,10 +257,10 @@ static void paging_T3113_expired(void *data) gsm_cbfn *cbfn; int msg; - log_set_context(LOG_CTX_VLR_SUBSCR, req->subscr); + log_set_context(LOG_CTX_BSC_SUBSCR, req->bsub); LOGP(DPAG, LOGL_INFO, "T3113 expired for request %p (%s)\n", - req, req->subscr->imsi); + req, bsc_subscr_name(req->bsub)); /* must be destroyed before calling cbfn, to prevent double free */ rate_ctr_inc(&req->bts->network->bsc_ctrs->ctr[BSC_CTR_PAGING_EXPIRED]); @@ -277,21 +279,22 @@ static void paging_T3113_expired(void *data) } -static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, - int type, gsm_cbfn *cbfn, void *data) +static int _paging_request(struct gsm_bts *bts, struct bsc_subscr *bsub, + int type, gsm_cbfn *cbfn, void *data) { struct gsm_bts_paging_state *bts_entry = &bts->paging; struct gsm_paging_request *req; - if (paging_pending_request(bts_entry, subscr)) { - LOGP(DPAG, LOGL_INFO, "Paging request already pending for %s\n", subscr->imsi); + if (paging_pending_request(bts_entry, bsub)) { + LOGP(DPAG, LOGL_INFO, "Paging request already pending for %s\n", + bsc_subscr_name(bsub)); return -EEXIST; } - LOGP(DPAG, LOGL_DEBUG, "Start paging of subscriber %llu on bts %d.\n", - subscr->id, bts->nr); + LOGP(DPAG, LOGL_DEBUG, "Start paging of subscriber %s on bts %d.\n", + bsc_subscr_name(bsub), bts->nr); req = talloc_zero(tall_paging_ctx, struct gsm_paging_request); - req->subscr = subscr_get(subscr); + req->bsub = bsc_subscr_get(bsub); req->bts = bts; req->chan_type = type; req->cbfn = cbfn; @@ -305,8 +308,8 @@ static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, return 0; } -int paging_request_bts(struct gsm_bts *bts, struct gsm_subscriber *subscr, - int type, gsm_cbfn *cbfn, void *data) +int paging_request_bts(struct gsm_bts *bts, struct bsc_subscr *bsub, + int type, gsm_cbfn *cbfn, void *data) { int rc; @@ -317,15 +320,14 @@ int paging_request_bts(struct gsm_bts *bts, struct gsm_subscriber *subscr, /* maybe it is the first time we use it */ paging_init_if_needed(bts); - /* Trigger paging, pass any error to the caller */ - rc = _paging_request(bts, subscr, type, cbfn, data); + rc = _paging_request(bts, bsub, type, cbfn, data); if (rc < 0) return rc; return 1; } -int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, +int paging_request(struct gsm_network *network, struct bsc_subscr *bsub, int type, gsm_cbfn *cbfn, void *data) { struct gsm_bts *bts = NULL; @@ -337,13 +339,14 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, do { int rc; - bts = gsm_bts_by_lac(network, subscr->lac, bts); + bts = gsm_bts_by_lac(network, bsub->lac, bts); if (!bts) break; - rc = paging_request_bts(bts, subscr, type, cbfn, data); + rc = paging_request_bts(bts, bsub, type, cbfn, data); if (rc < 0) { - paging_request_stop(NULL, subscr, NULL, NULL); + paging_request_stop(&network->bts_list, NULL, bsub, + NULL, NULL); return rc; } num_pages += rc; @@ -357,7 +360,7 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr, /* we consciously ignore the type of the request here */ -static void _paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr, +static void _paging_request_stop(struct gsm_bts *bts, struct bsc_subscr *bsub, struct gsm_subscriber_connection *conn, struct msgb *msg) { @@ -367,8 +370,8 @@ static void _paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *sub paging_init_if_needed(bts); llist_for_each_entry_safe(req, req2, &bts_entry->pending_requests, - entry) { - if (req->subscr == subscr) { + entry) { + if (req->bsub == bsub) { gsm_cbfn *cbfn = req->cbfn; void *param = req->cbfn_param; @@ -377,35 +380,36 @@ static void _paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *sub req = NULL; if (conn && cbfn) { - LOGP(DPAG, LOGL_DEBUG, "Stop paging %s on bts %d, calling cbfn.\n", subscr->imsi, bts->nr); + LOGP(DPAG, LOGL_DEBUG, "Stop paging %s on bts %d, calling cbfn.\n", bsub->imsi, bts->nr); cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED, - msg, conn, param); + msg, conn, param); } else - LOGP(DPAG, LOGL_DEBUG, "Stop paging %s on bts %d silently.\n", subscr->imsi, bts->nr); + LOGP(DPAG, LOGL_DEBUG, "Stop paging %s on bts %d silently.\n", bsub->imsi, bts->nr); break; } } } /* Stop paging on all other bts' */ -void paging_request_stop(struct gsm_bts *_bts, struct gsm_subscriber *subscr, +void paging_request_stop(struct llist_head *bts_list, + struct gsm_bts *_bts, struct bsc_subscr *bsub, struct gsm_subscriber_connection *conn, struct msgb *msg) { struct gsm_bts *bts; - log_set_context(LOG_CTX_VLR_SUBSCR, subscr); + log_set_context(LOG_CTX_BSC_SUBSCR, bsub); /* Stop this first and dispatch the request */ if (_bts) - _paging_request_stop(_bts, subscr, conn, msg); + _paging_request_stop(_bts, bsub, conn, msg); /* Make sure to cancel this everywhere else */ - llist_for_each_entry(bts, &subscr->group->net->bts_list, list) { + llist_for_each_entry(bts, bts_list, list) { /* Sort of an optimization. */ if (bts == _bts) continue; - _paging_request_stop(bts, subscr, NULL, NULL); + _paging_request_stop(bts, bsub, NULL, NULL); } } @@ -434,12 +438,12 @@ unsigned int paging_pending_requests_nr(struct gsm_bts *bts) /** * Find any paging data for the given subscriber at the given BTS. */ -void *paging_get_data(struct gsm_bts *bts, struct gsm_subscriber *subscr) +void *paging_get_data(struct gsm_bts *bts, struct bsc_subscr *bsub) { struct gsm_paging_request *req; llist_for_each_entry(req, &bts->paging.pending_requests, entry) - if (req->subscr == subscr) + if (req->bsub == bsub) return req->cbfn_param; return NULL; -- cgit v1.2.3