diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2018-04-11 01:28:21 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2018-06-16 15:53:52 +0200 |
commit | 73e028416e82f5f6b21d7f323fd907110ae02d74 (patch) | |
tree | 6af418ba0af169d730a68fcfc2f02f40b6a96d49 | |
parent | d4a80811026effef6fdd01cc67e811b8dc76c9cc (diff) |
prevent ARFCN+BSIC collisions in config
If multiple BTS are configured with identical ARFCN+BSIC, handover cannot
possibly work. Add warn_on_arfcn_bsic_collisions() and when collisions are
detected:
- exit right away on program startup.
- warn on vty bts node-exit (go_parent_cb()), i.e. when ARFCN+BSIC collide
implicitly from default values.
- warn on vty bts/base_station_id_code cmd coming from telnet vty,
i.e. when the user actively configures colliding BSIC.
- warn on vty trx/arfcn cmd coming from telnet vty,
i.e. when the user actively configures colliding ARFCN.
When warning, warn on all of:
- DHO log,
- stderr,
- vty_out() in case a vty instance is passed (i.e. from interactive vty).
It's better to log this once too often than let the user miss it.
Rationale: when I started to implement ttcn3 tests for inter-bsc HO, I saw that
the new code based on ARFCN+BSIC would cause a handover request intended to go
from BTS 0 to BTS 1 to instead go from BTS 0 to back to BTS 0 -- because of
identical ARFCN+BSIC in the config of ttcn3-bsc-tests. Such a config badly
confuses handover: measurement reports interpreted to come from the wrong cell,
all handovers attempted to go to the first BTS (sometimes correctly, sometimes
wrongly), in short, non-obvious failure across the handover board. The network
would appear to work well, but occasionally a handover would kill a call
without apparent reason. It seems worthwhile to prevent such misconfiguration
as early as possible, and even allow previous ARFCN+BSIC misconfiguration that
used to work to instead break now (only upon reading config during program
startup, to not cause program exit just because a user introduces a temporary
collision in an interactive vty session).
Change-Id: Ia7c38188ccbad5d8b7398e3e5220015e62c08c8b
-rw-r--r-- | include/osmocom/bsc/vty.h | 2 | ||||
-rw-r--r-- | src/osmo-bsc/bsc_vty.c | 30 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_main.c | 4 |
3 files changed, 36 insertions, 0 deletions
diff --git a/include/osmocom/bsc/vty.h b/include/osmocom/bsc/vty.h index e63275546..bfea69d2a 100644 --- a/include/osmocom/bsc/vty.h +++ b/include/osmocom/bsc/vty.h @@ -35,4 +35,6 @@ int bsc_vty_init_extra(void); struct gsm_network *gsmnet_from_vty(struct vty *vty); +int warn_on_arfcn_bsic_collisions(struct gsm_network *net, struct vty *vty); + #endif diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c index 27e1bc697..5298644e6 100644 --- a/src/osmo-bsc/bsc_vty.c +++ b/src/osmo-bsc/bsc_vty.c @@ -2119,6 +2119,30 @@ DEFUN_HIDDEN(cfg_bts_tsc, return CMD_SUCCESS; } +int warn_on_arfcn_bsic_collisions(struct gsm_network *net, struct vty *vty) +{ + struct gsm_bts *bts, *bts2; + int errors = 0; + + llist_for_each_entry(bts, &net->bts_list, list) { + struct neighbor_ident_key *nik = bts_ident_key(bts); + + bts2 = bts_by_neighbor_ident(net, nik); + if (bts != bts2) { + LOGP(DHO, LOGL_ERROR, "CONFIG ERROR: Multiple BTS match %s: %d and %d\n", + neighbor_ident_key_name(nik), bts->nr, bts2->nr); + fprintf(stderr, "CONFIG ERROR: Multiple BTS match %s: %d and %d\n", + neighbor_ident_key_name(nik), bts->nr, bts2->nr); + if (vty) + vty_out(vty, "%% CONFIG ERROR: Multiple BTS match %s: %d and %d%s", + neighbor_ident_key_name(nik), bts->nr, bts2->nr, + VTY_NEWLINE); + errors ++; + } + } + return errors; +} + DEFUN(cfg_bts_bsic, cfg_bts_bsic_cmd, "base_station_id_code <0-63>", @@ -2135,6 +2159,9 @@ DEFUN(cfg_bts_bsic, } bts->bsic = bsic; + if (vty->type != VTY_FILE) + warn_on_arfcn_bsic_collisions(bts->network, vty); + return CMD_SUCCESS; } @@ -3884,6 +3911,9 @@ DEFUN(cfg_trx_arfcn, /* FIXME: use OML layer to update the ARFCN */ /* FIXME: use RSL layer to update SYSTEM INFORMATION */ + if (vty->type != VTY_FILE) + warn_on_arfcn_bsic_collisions(trx->bts->network, vty); + return CMD_SUCCESS; } diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c index 69db32e55..c46d2fa9e 100644 --- a/src/osmo-bsc/osmo_bsc_main.c +++ b/src/osmo-bsc/osmo_bsc_main.c @@ -539,6 +539,8 @@ static int bsc_vty_go_parent(struct vty *vty) vty->index = bts->network; vty->index_sub = NULL; } + if (vty->type != VTY_FILE) + warn_on_arfcn_bsic_collisions(bsc_gsmnet, vty); break; case TRX_NODE: vty->node = BTS_NODE; @@ -826,6 +828,8 @@ int main(int argc, char **argv) fprintf(stderr, "Bootstrapping the network failed. exiting.\n"); exit(1); } + if (warn_on_arfcn_bsic_collisions(bsc_gsmnet, NULL)) + exit(1); /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ |