diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2019-07-13 01:12:53 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2019-08-13 23:47:23 +0200 |
commit | 91a202d4885d1e3aff6cb090ec688d695c2cd26b (patch) | |
tree | d3a0ebfff0c2acdce868a4756cd3231e41563443 /src/osmo-bsc/handover_fsm.c | |
parent | 12224e7ca7201b78cdf78b055065f07d223a060d (diff) |
neighbor config: allow re-using ARFCN+BSIC pairs
Fix neighbor config to match OsmoBSC manual: implement the plan for neighbor
configuration that was so far only described in the manual without actually
being in operation.
This first allows re-using ARFCN+BSIC pairs in and across BSS.
So far the handover_start() code always looked for handover target cells across
*all* local cells, even if they were not listed as neighbors to a source cell.
Imply all cells as neighbors only as long as there are no explicit neighbors
configured. As soon as the first 'neighbor' line appears in a 'bts' config,
only the listed neighbors are regarded as handover target cells. (The
'neighbor-list' commands are not related to this, only the relatively new
'neighbor (bts|lac|cgi|...)' commands affect actual handover procedures.)
TTCN3 tests TC_ho_neighbor_config_1 thru _7 play through the various aspects of
neighbor configuration: both the legacy implicit all-cells-are-neighbors as
well as allowing only explicit neighbors by config.
Related: OS#4056
Related: osmo-ttcn3-hacks Ia4ba0e75abd3d45a3422b2525e5f938cdc5a04cc
Change-Id: I29bca59ab232eddc74e0d4698efb9c9992443983
Diffstat (limited to 'src/osmo-bsc/handover_fsm.c')
-rw-r--r-- | src/osmo-bsc/handover_fsm.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c index 6d0c2d47e..d1593470b 100644 --- a/src/osmo-bsc/handover_fsm.c +++ b/src/osmo-bsc/handover_fsm.c @@ -31,6 +31,7 @@ #include <osmocom/bsc/bsc_subscriber.h> #include <osmocom/bsc/handover_fsm.h> +#include <osmocom/bsc/handover_cfg.h> #include <osmocom/bsc/bsc_subscr_conn_fsm.h> #include <osmocom/bsc/lchan_select.h> #include <osmocom/bsc/lchan_fsm.h> @@ -200,6 +201,9 @@ void handover_request(struct handover_out_req *req) conn = req->old_lchan->conn; OSMO_ASSERT(conn && conn->fi); + /* Make sure the handover target neighbor_ident_key contains the correct source bts nr */ + req->target_nik.from_bts = req->old_lchan->ts->trx->bts->nr; + /* To make sure we're allowed to start a handover, go through a gscon event dispatch. If that is accepted, the * same req is passed to handover_start(). */ osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_HANDOVER_START, req); @@ -285,9 +289,10 @@ void handover_start(struct handover_out_req *req) OSMO_ASSERT(req && req->old_lchan && req->old_lchan->conn); struct gsm_subscriber_connection *conn = req->old_lchan->conn; + const struct neighbor_ident_key *search_for = &req->target_nik; struct handover *ho = &conn->ho; - struct gsm_bts *bts; - const struct gsm0808_cell_id_list2 *cil; + struct gsm_bts *local_target_cell = NULL; + const struct gsm0808_cell_id_list2 *remote_target_cell = NULL; if (conn->ho.fi) { LOG_HO(conn, LOGL_ERROR, "Handover requested while another handover is ongoing; Ignore\n"); @@ -295,6 +300,9 @@ void handover_start(struct handover_out_req *req) } handover_reset(conn); + /* When handover_start() is invoked by the gscon, it expects a HANDOVER_END event. The best way to ensure this + * is to always create a handover_fsm instance, even if the target cell is not resolved yet. Any failure should + * then call handover_end(), which ensures that the conn snaps back to a valid state. */ handover_fsm_alloc(conn); ho->from_hodec_id = req->from_hodec_id; @@ -302,21 +310,25 @@ void handover_start(struct handover_out_req *req) req->old_lchan->type : req->new_lchan_type; ho->target_cell = req->target_nik; - bts = bts_by_neighbor_ident(conn->network, &req->target_nik); - if (bts) { - ho->new_bts = bts; + if (find_handover_target_cell(&local_target_cell, &remote_target_cell, + conn, search_for, true)) + goto no_handover; + + if (local_target_cell) { + ho->new_bts = local_target_cell; handover_start_intra_bsc(conn); return; } - cil = neighbor_ident_get(conn->network->neighbor_bss_cells, &req->target_nik); - if (cil) { - handover_start_inter_bsc_out(conn, cil); + if (remote_target_cell) { + handover_start_inter_bsc_out(conn, remote_target_cell); return; } - LOG_HO(conn, LOGL_ERROR, "Cannot handover %s: neighbor unknown\n", - neighbor_ident_key_name(&req->target_nik)); + /* should never reach this, because find_handover_target_cell() would have returned error. */ + OSMO_ASSERT(false); + +no_handover: handover_end(conn, HO_RESULT_FAIL_NO_CHANNEL); } |