From 0cfed38f07b4eb1bb17463b02d78917270ee8410 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 10 Feb 2021 16:10:56 +0100 Subject: [PATCH] Fix neigh resolution service on local neighbours Change-Id: I217e3550aa6d7f3c3cab4e545641d790ae12b23f Related: SYS#4909 --- src/osmo-bsc/neighbor_ident.c | 41 ++++++++++++++++++--- tests/ctrl/osmo-bsc-neigh-test.cfg | 59 ++++++++++++++++++++++++++++++ tests/ctrl_test_runner.py | 15 +++++++- 3 files changed, 109 insertions(+), 6 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); diff --git a/tests/ctrl/osmo-bsc-neigh-test.cfg b/tests/ctrl/osmo-bsc-neigh-test.cfg index f1e71b671..2fbc8f806 100644 --- a/tests/ctrl/osmo-bsc-neigh-test.cfg +++ b/tests/ctrl/osmo-bsc-neigh-test.cfg @@ -46,6 +46,8 @@ network oml ipa stream-id 255 line 0 codec-support fr gprs mode gprs + gprs routing area 5 + ! remote neigh: neighbor cgi-ps 23 42 423 2 5 arfcn 23 bsic 32 trx 0 rf_locked 0 @@ -78,6 +80,63 @@ network timeslot 7 phys_chan_config TCH/F hopping enabled 0 + bts 1 + type sysmobts + band DCS1800 + cell_identity 123 + location_area_code 1 + base_station_id_code 55 + ms max power 15 + cell reselection hysteresis 4 + rxlev access min 0 + radio-link-timeout 32 + channel allocator ascending + rach tx integer 9 + rach max transmission 7 + channel-description attach 1 + channel-description bs-pa-mfrms 5 + channel-description bs-ag-blks-res 1 + early-classmark-sending forbidden + ipa unit-id 55 0 + oml ipa stream-id 255 line 0 + codec-support fr + gprs mode gprs + gprs routing area 6 + neighbor bts 0 + trx 0 + rf_locked 0 + arfcn 880 + nominal power 23 + ! to use full TRX power, set max_power_red 0 + max_power_red 20 + rsl e1 tei 0 + timeslot 0 + phys_chan_config CCCH+SDCCH4 + hopping enabled 0 + timeslot 1 + phys_chan_config TCH/F + hopping enabled 0 + timeslot 2 + phys_chan_config TCH/F + hopping enabled 0 + timeslot 3 + phys_chan_config TCH/F + hopping enabled 0 + timeslot 4 + phys_chan_config TCH/F + hopping enabled 0 + timeslot 5 + phys_chan_config TCH/F + hopping enabled 0 + timeslot 6 + phys_chan_config TCH/F + hopping enabled 0 + timeslot 7 + phys_chan_config TCH/F + hopping enabled 0 + bts 0 + ! local neigh, refers to bts 1: + neighbor cgi-ps 1 1 1 6 123 msc 0 type normal allow-emergency allow diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py index fb983c984..501b917b5 100755 --- a/tests/ctrl_test_runner.py +++ b/tests/ctrl_test_runner.py @@ -501,11 +501,24 @@ class TestCtrlBSCNeighbor(TestCtrlBase): def ctrl_app(self): return (4248, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc") - def testCtrlNeighborResolution(self): + def testCtrlNeighborResolutionLocalBtsNr(self): + r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci.1.123.871.63') + self.assertEqual(r['mtype'], 'GET_REPLY') + self.assertEqual(r['var'], 'neighbor_resolve_cgi_ps_from_lac_ci.1.123.871.63') + self.assertEqual(r['value'], '001-01-1-5-6969') + + def testCtrlNeighborResolutionLocalWithoutArfcnBsic(self): + r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci.1.6969.880.55') + self.assertEqual(r['mtype'], 'GET_REPLY') + self.assertEqual(r['var'], 'neighbor_resolve_cgi_ps_from_lac_ci.1.6969.880.55') + self.assertEqual(r['value'], '001-01-1-6-123') + + def testCtrlNeighborResolutionWrongSyntax(self): r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci') self.assertEqual(r['mtype'], 'ERROR') self.assertEqual(r['error'], 'The format is ,,,') + def testCtrlNeighborResolutionRemote(self): r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci.1.6969.23.32') self.assertEqual(r['mtype'], 'GET_REPLY') self.assertEqual(r['var'], 'neighbor_resolve_cgi_ps_from_lac_ci.1.6969.23.32')