aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc
diff options
context:
space:
mode:
authorStefan Sperling <ssperling@sysmocom.de>2018-01-11 14:53:18 +0100
committerStefan Sperling <ssperling@sysmocom.de>2018-01-16 14:14:01 +0100
commit714c2f9552c5ce54d4a29e72b4bd1d830524a992 (patch)
treeb989f3c2524b381d93d9eea522412282a1b83466 /src/osmo-bsc
parent74b8cdb8e9d7112026ec3c6e346e5c667d261db3 (diff)
Move BTS selection for paging from osmo_bsc_grace.c into osmo_bsc_bssap.c.
We can now either page an invidual BTS directly or page several BTS in a given location area. This decision is taken based on the contents of the cell identifier list in the paging request. Select a set of BTS for paging while processing the cell identifier list, rather than requiring the paging layer to loop over all BTS in the MSC. This change requires some adjustment in bssap_test. In particular, this test must now add a BTS to its network in order to pass. The purpose of this change is to make the layering a bit cleaner. There is one functional change: We no longer abort paging if paging fails for a particular BTS. Instead, we keep trying to page on other BTS. Change-Id: Ic1c72c7f83e53988eb9fedf314b1dc459836833d Suggested-by: Harald Welte Depends: Ic7772e75c3d7fb0df6e17e118bb33b3248352d4d Related: OS#2753
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)