From aafff96c4060e9bf6ceb9dee9652a91d293a6e1e Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 20 Apr 2016 15:57:14 +0200 Subject: Add vty check for max si2quater size Explicitly check if added (U|E)ARFCN will fit into available si2quater message. --- openbsc/include/openbsc/system_information.h | 1 + openbsc/src/libbsc/bsc_vty.c | 23 +++++++----- openbsc/src/libbsc/system_information.c | 21 ++++++++++- openbsc/tests/gsm0408/gsm0408_test.c | 52 +++++++++++----------------- openbsc/tests/gsm0408/gsm0408_test.ok | 5 +-- 5 files changed, 60 insertions(+), 42 deletions(-) (limited to 'openbsc') diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h index ecc696422..7e3ceaa29 100644 --- a/openbsc/include/openbsc/system_information.h +++ b/openbsc/include/openbsc/system_information.h @@ -11,6 +11,7 @@ unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len); unsigned earfcn_size(const struct osmo_earfcn_si2q *e); unsigned range1024_p(unsigned n); unsigned range512_q(unsigned m); +bool si2q_size_check(const struct gsm_bts *bts); int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index cc4686577..e81308b30 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -2789,15 +2789,19 @@ DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd, VTY_NEWLINE); return CMD_WARNING; } + if (si2q_size_check(bts)) { + if (e->thresh_hi && thresh != e->thresh_hi) + vty_out(vty, "Warning: multiple thresholds are not " + "supported, overriding previous threshold %u%s", + e->thresh_hi, VTY_NEWLINE); - if (e->thresh_hi && thresh != e->thresh_hi) - vty_out(vty, "Warning: multiple thresholds are not supported, " - "overriding previous threshold %u%s", - e->thresh_hi, VTY_NEWLINE); - - e->thresh_hi = thresh; - - return CMD_SUCCESS; + e->thresh_hi = thresh; + return CMD_SUCCESS; + } + vty_out(vty, "Warning: not enough space in si2quater for a given arfcn%s" + , VTY_NEWLINE); + osmo_earfcn_del(e, arfcn); + return CMD_WARNING; } DEFUN(cfg_bts_si2quater_neigh_del, cfg_bts_si2quater_neigh_del_cmd, @@ -2835,6 +2839,9 @@ DEFUN(cfg_bts_si2quater_uarfcn_add, cfg_bts_si2quater_uarfcn_add_cmd, case -ENOMEM: vty_out(vty, "Unable to add arfcn: max number of UARFCNs (%u) " "reached%s", MAX_EARFCN_LIST, VTY_NEWLINE); + case -ENOSPC: + vty_out(vty, "Warning: not enough space in si2quater for a " + "given arfcn%s", VTY_NEWLINE); case -EADDRINUSE: vty_out(vty, "Unable to add arfcn: (%u, %u) is already added%s", arfcn, scramble, VTY_NEWLINE); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 8952534c1..3b0f889a1 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -134,6 +134,20 @@ unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len) return 29 + range1024_p(u_len); } +bool si2q_size_check(const struct gsm_bts *bts) +{ + const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; + const uint16_t *u = bts->si_common.data.uarfcn_list, + *sc = bts->si_common.data.scramble_list; + size_t len = bts->si_common.uarfcn_length; + unsigned e_sz = e ? earfcn_size(e) : 1, + u_sz = len ? uarfcn_size(u, sc, len) : 1; + /* 2 bits are used in between UARFCN and EARFCN structs */ + if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN) + return false; + return true; +} + /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */ uint16_t encode_fdd(uint16_t scramble, bool diversity) { @@ -198,7 +212,12 @@ int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, ual[k] = arfcn; scl[k] = scr; bts->si_common.uarfcn_length++; - return 0; + + if (si2q_size_check(bts)) + return 0; + + bts_uarfcn_del(bts, arfcn, scramble); + return -ENOSPC; } static inline int use_arfcn(const struct gsm_bts *bts, const bool bis, const bool ter, diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 2d91b68f0..92626670c 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -103,6 +103,16 @@ static inline void gen(struct gsm_bts *bts) printf("failed to generate SI2quater: %s\n", strerror(-r)); } +static inline void _bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, + uint16_t scramble, bool diversity) +{ + int r = bts_uarfcn_add(bts, arfcn, scramble, diversity); + if (r < 0) + printf("failed to add UARFCN to SI2quater: %s\n", strerror(-r)); + else + gen(bts); +} + static inline void test_si2q_u(void) { struct gsm_bts *bts; @@ -113,37 +123,17 @@ static inline void test_si2q_u(void) exit(1); bts = gsm_bts_alloc(network); - bts_uarfcn_add(bts, 1982, 13, 1); - gen(bts); - - bts_uarfcn_add(bts, 1982, 44, 0); - gen(bts); - - bts_uarfcn_add(bts, 1982, 61, 1); - gen(bts); - - bts_uarfcn_add(bts, 1982, 89, 1); - gen(bts); - - bts_uarfcn_add(bts, 1982, 113, 0); - gen(bts); - - bts_uarfcn_add(bts, 1982, 123, 0); - gen(bts); - - bts_uarfcn_add(bts, 1982, 56, 1); - gen(bts); - - bts_uarfcn_add(bts, 1982, 72, 1); - gen(bts); - - bts_uarfcn_add(bts, 1982, 223, 1); - gen(bts); - - bts_uarfcn_add(bts, 1982, 14, 0); - gen(bts); - - bts_uarfcn_add(bts, 1982, 88, 0); + _bts_uarfcn_add(bts, 1982, 13, 1); + _bts_uarfcn_add(bts, 1982, 44, 0); + _bts_uarfcn_add(bts, 1982, 61, 1); + _bts_uarfcn_add(bts, 1982, 89, 1); + _bts_uarfcn_add(bts, 1982, 113, 0); + _bts_uarfcn_add(bts, 1982, 123, 0); + _bts_uarfcn_add(bts, 1982, 56, 1); + _bts_uarfcn_add(bts, 1982, 72, 1); + _bts_uarfcn_add(bts, 1982, 223, 1); + _bts_uarfcn_add(bts, 1982, 14, 0); + _bts_uarfcn_add(bts, 1982, 88, 0); gen(bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.ok b/openbsc/tests/gsm0408/gsm0408_test.ok index 565eac672..7b7a2cc76 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.ok +++ b/openbsc/tests/gsm0408/gsm0408_test.ok @@ -80,6 +80,7 @@ generated SI2quater: [23] 59 06 07 c0 00 25 0f 7c 34 1a 64 26 5d f2 05 04 86 59 generated SI2quater: [23] 59 06 07 c0 00 25 0f 7c 38 58 12 22 fd ce 8e 05 04 86 59 00 03 2b 2b generated SI2quater: [23] 59 06 07 c0 00 25 0f 7c 40 58 1d 22 fa ce 88 85 7b 00 44 b2 00 03 2b generated SI2quater: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 10 99 64 00 0b -failed to generate SI2quater: Cannot allocate memory -failed to generate SI2quater: Cannot allocate memory +failed to add UARFCN to SI2quater: No space left on device +failed to add UARFCN to SI2quater: No space left on device +generated SI2quater: [23] 59 06 07 c0 00 25 0f 7c 4c 7a 34 0e 64 77 85 43 55 c8 10 99 64 00 0b Done. -- cgit v1.2.3