diff options
author | Pau Espin Pedrol <pespin@espeweb.net> | 2021-02-10 16:10:56 +0100 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2021-02-13 08:15:01 +0000 |
commit | 0cfed38f07b4eb1bb17463b02d78917270ee8410 (patch) | |
tree | d82cb34b75bbf49b95bc68d6dce007766880299b /src/osmo-bsc/neighbor_ident.c | |
parent | a27e8a5c9a797638a00bdf8ecdf1276ae5c4c6cc (diff) |
Fix neigh resolution service on local neighbours
Change-Id: I217e3550aa6d7f3c3cab4e545641d790ae12b23f
Related: SYS#4909
Diffstat (limited to 'src/osmo-bsc/neighbor_ident.c')
-rw-r--r-- | src/osmo-bsc/neighbor_ident.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/osmo-bsc/neighbor_ident.c b/src/osmo-bsc/neighbor_ident.c index 335091e3a..323550829 100644 --- a/src/osmo-bsc/neighbor_ident.c +++ b/src/osmo-bsc/neighbor_ident.c @@ -276,6 +276,19 @@ struct neighbor_ident_key *bts_ident_key(const struct gsm_bts *bts) CTRL_CMD_DEFINE_RO(neighbor_resolve_cgi_ps_from_lac_ci, "neighbor_resolve_cgi_ps_from_lac_ci"); +static int gsm_bts_get_cgi_ps(const struct gsm_bts *bts, struct osmo_cell_global_id_ps *cgi_ps) +{ + if (bts->gprs.mode == BTS_GPRS_NONE) + return -ENOTSUP; + + cgi_ps->rai.lac.plmn = bts->network->plmn; + cgi_ps->rai.lac.lac = bts->location_area_code; + cgi_ps->rai.rac = bts->gprs.rac; + cgi_ps->cell_identity = bts->cell_identity; + + return 0; +} + static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *data) { struct gsm_network *net = (struct gsm_network *)data; @@ -284,7 +297,9 @@ static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *d char *tmp = NULL, *tok, *saveptr; struct neighbor_ident_key ni; unsigned lac, cell_id; - const struct osmo_cell_global_id_ps *cgi_ps; + struct osmo_cell_global_id_ps local_cgi_ps; + const struct osmo_cell_global_id_ps *cgi_ps = NULL; + struct gsm_bts_ref *neigh; if (!cmd->variable) goto fmt_err; @@ -335,10 +350,26 @@ static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *d if (!neighbor_ident_key_valid(&ni)) goto fmt_err; - tgt_cell_li = neighbor_ident_get(net->neighbor_bss_cells, &ni); - if (!tgt_cell_li || tgt_cell_li->id_discr != CELL_IDENT_WHOLE_GLOBAL_PS || tgt_cell_li->id_list_len < 1) - goto notfound_err; - cgi_ps = &tgt_cell_li->id_list[0].global_ps; + /* Is there a local BTS that matches the key? */ + llist_for_each_entry(neigh, &bts_found->local_neighbors, entry) { + struct gsm_bts *neigh_bts = neigh->bts; + struct neighbor_ident_key *neigh_bts_key = bts_ident_key(neigh_bts); + neigh_bts_key->from_bts = ni.from_bts; + if (!neighbor_ident_key_match(neigh_bts_key, &ni, true)) + continue; + if (gsm_bts_get_cgi_ps(neigh->bts, &local_cgi_ps) < 0) + continue; /* Not supporting GPRS */ + cgi_ps = &local_cgi_ps; + break; + } + + /* No local neighbor found, looking for remote neighbors */ + if (!cgi_ps) { + tgt_cell_li = neighbor_ident_get(net->neighbor_bss_cells, &ni); + if (!tgt_cell_li || tgt_cell_li->id_discr != CELL_IDENT_WHOLE_GLOBAL_PS || tgt_cell_li->id_list_len < 1) + goto notfound_err; + cgi_ps = &tgt_cell_li->id_list[0].global_ps; + } ctrl_cmd_reply_printf(cmd, "%s", osmo_cgi_ps_name(cgi_ps)); talloc_free(tmp); |