diff options
-rw-r--r-- | include/osmocom/bsc/paging.h | 2 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_bssap.c | 61 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_grace.c | 47 | ||||
-rw-r--r-- | tests/bssap/bssap_test.c | 13 | ||||
-rw-r--r-- | tests/bssap/bssap_test.err | 6 |
5 files changed, 54 insertions, 75 deletions
diff --git a/include/osmocom/bsc/paging.h b/include/osmocom/bsc/paging.h index 2b1bc506c..2be71c39f 100644 --- a/include/osmocom/bsc/paging.h +++ b/include/osmocom/bsc/paging.h @@ -56,8 +56,6 @@ struct gsm_paging_request { }; /* schedule paging request */ -int paging_request(struct gsm_network *network, struct bsc_subscr *bsub, int type, - struct bsc_msc_data *msc); int paging_request_bts(struct gsm_bts *bts, struct bsc_subscr *bsub, int type, struct bsc_msc_data *msc); diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index a02ea9e81..e3a30f595 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -228,14 +228,16 @@ static int bssmap_handle_reset(struct bsc_msc_data *msc, return 0; } -/* Page a subscriber based on TMSI and LAC in the specified MSC. - * If BTS is not NULL, page the subscriber via this particular BTS. - * A non-zero return value indicates a fatal out of memory condition. */ +/* Page a subscriber based on TMSI and LAC via the specified BTS. + * The msc parameter is the MSC which issued the corresponding paging request. + * Returns 1 if the paging request could be issued, 0 if not. + * A negative return value indicates an error. */ static int page_subscriber(struct bsc_msc_data *msc, struct gsm_bts *bts, uint32_t tmsi, uint32_t lac, const char *mi_string, uint8_t chan_needed) { struct bsc_subscr *subscr; + int ret; subscr = bsc_subscr_find_or_create_by_imsi(msc->network->bsc_subscribers, mi_string); @@ -247,19 +249,15 @@ page_subscriber(struct bsc_msc_data *msc, struct gsm_bts *bts, subscr->lac = lac; subscr->tmsi = tmsi; - if (bts) - LOGP(DMSC, LOGL_INFO, "Paging request from MSC BTS: %d IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", - bts->nr, mi_string, tmsi, tmsi, lac); - else - LOGP(DMSC, LOGL_INFO, "Paging request from MSC IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", mi_string, tmsi, tmsi, lac); + LOGP(DMSC, LOGL_INFO, "Paging request from MSC BTS: %d IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", + bts->nr, mi_string, tmsi, tmsi, lac); - bsc_grace_paging_request(msc->network->bsc_data->rf_ctrl->policy, - subscr, chan_needed, msc, bts); + ret = bsc_grace_paging_request(msc->network->bsc_data->rf_ctrl->policy, subscr, chan_needed, msc, bts); /* the paging code has grabbed its own references */ bsc_subscr_put(subscr); - return 0; + return ret; } /* GSM 08.08 ยง 3.2.1.19 */ @@ -277,6 +275,7 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, const uint8_t *data; uint8_t chan_needed = RSL_CHANNEED_ANY; uint8_t cell_ident; + struct gsm_bts *bts; tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 0, 0); remain = payload_length - 1; @@ -353,7 +352,6 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, uint16_t *ci_be = (uint16_t *)(&data[1]); while (remain >= sizeof(*ci_be)) { uint16_t ci = osmo_load16be(ci_be); - struct gsm_bts *bts; llist_for_each_entry(bts, &msc->network->bts_list, list) { if (bts->cell_identity == ci) @@ -361,11 +359,12 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, } if (bts) { - if (page_subscriber(msc, bts, tmsi, lac, mi_string, chan_needed) != 0) - break; - } else + /* ignore errors from page_subscriber(); keep trying other BTS */ + page_subscriber(msc, bts, tmsi, lac, mi_string, chan_needed); + } else { LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: BTS with cell identifier %d not found\n", mi_string, ci); + } remain -= sizeof(*ci_be); ci_be++; } @@ -387,13 +386,17 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, break; } if (mcc == msc->network->country_code && mnc == msc->network->network_code) { - if (page_subscriber(msc, NULL, tmsi, lac, mi_string, chan_needed) != 0) - break; - } else + llist_for_each_entry(bts, &msc->network->bts_list, list) { + if (bts->location_area_code != lac) + continue; + /* ignore errors from page_subscriber(); keep trying other BTS */ + page_subscriber(msc, bts, tmsi, lac, mi_string, chan_needed); + } + } else { LOGP(DMSC, LOGL_DEBUG, "Not paging IMSI %s: MCC/MNC in Cell Identifier List " "(%d/%d) do not match our network (%d/%d)\n", mi_string, mcc, mnc, msc->network->country_code, msc->network->network_code); - + } remain -= sizeof(lai); i++; } @@ -404,8 +407,12 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, lacp_be = (uint16_t *)(&data[1]); while (remain >= sizeof(*lacp_be)) { lac = osmo_load16be(lacp_be); - if (page_subscriber(msc, NULL, tmsi, lac, mi_string, chan_needed) != 0) - break; + llist_for_each_entry(bts, &msc->network->bts_list, list) { + if (bts->location_area_code != lac) + continue; + /* ignore errors from page_subscriber(); keep trying other BTS */ + page_subscriber(msc, bts, tmsi, lac, mi_string, chan_needed); + } remain -= sizeof(*lacp_be); lacp_be++; } @@ -417,16 +424,20 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, " has invalid length: %u, paging entire BSS anyway (%s)\n", mi_string, CELL_IDENT_BSS, data_length, osmo_hexdump(data, data_length)); } - if (page_subscriber(msc, NULL, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed) != 0) - break; + llist_for_each_entry(bts, &msc->network->bts_list, list) { + /* ignore errors from page_subscriber(); try all BTS */ + page_subscriber(msc, bts, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed); + } break; default: LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: unimplemented Cell Identifier List (0x%x)," " paging entire BSS instead (%s)\n", mi_string, cell_ident, osmo_hexdump(data, data_length)); - if (page_subscriber(msc, NULL, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed) != 0) - break; + llist_for_each_entry(bts, &msc->network->bts_list, list) { + /* ignore errors from page_subscriber(); try all BTS */ + page_subscriber(msc, bts, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed); + } break; } diff --git a/src/osmo-bsc/osmo_bsc_grace.c b/src/osmo-bsc/osmo_bsc_grace.c index 93ca9b93e..705933cb4 100644 --- a/src/osmo-bsc/osmo_bsc_grace.c +++ b/src/osmo-bsc/osmo_bsc_grace.c @@ -34,22 +34,6 @@ int bsc_grace_allow_new_connection(struct gsm_network *network, struct gsm_bts * } -static int normal_paging(struct bsc_subscr *subscr, int chan_needed, - struct bsc_msc_data *msc) -{ - /* we can't page by lac.. we need to page everything */ - if (msc->core_lac != -1) { - struct gsm_bts *bts; - - llist_for_each_entry(bts, &msc->network->bts_list, list) - paging_request_bts(bts, subscr, chan_needed, msc); - - return 0; - } - - return paging_request(msc->network, subscr, chan_needed, msc); -} - /* Return value is like paging_request_bts(): * returns 1 on success (one BTS was paged); 0 in case of error (e.g. TRX down) */ static int locked_paging_bts(struct gsm_bts *bts, @@ -68,31 +52,14 @@ static int locked_paging_bts(struct gsm_bts *bts, return paging_request_bts(bts, subscr, chan_needed, msc); } -static int locked_paging(struct bsc_subscr *subscr, int chan_needed, - struct bsc_msc_data *msc) -{ - struct gsm_bts *bts = NULL; - int num_pages = 0; - - /* - * Check if there is any BTS that is on for the given lac. Start - * with NULL and iterate through all bts. - * All other bts are either off or in the grace period. - */ - llist_for_each_entry(bts, &msc->network->bts_list, list) - num_pages += locked_paging_bts(bts, subscr, chan_needed, msc); - - return num_pages; -} - /** * Page a subscriber in an MSC. * \param[in] rf_policy if not S_RF_ON, page only BTSs which are not excluded from the RF lock * \param[in] subscr subscriber we want to page * \param[in] chan_needed value of the GSM0808_IE_CHANNEL_NEEDED IE * \param[in] msc MSC which has issued this paging - * \param[in] bts if not NULL, page via this particular BTS - * \returns number of BTS on which we issued the paging + * \param[in] bts The BTS to issue the paging on + * \returns 1 if paging was issued to the BTS, 0 if not */ int bsc_grace_paging_request(enum signal_rf rf_policy, struct bsc_subscr *subscr, @@ -100,15 +67,9 @@ int bsc_grace_paging_request(enum signal_rf rf_policy, struct bsc_msc_data *msc, struct gsm_bts *bts) { - if (bts) { - if (rf_policy == S_RF_ON) - return paging_request_bts(bts, subscr, chan_needed, msc); - return locked_paging_bts(bts, subscr, chan_needed, msc); - } - if (rf_policy == S_RF_ON) - return normal_paging(subscr, chan_needed, msc); - return locked_paging(subscr, chan_needed, msc); + return paging_request_bts(bts, subscr, chan_needed, msc); + return locked_paging_bts(bts, subscr, chan_needed, msc); } static int handle_sub(struct gsm_lchan *lchan, const char *text) diff --git a/tests/bssap/bssap_test.c b/tests/bssap/bssap_test.c index c97393d5e..1d8fe7720 100644 --- a/tests/bssap/bssap_test.c +++ b/tests/bssap/bssap_test.c @@ -24,6 +24,7 @@ #include <osmocom/bsc/signal.h> #include <osmocom/bsc/bsc_subscriber.h> #include <osmocom/bsc/bsc_msc_data.h> +#include <osmocom/bsc/gsm_data_shared.h> #include <osmocom/bsc/common_bsc.h> #include <osmocom/bsc/osmo_bsc_rf.h> @@ -41,9 +42,9 @@ uint16_t gl_expect_lac = 0; /* override, requires '-Wl,--wrap=bsc_grace_paging_request' */ int __real_bsc_grace_paging_request(enum signal_rf rf_policy, struct bsc_subscr *subscr, int chan_needed, - struct bsc_msc_data *msc); + struct bsc_msc_data *msc, struct gsm_bts *bts); int __wrap_bsc_grace_paging_request(enum signal_rf rf_policy, struct bsc_subscr *subscr, int chan_needed, - struct bsc_msc_data *msc) + struct bsc_msc_data *msc, struct gsm_bts *bts) { if (subscr->lac == GSM_LAC_RESERVED_ALL_BTS) fprintf(stderr, "BSC paging started on entire BSS (%u)\n", subscr->lac); @@ -86,6 +87,7 @@ void test_cell_identifier() int rc; struct gsm_network *net; struct bsc_msc_data *msc; + struct gsm_bts *bts; net = bsc_network_init(NULL, 1, 1); net->bsc_data->rf_ctrl = talloc_zero(NULL, struct osmo_bsc_rf); @@ -94,6 +96,12 @@ void test_cell_identifier() msc = talloc_zero(net, struct bsc_msc_data); msc->network = net; + bts = gsm_bts_alloc_register(net, GSM_BTS_TYPE_UNKNOWN, 0); + if (bts == NULL) { + fprintf(stderr, "gsm_bts_alloc_register() returned NULL\n"); + return; + } + log_set_log_level(osmo_stderr_target, LOGL_DEBUG); for (i = 0; i < ARRAY_SIZE(cell_identifier_tests); i++) { @@ -102,6 +110,7 @@ void test_cell_identifier() msg = msgb_from_hex("test_cell_identifier", 1024, cell_identifier_tests[i].msg); gl_expect_lac = cell_identifier_tests[i].expect_lac; + bts->location_area_code = (gl_expect_lac == GSM_LAC_RESERVED_ALL_BTS ? 0 : gl_expect_lac); rc = bsc_handle_udt(msc, msg, msgb_l2len(msg)); fprintf(stderr, "bsc_handle_udt() returned %d\n", rc); diff --git a/tests/bssap/bssap_test.err b/tests/bssap/bssap_test.err index f24ff7c8c..abe1defc3 100644 --- a/tests/bssap/bssap_test.err +++ b/tests/bssap/bssap_test.err @@ -2,14 +2,14 @@ 0: DMSC Rx MSC UDT: 00 16 52 08 08 59 51 20 69 00 07 43 94 09 04 01 08 44 60 1a 03 05 00 65 DMSC Rx MSC UDT BSSMAP PAGING -DMSC Paging request from MSC IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0x65 +DMSC Paging request from MSC BTS: 0 IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0x65 BSC paging started with LAC 101 bsc_handle_udt() returned 0 1: DMSC Rx MSC UDT: 00 14 52 08 08 59 51 20 69 00 07 43 94 09 04 01 08 44 60 1a 01 06 DMSC Rx MSC UDT BSSMAP PAGING -DMSC Paging request from MSC IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0xfffe +DMSC Paging request from MSC BTS: 0 IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0xfffe BSC paging started on entire BSS (65534) bsc_handle_udt() returned 0 @@ -22,6 +22,6 @@ bsc_handle_udt() returned 0 3: DMSC Rx MSC UDT: 00 19 52 08 08 59 51 20 69 00 07 43 94 09 04 01 08 44 60 1a 06 04 00 f1 10 00 65 DMSC Rx MSC UDT BSSMAP PAGING -DMSC Paging request from MSC IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0x65 +DMSC Paging request from MSC BTS: 0 IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0x65 BSC paging started with LAC 101 bsc_handle_udt() returned 0 |