Hello Jenkins Builder, I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/5705 to look at the new patch set (#5). Implement support for paging based on CI (cell identifier). This builds upon https://gerrit.osmocom.org/#/c/5698/ which implements support for paging by LAI. The ttcn3 test TC_paging_imsi_nochan_ci passes with this code when run in isolation. It does not pass if another paging test (such as TC_paging_imsi_nochan_lai) is executed beforehand. This problem looks similar to the scenario tested in TC_paging_imsi_a_reset. Change-Id: Ic7772e75c3d7fb0df6e17e118bb33b3248352d4d Depends: Ic3c62ff0fccea586794ea4b3c275a0685cc9326e Related: OS#2753 --- M include/osmocom/bsc/osmo_bsc_grace.h M src/osmo-bsc/osmo_bsc_bssap.c M src/osmo-bsc/osmo_bsc_grace.c 3 files changed, 91 insertions(+), 44 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/05/5705/5 diff --git a/include/osmocom/bsc/osmo_bsc_grace.h b/include/osmocom/bsc/osmo_bsc_grace.h index b7950ce..d78e41c 100644 --- a/include/osmocom/bsc/osmo_bsc_grace.h +++ b/include/osmocom/bsc/osmo_bsc_grace.h @@ -30,6 +30,7 @@ int 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); #endif diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 54e0205..0dd4ee5 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -228,11 +228,12 @@ return 0; } -/* Page a subscriber based on TMSI and LAC. +/* 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. */ static int -page_subscriber(struct bsc_msc_data *msc, uint32_t tmsi, uint32_t lac, - const char *mi_string, uint8_t chan_needed) +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; @@ -246,9 +247,14 @@ subscr->lac = lac; subscr->tmsi = tmsi; - LOGP(DMSC, LOGL_INFO, "Paging request from MSC IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", mi_string, tmsi, tmsi, lac); + 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); + bsc_grace_paging_request(msc->network->bsc_data->rf_ctrl->policy, - subscr, chan_needed, msc); + subscr, chan_needed, msc, bts); /* the paging code has grabbed its own references */ bsc_subscr_put(subscr); @@ -339,6 +345,28 @@ lac = GSM_LAC_RESERVED_ALL_BTS; switch (cell_ident) { + case CELL_IDENT_CI: { + 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) + break; + } + + if (bts) { + if (page_subscriber(msc, bts, tmsi, lac, mi_string, chan_needed) != 0) + break; + } 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++; + } + break; + } case CELL_IDENT_LAI_AND_LAC: { struct gsm48_loc_area_id lai; int i = 0; @@ -354,7 +382,7 @@ break; } if (mcc == msc->network->country_code && mnc == msc->network->network_code) { - if (page_subscriber(msc, tmsi, lac, mi_string, chan_needed) != 0) + if (page_subscriber(msc, NULL, tmsi, lac, mi_string, chan_needed) != 0) break; } else LOGP(DMSC, LOGL_DEBUG, "Not paging IMSI %s: MCC/MNC in Cell Identifier List " @@ -371,7 +399,7 @@ lacp_be = (uint16_t *)(&data[1]); while (remain >= sizeof(*lacp_be)) { lac = osmo_load16be(lacp_be); - if (page_subscriber(msc, tmsi, lac, mi_string, chan_needed) != 0) + if (page_subscriber(msc, NULL, tmsi, lac, mi_string, chan_needed) != 0) break; remain -= sizeof(*lacp_be); lacp_be++; @@ -384,7 +412,7 @@ " 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, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed) != 0) + if (page_subscriber(msc, NULL, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed) != 0) break; break; @@ -392,7 +420,7 @@ 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, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed) != 0) + if (page_subscriber(msc, NULL, tmsi, GSM_LAC_RESERVED_ALL_BTS, mi_string, chan_needed) != 0) break; break; } diff --git a/src/osmo-bsc/osmo_bsc_grace.c b/src/osmo-bsc/osmo_bsc_grace.c index f16a19a..93ca9b9 100644 --- a/src/osmo-bsc/osmo_bsc_grace.c +++ b/src/osmo-bsc/osmo_bsc_grace.c @@ -50,44 +50,62 @@ return paging_request(msc->network, 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; - - /* - * Check if there is any BTS that is on for the given lac. Start - * with NULL and iterate through all bts. - */ - llist_for_each_entry(bts, &msc->network->bts_list, list) { - /* - * continue if the BTS is not excluded from the lock - */ - if (!bts->excl_from_rf_lock) - continue; - - /* in case of no lac patching is in place, check the BTS */ - if (msc->core_lac == -1 && subscr->lac != bts->location_area_code) - continue; - - /* - * now page on this bts - */ - paging_request_bts(bts, subscr, chan_needed, msc); - }; - - /* All bts are either off or in the grace period */ - return 0; -} - -/** - * Try to not page if everything the cell is not on. - */ -int bsc_grace_paging_request(enum signal_rf rf_policy, +/* 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, struct bsc_subscr *subscr, int chan_needed, struct bsc_msc_data *msc) { + /* Return error if the BTS is not excluded from the lock. */ + if (!bts->excl_from_rf_lock) + return 0; + + /* in case of no lac patching is in place, check the BTS */ + if (msc->core_lac == -1 && subscr->lac != bts->location_area_code) + return 0; + + 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 + */ +int bsc_grace_paging_request(enum signal_rf rf_policy, + struct bsc_subscr *subscr, + int chan_needed, + 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); -- To view, visit https://gerrit.osmocom.org/5705 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic7772e75c3d7fb0df6e17e118bb33b3248352d4d Gerrit-PatchSet: 5 Gerrit-Project: osmo-bsc Gerrit-Branch: master Gerrit-Owner: Stefan Sperling <ssperl...@sysmocom.de> Gerrit-Reviewer: Jenkins Builder