Change in osmo-bsc[master]: Introduce Neighbor Resolution Service

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Wed Jan 13 18:17:09 UTC 2021


pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bsc/+/21848 )

Change subject: Introduce Neighbor Resolution Service
......................................................................

Introduce Neighbor Resolution Service

This new CTRL interface allows users of this BSC (such as attached PCU)
to gather neighbor information.

This interface is needed for PCU to translate ARFCN+BSIC keys provided
by MS in the Um side into CGI + RAC keys used to identify target cells
in RIM procedures against SGSNs on the Gb interface.

This patch extends the already existing neighbor information storage in
the VTY by allowing storage of CGI + RAC (RAC couldn't be stored
beforehand).

Related: SYS#4909
Depends: libosmocore.git Change-Id If48f412c32e8e5a3e604a78d12b74787a4786374
Change-Id: Ib07c9d23026332a207d4b7a0f7b4e76c0094e379
---
M doc/manuals/chapters/handover.adoc
M include/osmocom/bsc/gsm_data.h
M include/osmocom/bsc/neighbor_ident.h
M src/osmo-bsc/bsc_vty.c
M src/osmo-bsc/bts.c
M src/osmo-bsc/neighbor_ident.c
M src/osmo-bsc/neighbor_ident_vty.c
M src/osmo-bsc/osmo_bsc_main.c
M tests/Makefile.am
M tests/bsc/Makefile.am
A tests/ctrl/osmo-bsc-neigh-test.cfg
M tests/ctrl_test_runner.py
M tests/gsm0408/Makefile.am
M tests/neighbor_ident.vty
14 files changed, 471 insertions(+), 7 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/doc/manuals/chapters/handover.adoc b/doc/manuals/chapters/handover.adoc
index 8601dce..4de744b 100644
--- a/doc/manuals/chapters/handover.adoc
+++ b/doc/manuals/chapters/handover.adoc
@@ -1,4 +1,5 @@
-== Handover
+[[cs_handover]]
+== CS Handover
 
 Handover is the process of moving a continuously used channel (lchan) from one
 cell to another. Usually, that is an ongoing call, so that phones are able to
@@ -144,6 +145,7 @@
 number of times across a network, and even between cells managed by one and the
 same BSC.
 
+[[config_neigh]]
 === Configuring Neighbors
 
 The most important step to enable handover in OsmoBSC is to configure each cell
@@ -692,3 +694,100 @@
 
 4G neighbor cells can be removed using the same command, just replacing
 `add` with `del`.
+
+[[ps_handover]]
+== PS Handover
+
+Packet Switch Handover is mostly managed by the packet switching nodes such as
+PCU, SGSN and GGSN. However, the PCU encounters a similar difficulty to that
+explained in <<cs_handover>>: that is, it must find a way to translate
+ARFCN+BSIC identifiers provided by the MS into the sort of identifiers
+understood by the Core Network (SGSN). These identifiers are in this case
+composed of RAC+CI (instead LAC+CI), or more specifically, CGI+RAC (named as
+"Packet Switched CGI" or "CGI-PS" from now on for convenience).
+
+Hence, it feels natural extending the <<config_neigh>> storage in the BSC to
+also provide Packet Switched related identifiers in order to provide the PCU the
+required information to do the translations, instead of duplicating the whole
+neighbor information in two different network nodes.
+
+This can be done, similarly to already presented CS related commands in
+<<config_neigh>>, by using the `neighbor cgi-ps` VTY command, which allows for
+specifying the extra identifier (RAC) required by PS related translations:
+
+.Example: configuring PS neighbors within the local BSS in osmo-bsc.cfg, identified by CGI-PS (CGI+RAC)
+----
+network
+ bts 0
+neighbor cgi-ps <MCC> <MNC> <LAC> <RAC> <CI> arfcn <0-1023> bsic (<0-63>|any)
+----
+
+This information should already be present by default if one uses the `local BTS
+number` to identify the network, as long as that BTS is properly configured to
+have GPRS enabled and the RAC code is set by `gprs routing area <0-255>`
+command:
+
+.Example: configuring PS neighbors within the local BSS in osmo-bsc.cfg, identified by local BTS number
+----
+network
+ bts 0
+  gprs mode gprs
+  gprs routing area 45
+  neighbor bts 1
+  ...
+ bts 1
+  gprs mode egprs
+  gprs routing area 48
+  neighbor bts 0
+  ...
+----
+
+This PS information is solely used by the Neighbor Resolution Service, aimed at
+nodes other than BSC itself, and described below.
+
+=== Neighbor Resolution Service CTRL interface
+
+This service is provided in order to provide the PCU a way to translate
+ARCFCN+BSIC into CGI-PS in order to use RIM services and accomplish PS
+Handovers.
+
+This interface is Osmocom specific, since the standard doesn't provide any
+specifications on how to provide this kind of information to the PCU.
+
+Since the PCU can be either BSC-colocated or BTS-colocated (hence on a different
+host than BSC), this must be a network-based interface. Since the service is
+Osmocom-specific, it was decided to re-use the CTRL interface available in most
+Osmocom processes (see <<control>>).
+
+Due to security concerns, the set of CTRL commands available in this
+service is configured in a different IP address and port, since the service
+needs to be reachable by all PCU under the BSC. This way the user can still
+constrain the regular CTRL port (which may contains lots of configuration
+related commands) listening in a more constrained address (eg. localhost).
+
+By default, this interface is disabled, and it is enabled by configuring the
+desired IP address to bind to (and optionally a different port other than
+well-known `4248`):
+
+.Example: Enable and configure Neighbor Resolution Service CTRL interface
+----
+network
+ neighbor-resolution bind 127.0.0.1 5000
+----
+
+osmo-pcu will then be able to connect to the BSC and query for resolution during eg. NACC requests from MS.
+
+The relevant commands are::
+
+* neighbor_resolve_cgi_ps_from_lac_ci:
+----
+GET neighbor_resolve_cgi_ps_from_lac_ci.<src_lac>.<src_cell_id>.<dst_arfcn>.<dst_bsic>
+GET_REPLY <MCC>-<MNC>-<LAC>-<RAC>-<CI>
+----
+
+Where the `src_lac` and `src_ci` are provided by BTS/BSC over `PCUIF` interface
+during startup (`INFO IND`), and `dst_arfcn` and `dst_bsic` are those of the
+neighbor the PCU is willing to request the CGI-PS information. Hence, from the
+`src` params the BSC is able to look up the BTS and afterwards apply the
+translation of `dst` parameters based on the neighbor information available for
+that BTS.
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 233c3b6..8b53902 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1213,6 +1213,12 @@
 
 	/* Remote BSS Cell Identifier Lists */
 	struct neighbor_ident_list *neighbor_bss_cells;
+	/* Remote BSS resolution sevice (CTRL iface) */
+	struct {
+		char *addr;
+		uint16_t port;
+		struct ctrl_handle *handle;
+	} neigh_ctrl;
 
 	/* Don't refuse to start with mutually exclusive codec settings */
 	bool allow_unusable_timeslots;
diff --git a/include/osmocom/bsc/neighbor_ident.h b/include/osmocom/bsc/neighbor_ident.h
index aa38276..c8580e2 100644
--- a/include/osmocom/bsc/neighbor_ident.h
+++ b/include/osmocom/bsc/neighbor_ident.h
@@ -5,6 +5,7 @@
 #include <stdbool.h>
 
 #include <osmocom/core/linuxlist.h>
+#include <osmocom/ctrl/control_cmd.h>
 
 struct vty;
 struct gsm_network;
@@ -45,7 +46,8 @@
 			 void *cb_data);
 
 void neighbor_ident_vty_init(struct gsm_network *net, struct neighbor_ident_list *nil);
-void neighbor_ident_vty_write(struct vty *vty, const char *indent, struct gsm_bts *bts);
+void neighbor_ident_vty_write_bts(struct vty *vty, const char *indent, struct gsm_bts *bts);
+void neighbor_ident_vty_write_network(struct vty *vty, const char *indent);
 
 bool neighbor_ident_bts_entry_exists(uint8_t from_bts);
 
@@ -58,3 +60,12 @@
 					 struct neighbor_ident_key *key);
 bool neighbor_ident_bts_parse_key_params(struct vty *vty, struct gsm_bts *bts, const char **argv,
 					 struct neighbor_ident_key *key);
+
+
+struct ctrl_handle *neighbor_controlif_setup(struct gsm_network *net);
+int neighbor_ctrl_cmds_install(struct gsm_network *net);
+
+enum neighbor_ctrl_node {
+	CTRL_NODE_NEIGH = _LAST_CTRL_NODE,
+	_LAST_CTRL_NODE_NEIGHBOR
+};
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index d61d379..400e1a6 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1175,7 +1175,7 @@
 			VTY_NEWLINE);
 	}
 
-	neighbor_ident_vty_write(vty, "  ", bts);
+	neighbor_ident_vty_write_bts(vty, "  ", bts);
 
 	vty_out(vty, "  codec-support fr");
 	if (bts->codec.hr)
@@ -1315,6 +1315,8 @@
 		vty_out(vty, "%s", VTY_NEWLINE);
 	}
 
+	neighbor_ident_vty_write_network(vty, " ");
+
 	return CMD_SUCCESS;
 }
 
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
index 39122ae..0774721 100644
--- a/src/osmo-bsc/bts.c
+++ b/src/osmo-bsc/bts.c
@@ -388,6 +388,10 @@
 	case CELL_IDENT_WHOLE_GLOBAL:
 		return gsm_bts_matches_lai(bts, &id->global.lai)
 			&& id->global.cell_identity == bts->cell_identity;
+	case CELL_IDENT_WHOLE_GLOBAL_PS:
+		return gsm_bts_matches_lai(bts, &id->global_ps.rai.lac)
+			&& id->global_ps.rai.rac == bts->gprs.rac
+			&& id->global_ps.cell_identity == bts->cell_identity;
 	case CELL_IDENT_LAC_AND_CI:
 		return id->lac_and_ci.lac == bts->location_area_code
 			&& id->lac_and_ci.ci == bts->cell_identity;
diff --git a/src/osmo-bsc/neighbor_ident.c b/src/osmo-bsc/neighbor_ident.c
index 4a0cd47..185cd0b 100644
--- a/src/osmo-bsc/neighbor_ident.c
+++ b/src/osmo-bsc/neighbor_ident.c
@@ -33,6 +33,13 @@
 
 #include <osmocom/bsc/neighbor_ident.h>
 
+#include <osmocom/ctrl/control_cmd.h>
+#include <osmocom/ctrl/control_if.h>
+
+#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/bts.h>
+#include <osmocom/bsc/debug.h>
+
 struct neighbor_ident_list {
 	struct llist_head list;
 };
@@ -253,3 +260,99 @@
 			return;
 	}
 }
+
+/* Neighbor Resolution CTRL iface */
+
+CTRL_CMD_DEFINE_RO(neighbor_resolve_cgi_ps_from_lac_ci, "neighbor_resolve_cgi_ps_from_lac_ci");
+
+static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *data)
+{
+	struct gsm_network *net = (struct gsm_network *)data;
+	struct gsm_bts *bts_tmp, *bts_found = NULL;
+	const struct gsm0808_cell_id_list2 *tgt_cell_li = NULL;
+	char *tmp = NULL, *tok, *saveptr;
+	struct neighbor_ident_key ni;
+	unsigned lac, cell_id;
+	const struct osmo_cell_global_id_ps *cgi_ps;
+
+	if (!cmd->variable)
+		goto fmt_err;
+
+	tmp = talloc_strdup(cmd, cmd->variable);
+	if (!tmp) {
+		cmd->reply = "OOM";
+		return CTRL_CMD_ERROR;
+	}
+
+	if (!(tok = strtok_r(tmp, ".", &saveptr)))
+		goto fmt_err;
+	OSMO_ASSERT(strcmp(tok, "neighbor_resolve_cgi_ps_from_lac_ci") == 0);
+
+	if (!(tok = strtok_r(NULL, ".", &saveptr)))
+		goto fmt_err;
+	lac = atoi(tok);
+
+	if (!(tok = strtok_r(NULL, ".", &saveptr)))
+		goto fmt_err;
+	cell_id = atoi(tok);
+
+	if (!(tok = strtok_r(NULL, ".", &saveptr)))
+		goto fmt_err;
+	ni.arfcn = atoi(tok);
+
+	if (!(tok = strtok_r(NULL, "\0", &saveptr)))
+		goto fmt_err;
+	ni.bsic = atoi(tok);
+
+	ni.from_bts = NEIGHBOR_IDENT_KEY_ANY_BTS;
+
+	llist_for_each_entry(bts_tmp, &net->bts_list, list) {
+		if (bts_tmp->location_area_code != lac)
+			continue;
+		if (bts_tmp->cell_identity != cell_id)
+			continue;
+		bts_found = bts_tmp;
+		ni.from_bts = bts_tmp->nr;
+		break;
+	}
+
+	if (!bts_found)
+		goto notfound_err;
+
+	LOG_BTS(bts_found, DLINP, LOGL_DEBUG, "Resolving neigbhor arfcn=%u bsic=%u\n", ni.arfcn, ni.bsic);
+
+	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;
+
+	ctrl_cmd_reply_printf(cmd, "%s", osmo_cgi_ps_name(cgi_ps));
+	talloc_free(tmp);
+	return CTRL_CMD_REPLY;
+
+notfound_err:
+	talloc_free(tmp);
+	cmd->reply = talloc_strdup(cmd, "No target CGI PS found");
+	return CTRL_CMD_ERROR;
+fmt_err:
+	talloc_free(tmp);
+	cmd->reply = talloc_strdup(cmd, "The format is <src_lac>,<src_cell_id>,<dst_arfcn>,<dst_bsic>");
+	return CTRL_CMD_ERROR;
+}
+
+int neighbor_ctrl_cmds_install(struct gsm_network *net)
+{
+	int rc;
+
+	rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_neighbor_resolve_cgi_ps_from_lac_ci);
+	return rc;
+}
+
+struct ctrl_handle *neighbor_controlif_setup(struct gsm_network *net)
+{
+	return ctrl_interface_setup_dynip2(net, net->neigh_ctrl.addr, net->neigh_ctrl.port,
+					   NULL, _LAST_CTRL_NODE_NEIGHBOR);
+}
diff --git a/src/osmo-bsc/neighbor_ident_vty.c b/src/osmo-bsc/neighbor_ident_vty.c
index 7feed2a..72c11b0 100644
--- a/src/osmo-bsc/neighbor_ident_vty.c
+++ b/src/osmo-bsc/neighbor_ident_vty.c
@@ -23,6 +23,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <inttypes.h>
+
+#include <osmocom/ctrl/ports.h>
 
 #include <osmocom/vty/command.h>
 #include <osmocom/gsm/gsm0808.h>
@@ -84,6 +87,9 @@
 #define CGI_PARAMS "cgi <0-999> <0-999> <0-65535> <0-65535>"
 #define CGI_DOC "Neighbor cell by cgi\n" "MCC\n" "MNC\n" "LAC\n" "CI\n"
 
+#define CGI_PS_PARAMS "cgi-ps <0-999> <0-999> <0-65535> <0-255> <0-65535>"
+#define CGI_PS_DOC "Neighbor cell by cgi (Packet Switched, with RAC)\n" "MCC\n" "MNC\n" "LAC\n" "RAC\n" "CI\n"
+
 #define LOCAL_BTS_PARAMS "bts <0-255>"
 #define LOCAL_BTS_DOC "Neighbor cell by local BTS number\n" "BTS number\n"
 
@@ -154,6 +160,34 @@
 	return &cell_id;
 }
 
+static struct gsm0808_cell_id *neighbor_ident_vty_parse_cgi_ps(struct vty *vty, const char **argv)
+{
+	static struct gsm0808_cell_id cell_id = {
+		.id_discr = CELL_IDENT_WHOLE_GLOBAL_PS,
+	};
+	struct osmo_cell_global_id_ps *cgi_ps = &cell_id.id.global_ps;
+	const char *mcc = argv[0];
+	const char *mnc = argv[1];
+	const char *lac = argv[2];
+	const char *rac = argv[3];
+	const char *ci = argv[4];
+
+	if (osmo_mcc_from_str(mcc, &cgi_ps->rai.lac.plmn.mcc)) {
+		vty_out(vty, "%% Error decoding MCC: %s%s", mcc, VTY_NEWLINE);
+		return NULL;
+	}
+
+	if (osmo_mnc_from_str(mnc, &cgi_ps->rai.lac.plmn.mnc, &cgi_ps->rai.lac.plmn.mnc_3_digits)) {
+		vty_out(vty, "%% Error decoding MNC: %s%s", mnc, VTY_NEWLINE);
+		return NULL;
+	}
+
+	cgi_ps->rai.lac.lac = atoi(lac);
+	cgi_ps->rai.rac = atoi(rac);
+	cgi_ps->cell_identity = atoi(ci);
+	return &cell_id;
+}
+
 static int add_local_bts(struct vty *vty, struct gsm_bts *neigh)
 {
 	int rc;
@@ -246,6 +280,13 @@
 	return add_local_bts(vty, bts_by_cell_id(vty, neighbor_ident_vty_parse_cgi(vty, argv)));
 }
 
+DEFUN(cfg_neighbor_add_cgi_ps, cfg_neighbor_add_cgi_ps_cmd,
+	NEIGHBOR_ADD_CMD CGI_PS_PARAMS,
+	NEIGHBOR_ADD_DOC CGI_PS_DOC)
+{
+	return add_local_bts(vty, bts_by_cell_id(vty, neighbor_ident_vty_parse_cgi_ps(vty, argv)));
+}
+
 bool neighbor_ident_key_matches_bts(const struct neighbor_ident_key *key, struct gsm_bts *bts)
 {
 	if (!bts || !key)
@@ -497,6 +538,19 @@
 	return add_remote_or_local_bts(vty, cell_id, &nik);
 }
 
+DEFUN(cfg_neighbor_add_cgi_ps_arfcn_bsic, cfg_neighbor_add_cgi_ps_arfcn_bsic_cmd,
+	NEIGHBOR_ADD_CMD CGI_PS_PARAMS " " NEIGHBOR_IDENT_VTY_KEY_PARAMS,
+	NEIGHBOR_ADD_DOC CGI_PS_DOC NEIGHBOR_IDENT_VTY_KEY_DOC)
+{
+	struct neighbor_ident_key nik;
+	struct gsm0808_cell_id *cell_id = neighbor_ident_vty_parse_cgi_ps(vty, argv);
+	if (!cell_id)
+		return CMD_WARNING;
+	if (!neighbor_ident_vty_parse_key_params(vty, argv + 5, &nik))
+		return CMD_WARNING;
+	return add_remote_or_local_bts(vty, cell_id, &nik);
+}
+
 DEFUN(cfg_neighbor_del_bts_nr, cfg_neighbor_del_bts_nr_cmd,
 	NEIGHBOR_DEL_CMD LOCAL_BTS_PARAMS,
 	NEIGHBOR_DEL_DOC LOCAL_BTS_DOC)
@@ -525,6 +579,27 @@
 	return neighbor_del_all(vty);
 }
 
+DEFUN(cfg_neighbor_bind, cfg_neighbor_bind_cmd,
+	"neighbor-resolution bind " VTY_IPV46_CMD " [<0-65535>]",
+	NEIGHBOR_DOC "Bind Neighbor Resolution Service (CTRL interface) to given ip and port\n"
+	IP_STR IPV6_STR "Port to bind the service to [defaults to 4248 if not provided]\n")
+{
+	osmo_talloc_replace_string(g_net, &g_net->neigh_ctrl.addr, argv[0]);
+	if (argc > 1)
+		g_net->neigh_ctrl.port = atoi(argv[1]);
+	else
+		g_net->neigh_ctrl.port = OSMO_CTRL_PORT_BSC_NEIGH;
+	return CMD_SUCCESS;
+}
+
+void neighbor_ident_vty_write_network(struct vty *vty, const char *indent)
+{
+	if (g_net->neigh_ctrl.addr)
+		vty_out(vty, "%sneighbor-resolution bind %s %" PRIu16 "%s", indent, g_net->neigh_ctrl.addr,
+			g_net->neigh_ctrl.port, VTY_NEWLINE);
+}
+
+
 struct write_neighbor_ident_entry_data {
 	struct vty *vty;
 	const char *indent;
@@ -576,6 +651,16 @@
 					cgi->lai.lac, cgi->cell_identity);
 		}
 		break;
+	case CELL_IDENT_WHOLE_GLOBAL_PS:
+		for (i = 0; i < val->id_list_len; i++) {
+			const struct osmo_cell_global_id_ps *cgi_ps = &val->id_list[i].global_ps;
+			NEIGH_BSS_WRITE("cgi-ps %s %s %u %u %u",
+					osmo_mcc_name(cgi_ps->rai.lac.plmn.mcc),
+					osmo_mnc_name(cgi_ps->rai.lac.plmn.mnc, cgi_ps->rai.lac.plmn.mnc_3_digits),
+					cgi_ps->rai.lac.lac, cgi_ps->rai.rac,
+					cgi_ps->cell_identity);
+		}
+		break;
 	default:
 		vty_out(vty, "%% Unsupported Cell Identity%s", VTY_NEWLINE);
 	}
@@ -604,7 +689,7 @@
 	}
 }
 
-void neighbor_ident_vty_write(struct vty *vty, const char *indent, struct gsm_bts *bts)
+void neighbor_ident_vty_write_bts(struct vty *vty, const char *indent, struct gsm_bts *bts)
 {
 	neighbor_ident_vty_write_local_neighbors(vty, indent, bts);
 	neighbor_ident_vty_write_remote_bss(vty, indent, bts);
@@ -662,13 +747,17 @@
 {
 	g_net = net;
 	g_neighbor_cells = nil;
+	install_element(GSMNET_NODE, &cfg_neighbor_bind_cmd);
+
 	install_element(BTS_NODE, &cfg_neighbor_add_bts_nr_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_add_lac_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_add_lac_ci_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_add_cgi_cmd);
+	install_element(BTS_NODE, &cfg_neighbor_add_cgi_ps_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_add_lac_arfcn_bsic_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_add_lac_ci_arfcn_bsic_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_add_cgi_arfcn_bsic_cmd);
+	install_element(BTS_NODE, &cfg_neighbor_add_cgi_ps_arfcn_bsic_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_del_bts_nr_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_del_arfcn_bsic_cmd);
 	install_element(BTS_NODE, &cfg_neighbor_del_all_cmd);
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index ed561aa..d751fc1 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -960,6 +960,19 @@
 		exit(1);
 	}
 
+	if (bsc_gsmnet->neigh_ctrl.addr) {
+		bsc_gsmnet->neigh_ctrl.handle = neighbor_controlif_setup(bsc_gsmnet);
+		if (!bsc_gsmnet->neigh_ctrl.handle) {
+			fprintf(stderr, "Failed to bind Neighbor Resolution Service. Exiting.\n");
+			exit(1);
+		}
+		rc = neighbor_ctrl_cmds_install(bsc_gsmnet);
+		if (rc < 0) {
+			fprintf(stderr, "Failed to install Neighbor Resolution Service commands. Exiting.\n");
+			exit(1);
+		}
+	}
+
 	if (rf_ctrl)
 		osmo_talloc_replace_string(bsc_gsmnet, &bsc_gsmnet->rf_ctrl_name, rf_ctrl);
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b11b905..6bc7839 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -41,6 +41,7 @@
 	osmo-bsc.vty \
 	timer.vty \
 	power_ctrl.vty \
+	ctrl/osmo-bsc-neigh-test.cfg \
 	$(NULL)
 
 TESTSUITE = $(srcdir)/testsuite
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index b6ba421..2cc57a4 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -8,6 +8,7 @@
 	-ggdb3 \
 	$(LIBOSMOCORE_CFLAGS) \
 	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOCTRL_CFLAGS) \
 	$(LIBOSMOABIS_CFLAGS) \
 	$(LIBOSMOLEGACYMGCP_CFLAGS) \
 	$(LIBOSMOSIGTRAN_CFLAGS) \
@@ -59,6 +60,7 @@
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
 	$(LIBOSMOVTY_LIBS) \
+	$(LIBOSMOCTRL_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
 	$(LIBOSMOLEGACYMGCP_LIBS) \
 	$(LIBRARY_GSM) \
diff --git a/tests/ctrl/osmo-bsc-neigh-test.cfg b/tests/ctrl/osmo-bsc-neigh-test.cfg
new file mode 100644
index 0000000..f1e71b6
--- /dev/null
+++ b/tests/ctrl/osmo-bsc-neigh-test.cfg
@@ -0,0 +1,97 @@
+! osmo-bsc default configuration
+! (assumes STP to run on 127.0.0.1 and uses default point codes)
+!
+log file /tmp/osmo-bsc-neigh.log
+ logging filter all 1
+ logging color 1
+ logging print category 1
+ logging timestamp 1
+ logging level set-all debug
+e1_input
+ e1_line 0 driver ipa
+network
+ network country code 1
+ mobile network code 1
+ encryption a5 0
+ neci 1
+ paging any use tch 0
+ handover 0
+ handover algorithm 1
+ handover1 window rxlev averaging 10
+ handover1 window rxqual averaging 1
+ handover1 window rxlev neighbor averaging 10
+ handover1 power budget interval 6
+ handover1 power budget hysteresis 3
+ handover1 maximum distance 9999
+ periodic location update 30
+ neighbor-resolution bind 127.0.0.1
+ bts 0
+  type sysmobts
+  band DCS1800
+  cell_identity 6969
+  location_area_code 1
+  base_station_id_code 63
+  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 6969 0
+  oml ipa stream-id 255 line 0
+  codec-support fr
+  gprs mode gprs
+  neighbor cgi-ps 23 42 423 2 5 arfcn 23 bsic 32
+  trx 0
+   rf_locked 0
+   arfcn 871
+   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
+msc 0
+ type normal
+ allow-emergency allow
+ amr-config 12_2k forbidden
+ amr-config 10_2k forbidden
+ amr-config 7_95k forbidden
+ amr-config 7_40k forbidden
+ amr-config 6_70k forbidden
+ amr-config 5_90k allowed
+ amr-config 5_15k forbidden
+ amr-config 4_75k forbidden
+ mgw remote-ip 127.0.0.1
+ mgw remote-port 2427
+ mgw local-port 2727
+ mgw endpoint-range 1 31
+bsc
+ mid-call-timeout 0
diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py
index 5d2af85..fb983c9 100755
--- a/tests/ctrl_test_runner.py
+++ b/tests/ctrl_test_runner.py
@@ -488,11 +488,34 @@
         self.assertEqual(r['var'], 'mcc')
         self.assertEqual(r['value'], '002')
 
-def add_bsc_test(suite, workdir):
+class TestCtrlBSCNeighbor(TestCtrlBase):
+
+    def tearDown(self):
+        TestCtrlBase.tearDown(self)
+        os.unlink("tmp_dummy_sock")
+
+    def ctrl_command(self):
+        return ["./src/osmo-bsc/osmo-bsc", "-r", "tmp_dummy_sock", "-c",
+                "tests/ctrl/osmo-bsc-neigh-test.cfg"]
+
+    def ctrl_app(self):
+        return (4248, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")
+
+    def testCtrlNeighborResolution(self):
+        r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci')
+        self.assertEqual(r['mtype'], 'ERROR')
+        self.assertEqual(r['error'], 'The format is <src_lac>,<src_cell_id>,<dst_arfcn>,<dst_bsic>')
+
+        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')
+        self.assertEqual(r['value'], '023-42-423-2-5')
+
+def add_bsc_test(suite, workdir, klass):
     if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
         print("Skipping the BSC test")
         return
-    test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlBSC)
+    test = unittest.TestLoader().loadTestsFromTestCase(klass)
     suite.addTest(test)
 
 if __name__ == '__main__':
@@ -525,6 +548,7 @@
     os.chdir(workdir)
     print("Running tests for specific control commands")
     suite = unittest.TestSuite()
-    add_bsc_test(suite, workdir)
+    add_bsc_test(suite, workdir, TestCtrlBSC)
+    add_bsc_test(suite, workdir, TestCtrlBSCNeighbor)
     res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
     sys.exit(len(res.errors) + len(res.failures))
diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am
index a00da46..571e7e6 100644
--- a/tests/gsm0408/Makefile.am
+++ b/tests/gsm0408/Makefile.am
@@ -7,6 +7,7 @@
 	-Wall \
 	$(LIBOSMOCORE_CFLAGS) \
 	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOCTRL_CFLAGS) \
 	$(LIBOSMOABIS_CFLAGS) \
 	$(NULL)
 
@@ -46,5 +47,6 @@
 	$(top_builddir)/src/osmo-bsc/nm_rcarrier_fsm.o \
 	$(LIBOSMOCORE_LIBS) \
 	$(LIBOSMOGSM_LIBS) \
+	$(LIBOSMOCTRL_LIBS) \
 	$(LIBOSMOABIS_LIBS) \
 	$(NULL)
diff --git a/tests/neighbor_ident.vty b/tests/neighbor_ident.vty
index ce414e1..93571b7 100644
--- a/tests/neighbor_ident.vty
+++ b/tests/neighbor_ident.vty
@@ -14,6 +14,10 @@
 OsmoBSC# configure terminal
 OsmoBSC(config)# network
 
+
+OsmoBSC(config-net)# neighbor-resolution bind 1.2.3.4 ?
+  [<0-65535>]  Port to bind the service to [defaults to 4248 if not provided]
+
 OsmoBSC(config-net)# bts 0
 OsmoBSC(config-net-bts)# type sysmobts
 OsmoBSC(config-net-bts)# base_station_id_code 10
@@ -84,9 +88,11 @@
   neighbor lac <0-65535>
   neighbor lac-ci <0-65535> <0-65535>
   neighbor cgi <0-999> <0-999> <0-65535> <0-65535>
+  neighbor cgi-ps <0-999> <0-999> <0-65535> <0-255> <0-65535>
   neighbor lac <0-65535> arfcn <0-1023> bsic (<0-63>|any)
   neighbor lac-ci <0-65535> <0-65535> arfcn <0-1023> bsic (<0-63>|any)
   neighbor cgi <0-999> <0-999> <0-65535> <0-65535> arfcn <0-1023> bsic (<0-63>|any)
+  neighbor cgi-ps <0-999> <0-999> <0-65535> <0-255> <0-65535> arfcn <0-1023> bsic (<0-63>|any)
   no neighbor bts <0-255>
   no neighbor arfcn <0-1023> bsic (<0-63>|any)
   no neighbors
@@ -100,6 +106,7 @@
   lac     Add Neighbor cell by LAC
   lac-ci  Add Neighbor cell by LAC and CI
   cgi     Add Neighbor cell by cgi
+  cgi-ps  Add Neighbor cell by cgi (Packet Switched, with RAC)
 
 OsmoBSC(config-net-bts)# neighbor bts ?
   <0-255>  BTS number
@@ -348,12 +355,16 @@
 OsmoBSC(config-net-bts)# neighbor lac-ci 789 10 arfcn 423 bsic any
 % BTS 0 to ARFCN 423 (any BSIC) now has 1 remote BSS Cell Identifier List entry
 
+OsmoBSC(config-net-bts)# neighbor cgi-ps 23 42 423 2 5 arfcn 23 bsic 32
+% BTS 0 to ARFCN 23 BSIC 32 now has 1 remote BSS Cell Identifier List entry
+
 OsmoBSC(config-net-bts)# no neighbors
 % Removed local neighbor bts 0 to bts 1
 % Removed local neighbor bts 0 to bts 2
 % Removed remote BSS neighbor BTS 0 to ARFCN 23 BSIC 42
 % Removed remote BSS neighbor BTS 0 to ARFCN 123 BSIC 45
 % Removed remote BSS neighbor BTS 0 to ARFCN 423 (any BSIC)
+% Removed remote BSS neighbor BTS 0 to ARFCN 23 BSIC 32
 
 OsmoBSC(config-net-bts)# show running-config
 ... !neighbor 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/21848
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Ib07c9d23026332a207d4b7a0f7b4e76c0094e379
Gerrit-Change-Number: 21848
Gerrit-PatchSet: 9
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210113/ae6a597f/attachment.htm>


More information about the gerrit-log mailing list