diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/abis_osmo.c | 69 | ||||
-rw-r--r-- | src/osmo-bsc/neighbor_ident.c | 97 | ||||
-rw-r--r-- | src/osmo-bsc/neighbor_ident_vty.c | 4 |
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]); |