aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc')
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c61
-rw-r--r--src/osmo-bsc/osmo_bsc_grace.c47
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)