diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/osmo_bsc_bssap.c | 61 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_grace.c | 47 |
2 files changed, 40 insertions, 68 deletions
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) |