diff options
authorNeels Hofmeyr <neels@hofmeyr.de>2018-04-11 01:28:21 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-06-16 15:53:52 +0200
commit73e028416e82f5f6b21d7f323fd907110ae02d74 (patch)
parentd4a80811026effef6fdd01cc67e811b8dc76c9cc (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
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);
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,
+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,
+ errors ++;
+ }
+ }
+ return errors;
"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);
@@ -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);
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);
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");
+ if (warn_on_arfcn_bsic_collisions(bsc_gsmnet, NULL))
+ exit(1);
/* start control interface after reading config for
* ctrl_vty_get_bind_addr() */