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/src/libbsc/bsc_vty.c | 23 +++++++++++++++-------- openbsc/src/libbsc/system_information.c | 21 ++++++++++++++++++++- 2 files changed, 35 insertions(+), 9 deletions(-) (limited to 'openbsc/src') 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, -- cgit v1.2.3