aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/paging.h2
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c61
-rw-r--r--src/osmo-bsc/osmo_bsc_grace.c47
-rw-r--r--tests/bssap/bssap_test.c13
-rw-r--r--tests/bssap/bssap_test.err6
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