diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_bssap.c | 48 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/bssap/Makefile.am | 50 | ||||
-rw-r--r-- | tests/bssap/bssap_test.c | 120 | ||||
-rw-r--r-- | tests/bssap/bssap_test.err | 22 | ||||
-rw-r--r-- | tests/bssap/bssap_test.ok | 0 | ||||
-rw-r--r-- | tests/testsuite.at | 7 |
8 files changed, 240 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac index 79523d141..02a81c691 100644 --- a/configure.ac +++ b/configure.ac @@ -149,6 +149,7 @@ AC_OUTPUT( tests/trau/Makefile tests/subscr/Makefile tests/nanobts_omlattr/Makefile + tests/bssap/Makefile doc/Makefile doc/examples/Makefile contrib/Makefile diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 431125024..93e9274a0 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -233,10 +233,11 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, struct tlv_parsed tp; char mi_string[GSM48_MI_SIZE]; uint32_t tmsi = GSM_RESERVED_TMSI; - unsigned int lac = GSM_LAC_RESERVED_ALL_BTS; + unsigned int lac; uint8_t data_length; const uint8_t *data; uint8_t chan_needed = RSL_CHANNEED_ANY; + uint8_t cell_ident; tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 0, 0); @@ -265,21 +266,50 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc, TLVP_VAL(&tp, GSM0808_IE_IMSI), TLVP_LEN(&tp, GSM0808_IE_IMSI)); /* - * parse the cell identifier list + * There are various cell identifier list types defined at 3GPP TS ยง 08.08, we don't support all + * of them yet. To not disrupt paging operation just because we're lacking some implementation, + * interpret any unknown cell identifier type as "page the entire BSS". */ data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST); data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST); - /* - * Support paging to all network or one BTS at one LAC - */ - if (data_length == 3 && data[0] == CELL_IDENT_LAC) { - lac = osmo_load16be(&data[1]); - } else if (data_length > 1 || (data[0] & 0x0f) != CELL_IDENT_BSS) { - LOGP(DMSC, LOGL_ERROR, "Unsupported Cell Identifier List: %s\n", osmo_hexdump(data, data_length)); + if (data_length < 1) { + LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Zero length Cell Identifier List\n", + mi_string); return -1; } + cell_ident = data[0] & 0xf; + + /* Default fallback: page entire BSS */ + lac = GSM_LAC_RESERVED_ALL_BTS; + + switch (cell_ident) { + case CELL_IDENT_LAC: + if (data_length != 3) { + LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Cell Identifier List for LAC (0x%x)" + " has invalid length: %u, paging entire BSS instead (%s)\n", + mi_string, CELL_IDENT_LAC, data_length, osmo_hexdump(data, data_length)); + break; + } + lac = osmo_load16be(&data[1]); + break; + + case CELL_IDENT_BSS: + if (data_length != 1) { + LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Cell Identifier List for BSS (0x%x)" + " has invalid length: %u, paging entire BSS anyway (%s)\n", + mi_string, CELL_IDENT_BSS, data_length, osmo_hexdump(data, data_length)); + } + 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)); + break; + } + if (TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_NEEDED) && TLVP_LEN(&tp, GSM0808_IE_CHANNEL_NEEDED) == 1) chan_needed = TLVP_VAL(&tp, GSM0808_IE_CHANNEL_NEEDED)[0] & 0x03; diff --git a/tests/Makefile.am b/tests/Makefile.am index aff05bb44..474f82167 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,6 +8,7 @@ SUBDIRS = \ nanobts_omlattr \ bsc-nat \ bsc-nat-trie \ + bssap \ $(NULL) # The `:;' works around a Bash 3.2 bug when the output is not writeable. diff --git a/tests/bssap/Makefile.am b/tests/bssap/Makefile.am new file mode 100644 index 000000000..80d655fe7 --- /dev/null +++ b/tests/bssap/Makefile.am @@ -0,0 +1,50 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +EXTRA_DIST = \ + bssap_test.ok \ + bssap_test.err \ + $(NULL) + +noinst_PROGRAMS = \ + bssap_test \ + $(NULL) + +bssap_test_SOURCES = \ + bssap_test.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_bssap.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_sigtran.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c \ + $(top_srcdir)/src/osmo-bsc/osmo_bsc_grace.c \ + $(NULL) + +bssap_test_LDADD = \ + $(top_builddir)/src/libbsc/libbsc.a \ + $(top_builddir)/src/libcommon/libcommon.a \ + $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ + $(top_builddir)/src/libtrau/libtrau.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(NULL) + +bssap_test_LDFLAGS = \ + -Wl,--wrap=bsc_grace_paging_request \ + $(NULL) + +.PHONY: update_exp +update_exp: + $(builddir)/bssap_test >$(srcdir)/bssap_test.ok 2>$(srcdir)/bssap_test.err diff --git a/tests/bssap/bssap_test.c b/tests/bssap/bssap_test.c new file mode 100644 index 000000000..2b154c100 --- /dev/null +++ b/tests/bssap/bssap_test.c @@ -0,0 +1,120 @@ +/* + * (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/core/application.h> + +#include <osmocom/bsc/debug.h> +#include <osmocom/bsc/osmo_bsc.h> +#include <osmocom/bsc/signal.h> +#include <osmocom/bsc/bsc_subscriber.h> +#include <osmocom/bsc/bsc_msc_data.h> +#include <osmocom/bsc/common_bsc.h> +#include <osmocom/bsc/osmo_bsc_rf.h> + +struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex) +{ + struct msgb *msg = msgb_alloc(size, label); + unsigned char *rc; + msg->l2h = msg->l3h = msg->head; + rc = msgb_put(msg, osmo_hexparse(hex, msg->head, msgb_tailroom(msg))); + OSMO_ASSERT(rc == msg->l2h); + return msg; +} + +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); +int __wrap_bsc_grace_paging_request(enum signal_rf rf_policy, struct bsc_subscr *subscr, int chan_needed, + struct bsc_msc_data *msc) +{ + if (subscr->lac == GSM_LAC_RESERVED_ALL_BTS) + fprintf(stderr, "BSC paging started on entire BSS (%u)\n", subscr->lac); + else + fprintf(stderr, "BSC paging started with LAC %u\n", subscr->lac); + OSMO_ASSERT(gl_expect_lac == subscr->lac); + return 0; +} + +struct { + const char *msg; + uint16_t expect_lac; + int expect_rc; +} cell_identifier_tests[] = { + { + "001652080859512069000743940904010844601a03050065", + /* ^^^^^^ Cell Identifier List: LAC */ + 0x65, 0 + }, + { + "001452080859512069000743940904010844601a0106", + /* ^^ Cell Identifier List: BSS */ + GSM_LAC_RESERVED_ALL_BTS, 0 + }, + { + "001952080859512069000743940904010844601a060415f5490065", + /* ^^^^^^^^^^^^ Cell Identifier List: LAI */ + GSM_LAC_RESERVED_ALL_BTS, 0 + }, +}; + +void test_cell_identifier() +{ + int i; + int rc; + struct gsm_network *net; + struct bsc_msc_data *msc; + + net = bsc_network_init(NULL, 1, 1, NULL); + net->bsc_data->rf_ctrl = talloc_zero(NULL, struct osmo_bsc_rf); + net->bsc_data->rf_ctrl->policy = S_RF_ON; + + msc = talloc_zero(net, struct bsc_msc_data); + msc->network = net; + + log_set_log_level(osmo_stderr_target, LOGL_DEBUG); + + for (i = 0; i < ARRAY_SIZE(cell_identifier_tests); i++) { + struct msgb *msg; + fprintf(stderr, "\n%d:\n", i); + msg = msgb_from_hex("test_cell_identifier", 1024, cell_identifier_tests[i].msg); + + gl_expect_lac = cell_identifier_tests[i].expect_lac; + rc = bsc_handle_udt(msc, msg, msgb_l2len(msg)); + + fprintf(stderr, "bsc_handle_udt() returned %d\n", rc); + OSMO_ASSERT(rc == cell_identifier_tests[i].expect_rc); + + msgb_free(msg); + } +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_timestamp(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + log_set_print_category(osmo_stderr_target, 1); + + test_cell_identifier(); + + return 0; +} diff --git a/tests/bssap/bssap_test.err b/tests/bssap/bssap_test.err new file mode 100644 index 000000000..1c432eb08 --- /dev/null +++ b/tests/bssap/bssap_test.err @@ -0,0 +1,22 @@ + +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 +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 +BSC paging started on entire BSS (65534) +bsc_handle_udt() returned 0 + +2: +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 15 f5 49 00 65 +DMSC Rx MSC UDT BSSMAP PAGING +DMSC Paging IMSI 515029600703449: unimplemented Cell Identifier List (0x4), paging entire BSS instead (04 15 f5 49 00 65 ) +DMSC Paging request from MSC IMSI: '515029600703449' TMSI: '0x1084460/17319008' LAC: 0xfffe +BSC paging started on entire BSS (65534) +bsc_handle_udt() returned 0 diff --git a/tests/bssap/bssap_test.ok b/tests/bssap/bssap_test.ok new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/bssap/bssap_test.ok diff --git a/tests/testsuite.at b/tests/testsuite.at index 50f68e12e..13f54e119 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -50,3 +50,10 @@ AT_KEYWORDS([nanobts_omlattr]) cat $abs_srcdir/nanobts_omlattr/nanobts_omlattr_test.ok > expout AT_CHECK([$abs_top_builddir/tests/nanobts_omlattr/nanobts_omlattr_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([bssap]) +AT_KEYWORDS([bssap]) +cat $abs_srcdir/bssap/bssap_test.ok > expout +cat $abs_srcdir/bssap/bssap_test.err > experr +AT_CHECK([$abs_top_builddir/tests/bssap/bssap_test], [], [expout], [experr]) +AT_CLEANUP |