aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/osmo-bsc/abis_osmo.c69
-rw-r--r--src/osmo-bsc/neighbor_ident.c97
-rw-r--r--src/osmo-bsc/neighbor_ident_vty.c4
3 files changed, 128 insertions, 42 deletions
diff --git a/src/osmo-bsc/abis_osmo.c b/src/osmo-bsc/abis_osmo.c
index 39caac6df..48774b4e8 100644
--- a/src/osmo-bsc/abis_osmo.c
+++ b/src/osmo-bsc/abis_osmo.c
@@ -32,6 +32,7 @@
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/pcuif_proto.h>
+#include <osmocom/bsc/neighbor_ident.h>
#define OM_HEADROOM_SIZE 128
@@ -40,7 +41,6 @@
///////////////////////////////////////
#define PCUIF_HDR_SIZE ( sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u) )
-#if 0
static struct msgb *abis_osmo_pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr, size_t extra_size)
{
struct msgb *msg;
@@ -62,7 +62,65 @@ static int abis_osmo_pcu_sendmsg(struct gsm_bts *bts, struct msgb *msg)
ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_PCU);
return abis_osmo_sendmsg(bts, msg);
}
-#endif
+
+static int abis_osmo_pcu_tx_neigh_addr_cnf(struct gsm_bts *bts, const struct gsm_pcu_if_neigh_addr_req *naddr_req,
+ uint8_t err_code, const struct osmo_cell_global_id_ps *cgi_ps)
+{
+ struct msgb *msg = abis_osmo_pcu_msgb_alloc(PCU_IF_MSG_CONTAINER, bts->bts_nr, sizeof(struct gsm_pcu_if_neigh_addr_cnf));
+ struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
+ struct gsm_pcu_if_neigh_addr_cnf *naddr_cnf = (struct gsm_pcu_if_neigh_addr_cnf *)&pcu_prim->u.container.data[0];
+
+ msgb_put(msg, sizeof(pcu_prim->u.container) + sizeof(struct gsm_pcu_if_neigh_addr_cnf));
+ pcu_prim->u.container.msg_type = PCU_IF_MSG_NEIGH_ADDR_CNF;
+ osmo_store16be(sizeof(struct gsm_pcu_if_neigh_addr_cnf), &pcu_prim->u.container.length);
+
+ naddr_cnf->orig_req = *naddr_req;
+ naddr_cnf->err_code = err_code;
+ if (err_code == 0) {
+ osmo_store16be(cgi_ps->rai.lac.plmn.mcc, &naddr_cnf->cgi_ps.mcc);
+ osmo_store16be(cgi_ps->rai.lac.plmn.mnc, &naddr_cnf->cgi_ps.mnc);
+ naddr_cnf->cgi_ps.mnc_3_digits = cgi_ps->rai.lac.plmn.mnc_3_digits;
+ osmo_store16be(cgi_ps->rai.lac.lac, &naddr_cnf->cgi_ps.lac);
+ naddr_cnf->cgi_ps.rac = cgi_ps->rai.rac;
+ osmo_store16be(cgi_ps->cell_identity, &naddr_cnf->cgi_ps.cell_identity);
+ }
+
+ return abis_osmo_pcu_sendmsg(bts, msg);
+}
+
+static int rcvmsg_pcu_neigh_addr_req(struct gsm_bts *bts, const struct gsm_pcu_if_neigh_addr_req *naddr_req)
+{
+
+ struct cell_ab ab;
+ uint16_t local_lac, local_ci;
+ struct osmo_cell_global_id_ps cgi_ps;
+ int rc;
+
+ local_lac = osmo_load16be(&naddr_req->local_lac);
+ local_ci = osmo_load16be(&naddr_req->local_ci);
+ ab = (struct cell_ab){
+ .arfcn = osmo_load16be(&naddr_req->tgt_arfcn),
+ .bsic = naddr_req->tgt_bsic,
+ };
+
+ LOGP(DNM, LOGL_INFO, "(bts=%d) Rx Neighbor Address Resolution Req (ARFCN=%u,BSIC=%u) from (LAC=%u,CI=%u)\n",
+ bts->nr, ab.arfcn, ab.bsic, local_lac, local_ci);
+
+ if (!cell_ab_valid(&ab)) {
+ rc = 2;
+ goto do_fail;
+ }
+
+ if (neighbor_address_resolution(bts->network, &ab, local_lac, local_ci, &cgi_ps) < 0) {
+ rc = 1;
+ goto do_fail;
+ }
+ return abis_osmo_pcu_tx_neigh_addr_cnf(bts, naddr_req, 0, &cgi_ps);
+
+do_fail:
+ return abis_osmo_pcu_tx_neigh_addr_cnf(bts, naddr_req, rc, NULL);
+}
+
static int rcvmsg_pcu_container(struct gsm_bts *bts, struct gsm_pcu_if_container *container, size_t container_len)
{
@@ -79,6 +137,13 @@ static int rcvmsg_pcu_container(struct gsm_bts *bts, struct gsm_pcu_if_container
bts->nr, container->msg_type);
switch (container->msg_type) {
+ case PCU_IF_MSG_NEIGH_ADDR_REQ:
+ if (data_length < sizeof(struct gsm_pcu_if_neigh_addr_req)) {
+ LOGP(DNM, LOGL_ERROR, "ABIS_OSMO_PCU CONTAINER ANR_CNF message too short\n");
+ return -EINVAL;
+ }
+ rc = rcvmsg_pcu_neigh_addr_req(bts, (struct gsm_pcu_if_neigh_addr_req *)&container->data);
+ break;
default:
LOGP(DNM, LOGL_NOTICE, "(bts=%d) Rx ABIS_OSMO_PCU unexpected msg type (%u) inside container!\n",
bts->nr, container->msg_type);
diff --git a/src/osmo-bsc/neighbor_ident.c b/src/osmo-bsc/neighbor_ident.c
index 6e706258d..c66d3ac55 100644
--- a/src/osmo-bsc/neighbor_ident.c
+++ b/src/osmo-bsc/neighbor_ident.c
@@ -366,47 +366,17 @@ static int gsm_bts_get_cgi_ps(const struct gsm_bts *bts, struct osmo_cell_global
return 0;
}
-static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *data)
+/* Attempt resolution of cgi_ps from ARFCN+BSIC of neighbor from BTS identified by LAC+CI */
+int neighbor_address_resolution(const struct gsm_network *net, const struct cell_ab *ab,
+ uint16_t lac, uint16_t cell_id,
+ struct osmo_cell_global_id_ps *res_cgi_ps)
{
- struct gsm_network *net = (struct gsm_network *)data;
struct gsm_bts *bts_tmp, *bts_found = NULL;
- char *tmp = NULL, *tok, *saveptr;
- struct cell_ab ab;
- unsigned lac, cell_id;
struct osmo_cell_global_id_ps local_cgi_ps;
const struct osmo_cell_global_id_ps *cgi_ps = NULL;
struct gsm_bts *local_neighbor = NULL;
struct gsm0808_cell_id_list2 remote_neighbors = { 0 };
- 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;
- ab.arfcn = atoi(tok);
-
- if (!(tok = strtok_r(NULL, "\0", &saveptr)))
- goto fmt_err;
- ab.bsic = atoi(tok);
-
llist_for_each_entry(bts_tmp, &net->bts_list, list) {
if (bts_tmp->location_area_code != lac)
continue;
@@ -420,12 +390,9 @@ static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *d
goto notfound_err;
LOG_BTS(bts_found, DLINP, LOGL_DEBUG, "Resolving neighbor BTS %u -> %s\n", bts_found->nr,
- cell_ab_to_str_c(OTC_SELECT, &ab));
-
- if (!cell_ab_valid(&ab))
- goto fmt_err;
+ cell_ab_to_str_c(OTC_SELECT, ab));
- if (resolve_neighbors(&local_neighbor, &remote_neighbors, bts_found, &ab, true))
+ if (resolve_neighbors(&local_neighbor, &remote_neighbors, bts_found, ab, true))
goto notfound_err;
/* resolve_neighbors() returns either a local_neighbor or remote_neighbors.
@@ -448,7 +415,57 @@ static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *d
if (!cgi_ps)
goto notfound_err;
- ctrl_cmd_reply_printf(cmd, "%s", osmo_cgi_ps_name(cgi_ps));
+ *res_cgi_ps = *cgi_ps;
+ return 0;
+
+notfound_err:
+ return -1;
+}
+
+static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *data)
+{
+ struct gsm_network *net = (struct gsm_network *)data;
+ char *tmp = NULL, *tok, *saveptr;
+ struct cell_ab ab;
+ unsigned int lac, cell_id;
+ 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;
+ ab.arfcn = atoi(tok);
+
+ if (!(tok = strtok_r(NULL, "\0", &saveptr)))
+ goto fmt_err;
+ ab.bsic = atoi(tok);
+
+ if (!cell_ab_valid(&ab))
+ goto fmt_err;
+
+ if (neighbor_address_resolution(net, &ab, lac, cell_id, &cgi_ps) < 0)
+ goto notfound_err;
+
+ ctrl_cmd_reply_printf(cmd, "%s", osmo_cgi_ps_name(&cgi_ps));
talloc_free(tmp);
return CTRL_CMD_REPLY;
diff --git a/src/osmo-bsc/neighbor_ident_vty.c b/src/osmo-bsc/neighbor_ident_vty.c
index b9160ec67..b500b34a4 100644
--- a/src/osmo-bsc/neighbor_ident_vty.c
+++ b/src/osmo-bsc/neighbor_ident_vty.c
@@ -481,6 +481,10 @@ DEFUN(cfg_neighbor_bind, cfg_neighbor_bind_cmd,
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")
{
+ vty_out(vty, "%% Warning: The CTRL interface for Neighbor Address Resolution is now deprecated."
+ "Upgrade osmo-pcu and drop the 'neighbor-resolution bind " VTY_IPV46_CMD " [<0-65535>]' VTY "
+ "option in order to let osmo-pcu use the new resoluton method using the PCUIF over IPA "
+ "multiplex, which will work out of the box without required configuration.%s", VTY_NEWLINE);
osmo_talloc_replace_string(bsc_gsmnet, &bsc_gsmnet->neigh_ctrl.addr, argv[0]);
if (argc > 1)
bsc_gsmnet->neigh_ctrl.port = atoi(argv[1]);