<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21848">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">WIP: Introduce Neigbhour resolution service<br><br>Change-Id: Ib07c9d23026332a207d4b7a0f7b4e76c0094e379<br>---<br>M include/osmocom/bsc/gsm_data.h<br>M include/osmocom/bsc/neighbor_ident.h<br>M src/osmo-bsc/bsc_vty.c<br>M src/osmo-bsc/bts.c<br>M src/osmo-bsc/neighbor_ident.c<br>M src/osmo-bsc/neighbor_ident_vty.c<br>M src/osmo-bsc/osmo_bsc_main.c<br>M tests/bsc/Makefile.am<br>A tests/ctrl/osmo-bsc-neigh-test.cfg<br>M tests/ctrl_test_runner.py<br>M tests/gsm0408/Makefile.am<br>M tests/neighbor_ident.vty<br>12 files changed, 373 insertions(+), 6 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/48/21848/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index 233c3b6..35e8545 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -1213,6 +1213,10 @@</span><br><span> </span><br><span>       /* Remote BSS Cell Identifier Lists */</span><br><span>       struct neighbor_ident_list *neighbor_bss_cells;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Remote BSS resolution sevice (CTRL iface) */</span><br><span style="color: hsl(120, 100%, 40%);">+       char *neigh_ctrl_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint16_t neigh_ctrl_port;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ctrl_handle *neigh_ctrl;</span><br><span> </span><br><span>  /* Don't refuse to start with mutually exclusive codec settings */</span><br><span>       bool allow_unusable_timeslots;</span><br><span>diff --git a/include/osmocom/bsc/neighbor_ident.h b/include/osmocom/bsc/neighbor_ident.h</span><br><span>index aa38276..c5b8e42 100644</span><br><span>--- a/include/osmocom/bsc/neighbor_ident.h</span><br><span>+++ b/include/osmocom/bsc/neighbor_ident.h</span><br><span>@@ -45,7 +45,8 @@</span><br><span>                       void *cb_data);</span><br><span> </span><br><span> void neighbor_ident_vty_init(struct gsm_network *net, struct neighbor_ident_list *nil);</span><br><span style="color: hsl(0, 100%, 40%);">-void neighbor_ident_vty_write(struct vty *vty, const char *indent, struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void neighbor_ident_vty_write_bts(struct vty *vty, const char *indent, struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+void neighbor_ident_vty_write_network(struct vty *vty, const char *indent);</span><br><span> </span><br><span> bool neighbor_ident_bts_entry_exists(uint8_t from_bts);</span><br><span> </span><br><span>@@ -58,3 +59,13 @@</span><br><span>                                    struct neighbor_ident_key *key);</span><br><span> bool neighbor_ident_bts_parse_key_params(struct vty *vty, struct gsm_bts *bts, const char **argv,</span><br><span>                                        struct neighbor_ident_key *key);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ctrl/control_cmd.h></span><br><span style="color: hsl(120, 100%, 40%);">+struct ctrl_handle *neighbor_controlif_setup(struct gsm_network *net);</span><br><span style="color: hsl(120, 100%, 40%);">+int neighbor_ctrl_cmds_install(struct gsm_network *net);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum neighbor_ctrl_node {</span><br><span style="color: hsl(120, 100%, 40%);">+     CTRL_NODE_NEIGH = _LAST_CTRL_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+    _LAST_CTRL_NIDE_NEIGHBOR</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span>diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c</span><br><span>index fe46d45..a750317 100644</span><br><span>--- a/src/osmo-bsc/bsc_vty.c</span><br><span>+++ b/src/osmo-bsc/bsc_vty.c</span><br><span>@@ -1175,7 +1175,7 @@</span><br><span>                    VTY_NEWLINE);</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   neighbor_ident_vty_write(vty, "  ", bts);</span><br><span style="color: hsl(120, 100%, 40%);">+   neighbor_ident_vty_write_bts(vty, "  ", bts);</span><br><span> </span><br><span>  vty_out(vty, "  codec-support fr");</span><br><span>        if (bts->codec.hr)</span><br><span>@@ -1315,6 +1315,8 @@</span><br><span>                vty_out(vty, "%s", VTY_NEWLINE);</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ neighbor_ident_vty_write_network(vty, " ");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c</span><br><span>index d5a848d..5819633 100644</span><br><span>--- a/src/osmo-bsc/bts.c</span><br><span>+++ b/src/osmo-bsc/bts.c</span><br><span>@@ -388,6 +388,10 @@</span><br><span>     case CELL_IDENT_WHOLE_GLOBAL:</span><br><span>                return gsm_bts_matches_lai(bts, &id->global.lai)</span><br><span>                      && id->global.cell_identity == bts->cell_identity;</span><br><span style="color: hsl(120, 100%, 40%);">+      case CELL_IDENT_WHOLE_GLOBAL_PS:</span><br><span style="color: hsl(120, 100%, 40%);">+              return gsm_bts_matches_lai(bts, &id->global_ps.rai.lac)</span><br><span style="color: hsl(120, 100%, 40%);">+                        && id->global_ps.rai.rac == bts->gprs.rac</span><br><span style="color: hsl(120, 100%, 40%);">+                       && id->global_ps.cell_identity == bts->cell_identity;</span><br><span>  case CELL_IDENT_LAC_AND_CI:</span><br><span>          return id->lac_and_ci.lac == bts->location_area_code</span><br><span>                   && id->lac_and_ci.ci == bts->cell_identity;</span><br><span>diff --git a/src/osmo-bsc/neighbor_ident.c b/src/osmo-bsc/neighbor_ident.c</span><br><span>index 4a0cd47..24709b2 100644</span><br><span>--- a/src/osmo-bsc/neighbor_ident.c</span><br><span>+++ b/src/osmo-bsc/neighbor_ident.c</span><br><span>@@ -33,6 +33,13 @@</span><br><span> </span><br><span> #include <osmocom/bsc/neighbor_ident.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ctrl/control_cmd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ctrl/control_if.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/gsm_data.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bts.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct neighbor_ident_list {</span><br><span>     struct llist_head list;</span><br><span> };</span><br><span>@@ -253,3 +260,107 @@</span><br><span>                        return;</span><br><span>      }</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Neighbor Resolution CTRL iface */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+CTRL_CMD_DEFINE_RO(neighbor_resolve_cgi_ps_from_lac_ci, "neighbor_resolve_cgi_ps_from_lac_ci");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_neighbor_resolve_cgi_ps_from_lac_ci(struct ctrl_cmd *cmd, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_network *net = (struct gsm_network *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts *bts_tmp, *bts_found = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct gsm0808_cell_id_list2 *tgt_cell_li = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       char *tmp = NULL, *tok, *saveptr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct neighbor_ident_key ni;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned lac, cell_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        const struct osmo_cell_global_id_ps *cgi_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        //LOGP(DLINP, LOGL_DEBUG, "get_neighbor_resolve_rai_by_lac_ci called: %s\n", cmd->variable);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!cmd->variable)</span><br><span style="color: hsl(120, 100%, 40%);">+                goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       tmp = talloc_strdup(cmd, cmd->variable);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!tmp)</span><br><span style="color: hsl(120, 100%, 40%);">+             goto oom;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!(tok = strtok_r(tmp, ".", &saveptr)))</span><br><span style="color: hsl(120, 100%, 40%);">+              goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(strcmp(tok, "neighbor_resolve_cgi_ps_from_lac_ci") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(tok = strtok_r(NULL, ".", &saveptr)))</span><br><span style="color: hsl(120, 100%, 40%);">+             goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ lac = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!(tok = strtok_r(NULL, ".", &saveptr)))</span><br><span style="color: hsl(120, 100%, 40%);">+             goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ cell_id = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!(tok = strtok_r(NULL, ".", &saveptr)))</span><br><span style="color: hsl(120, 100%, 40%);">+             goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ ni.arfcn = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!(tok = strtok_r(NULL, "\0", &saveptr)))</span><br><span style="color: hsl(120, 100%, 40%);">+            goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ ni.bsic = atoi(tok);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        //LOGP(DLINP, LOGL_DEBUG, "lac=%u cell_id=%u arfcn=%u bsic=%u\n", lac, cell_id, ni.arfcn, ni.bsic);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ni.from_bts = NEIGHBOR_IDENT_KEY_ANY_BTS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   llist_for_each_entry(bts_tmp, &net->bts_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (bts_tmp->location_area_code != lac)</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (bts_tmp->cell_identity != cell_id)</span><br><span style="color: hsl(120, 100%, 40%);">+                     continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             bts_found = bts_tmp;</span><br><span style="color: hsl(120, 100%, 40%);">+          ni.from_bts = bts_tmp->nr;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!bts_found)</span><br><span style="color: hsl(120, 100%, 40%);">+               goto notfound_err;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  LOG_BTS(bts_found, DLINP, LOGL_DEBUG, "Resolving neigbhor arfcn=%u bsic=%u\n", ni.arfcn, ni.bsic);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!neighbor_ident_key_valid(&ni))</span><br><span style="color: hsl(120, 100%, 40%);">+               goto fmt_err;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       tgt_cell_li = neighbor_ident_get(net->neighbor_bss_cells, &ni);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!tgt_cell_li || tgt_cell_li->id_discr != CELL_IDENT_WHOLE_GLOBAL_PS || tgt_cell_li->id_list_len < 1)</span><br><span style="color: hsl(120, 100%, 40%);">+             goto notfound_err;</span><br><span style="color: hsl(120, 100%, 40%);">+    cgi_ps = &tgt_cell_li->id_list[0].global_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ctrl_cmd_reply_printf(cmd, "%u,%u,%u,%u,%u", cgi_ps->rai.lac.plmn.mcc,</span><br><span style="color: hsl(120, 100%, 40%);">+                         cgi_ps->rai.lac.plmn.mnc,</span><br><span style="color: hsl(120, 100%, 40%);">+                          cgi_ps->rai.lac.lac, cgi_ps->rai.rac,</span><br><span style="color: hsl(120, 100%, 40%);">+                           cgi_ps->cell_identity);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return CTRL_CMD_REPLY;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+notfound_err:</span><br><span style="color: hsl(120, 100%, 40%);">+       talloc_free(tmp);</span><br><span style="color: hsl(120, 100%, 40%);">+     cmd->reply = talloc_strdup(cmd, "No target CGI PS found");</span><br><span style="color: hsl(120, 100%, 40%);">+       return CTRL_CMD_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+fmt_err:</span><br><span style="color: hsl(120, 100%, 40%);">+      talloc_free(tmp);</span><br><span style="color: hsl(120, 100%, 40%);">+     cmd->reply = talloc_strdup(cmd, "The format is <src_lac>,<src_cell_id>,<dst_arfcn>,<dst_bsic>");</span><br><span style="color: hsl(120, 100%, 40%);">+ return CTRL_CMD_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+oom:</span><br><span style="color: hsl(120, 100%, 40%);">+  cmd->reply = "OOM";</span><br><span style="color: hsl(120, 100%, 40%);">+      return CTRL_CMD_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int neighbor_ctrl_cmds_install(struct gsm_network *net)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_neighbor_resolve_cgi_ps_from_lac_ci);</span><br><span style="color: hsl(120, 100%, 40%);">+  return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ctrl_handle *neighbor_controlif_setup(struct gsm_network *net)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return ctrl_interface_setup_dynip2(net, net->neigh_ctrl_addr, net->neigh_ctrl_port,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        NULL, _LAST_CTRL_NIDE_NEIGHBOR);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/osmo-bsc/neighbor_ident_vty.c b/src/osmo-bsc/neighbor_ident_vty.c</span><br><span>index 7feed2a..49b740c 100644</span><br><span>--- a/src/osmo-bsc/neighbor_ident_vty.c</span><br><span>+++ b/src/osmo-bsc/neighbor_ident_vty.c</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <stdlib.h></span><br><span> #include <string.h></span><br><span> #include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span> </span><br><span> #include <osmocom/vty/command.h></span><br><span> #include <osmocom/gsm/gsm0808.h></span><br><span>@@ -84,6 +85,9 @@</span><br><span> #define CGI_PARAMS "cgi <0-999> <0-999> <0-65535> <0-65535>"</span><br><span> #define CGI_DOC "Neighbor cell by cgi\n" "MCC\n" "MNC\n" "LAC\n" "CI\n"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define CGI_PS_PARAMS "cgi-ps <0-999> <0-999> <0-65535> <0-255> <0-65535>"</span><br><span style="color: hsl(120, 100%, 40%);">+#define CGI_PS_DOC "Neighbor cell by cgi (Packet Switch, with RAC)\n" "MCC\n" "MNC\n" "LAC\n" "RAC\n" "CI\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define LOCAL_BTS_PARAMS "bts <0-255>"</span><br><span> #define LOCAL_BTS_DOC "Neighbor cell by local BTS number\n" "BTS number\n"</span><br><span> </span><br><span>@@ -154,6 +158,35 @@</span><br><span>         return &cell_id;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm0808_cell_id *neighbor_ident_vty_parse_cgi_ps(struct vty *vty, const char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  static struct gsm0808_cell_id cell_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        cell_id = (struct gsm0808_cell_id){</span><br><span style="color: hsl(120, 100%, 40%);">+           .id_discr = CELL_IDENT_WHOLE_GLOBAL_PS,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_cell_global_id_ps *cgi_ps = &cell_id.id.global_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *mcc = argv[0];</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *mnc = argv[1];</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *lac = argv[2];</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *rac = argv[3];</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *ci = argv[4];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_mcc_from_str(mcc, &cgi_ps->rai.lac.plmn.mcc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               vty_out(vty, "%% Error decoding MCC: %s%s", mcc, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_mnc_from_str(mnc, &cgi_ps->rai.lac.plmn.mnc, &cgi_ps->rai.lac.plmn.mnc_3_digits)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            vty_out(vty, "%% Error decoding MNC: %s%s", mnc, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   cgi_ps->rai.lac.lac = atoi(lac);</span><br><span style="color: hsl(120, 100%, 40%);">+   cgi_ps->rai.rac = atoi(rac);</span><br><span style="color: hsl(120, 100%, 40%);">+       cgi_ps->cell_identity = atoi(ci);</span><br><span style="color: hsl(120, 100%, 40%);">+  return &cell_id;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int add_local_bts(struct vty *vty, struct gsm_bts *neigh)</span><br><span> {</span><br><span>   int rc;</span><br><span>@@ -246,6 +279,13 @@</span><br><span>       return add_local_bts(vty, bts_by_cell_id(vty, neighbor_ident_vty_parse_cgi(vty, argv)));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_neighbor_add_cgi_ps, cfg_neighbor_add_cgi_ps_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+        NEIGHBOR_ADD_CMD CGI_PS_PARAMS,</span><br><span style="color: hsl(120, 100%, 40%);">+       NEIGHBOR_ADD_DOC CGI_PS_DOC)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return add_local_bts(vty, bts_by_cell_id(vty, neighbor_ident_vty_parse_cgi_ps(vty, argv)));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bool neighbor_ident_key_matches_bts(const struct neighbor_ident_key *key, struct gsm_bts *bts)</span><br><span> {</span><br><span>      if (!bts || !key)</span><br><span>@@ -497,6 +537,19 @@</span><br><span>     return add_remote_or_local_bts(vty, cell_id, &nik);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_neighbor_add_cgi_ps_arfcn_bsic, cfg_neighbor_add_cgi_ps_arfcn_bsic_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+   NEIGHBOR_ADD_CMD CGI_PS_PARAMS " " NEIGHBOR_IDENT_VTY_KEY_PARAMS,</span><br><span style="color: hsl(120, 100%, 40%);">+   NEIGHBOR_ADD_DOC CGI_PS_DOC NEIGHBOR_IDENT_VTY_KEY_DOC)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct neighbor_ident_key nik;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm0808_cell_id *cell_id = neighbor_ident_vty_parse_cgi_ps(vty, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!cell_id)</span><br><span style="color: hsl(120, 100%, 40%);">+         return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!neighbor_ident_vty_parse_key_params(vty, argv + 5, &nik))</span><br><span style="color: hsl(120, 100%, 40%);">+            return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   return add_remote_or_local_bts(vty, cell_id, &nik);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> DEFUN(cfg_neighbor_del_bts_nr, cfg_neighbor_del_bts_nr_cmd,</span><br><span>  NEIGHBOR_DEL_CMD LOCAL_BTS_PARAMS,</span><br><span>   NEIGHBOR_DEL_DOC LOCAL_BTS_DOC)</span><br><span>@@ -525,6 +578,25 @@</span><br><span>       return neighbor_del_all(vty);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_neighbor_bind, cfg_neighbor_bind_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+       "neighbor bind " VTY_IPV46_CMD " <0-65535>",</span><br><span style="color: hsl(120, 100%, 40%);">+        NEIGHBOR_DOC "Bind Neighbor Resolution Service (CTRL interface) to given ip and port\n"</span><br><span style="color: hsl(120, 100%, 40%);">+     "IPv4 address to bind the service to\n" "IPv6 address to bind the service to\n"</span><br><span style="color: hsl(120, 100%, 40%);">+   "Port to bind the service to\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_talloc_replace_string(g_net, &g_net->neigh_ctrl_addr, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+   g_net->neigh_ctrl_port = atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void neighbor_ident_vty_write_network(struct vty *vty, const char *indent)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (g_net->neigh_ctrl_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "%sneighbor bind %s %" PRIu16 "%s", indent, g_net->neigh_ctrl_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                       g_net->neigh_ctrl_port, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct write_neighbor_ident_entry_data {</span><br><span>  struct vty *vty;</span><br><span>     const char *indent;</span><br><span>@@ -576,6 +648,16 @@</span><br><span>                                   cgi->lai.lac, cgi->cell_identity);</span><br><span>             }</span><br><span>            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case CELL_IDENT_WHOLE_GLOBAL_PS:</span><br><span style="color: hsl(120, 100%, 40%);">+              for (i = 0; i < val->id_list_len; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        const struct osmo_cell_global_id_ps *cgi_ps = &val->id_list[i].global_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+                      NEIGH_BSS_WRITE("cgi-ps %s %s %u %u %u",</span><br><span style="color: hsl(120, 100%, 40%);">+                                    osmo_mcc_name(cgi_ps->rai.lac.plmn.mcc),</span><br><span style="color: hsl(120, 100%, 40%);">+                                   osmo_mnc_name(cgi_ps->rai.lac.plmn.mnc, cgi_ps->rai.lac.plmn.mnc_3_digits),</span><br><span style="color: hsl(120, 100%, 40%);">+                                     cgi_ps->rai.lac.lac, cgi_ps->rai.rac,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   cgi_ps->cell_identity);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span>       default:</span><br><span>             vty_out(vty, "%% Unsupported Cell Identity%s", VTY_NEWLINE);</span><br><span>       }</span><br><span>@@ -604,7 +686,7 @@</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void neighbor_ident_vty_write(struct vty *vty, const char *indent, struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+void neighbor_ident_vty_write_bts(struct vty *vty, const char *indent, struct gsm_bts *bts)</span><br><span> {</span><br><span>  neighbor_ident_vty_write_local_neighbors(vty, indent, bts);</span><br><span>  neighbor_ident_vty_write_remote_bss(vty, indent, bts);</span><br><span>@@ -662,13 +744,17 @@</span><br><span> {</span><br><span>  g_net = net;</span><br><span>         g_neighbor_cells = nil;</span><br><span style="color: hsl(120, 100%, 40%);">+       install_element(GSMNET_NODE, &cfg_neighbor_bind_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  install_element(BTS_NODE, &cfg_neighbor_add_bts_nr_cmd);</span><br><span>         install_element(BTS_NODE, &cfg_neighbor_add_lac_cmd);</span><br><span>    install_element(BTS_NODE, &cfg_neighbor_add_lac_ci_cmd);</span><br><span>         install_element(BTS_NODE, &cfg_neighbor_add_cgi_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(BTS_NODE, &cfg_neighbor_add_cgi_ps_cmd);</span><br><span>         install_element(BTS_NODE, &cfg_neighbor_add_lac_arfcn_bsic_cmd);</span><br><span>         install_element(BTS_NODE, &cfg_neighbor_add_lac_ci_arfcn_bsic_cmd);</span><br><span>      install_element(BTS_NODE, &cfg_neighbor_add_cgi_arfcn_bsic_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+  install_element(BTS_NODE, &cfg_neighbor_add_cgi_ps_arfcn_bsic_cmd);</span><br><span>      install_element(BTS_NODE, &cfg_neighbor_del_bts_nr_cmd);</span><br><span>         install_element(BTS_NODE, &cfg_neighbor_del_arfcn_bsic_cmd);</span><br><span>     install_element(BTS_NODE, &cfg_neighbor_del_all_cmd);</span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c</span><br><span>index ed561aa..9955bd5 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_main.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_main.c</span><br><span>@@ -960,6 +960,19 @@</span><br><span>                exit(1);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (bsc_gsmnet->neigh_ctrl_addr) {</span><br><span style="color: hsl(120, 100%, 40%);">+         bsc_gsmnet->neigh_ctrl = neighbor_controlif_setup(bsc_gsmnet);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!bsc_gsmnet->neigh_ctrl) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     fprintf(stderr, "Failed to install neighbor control commands. Exiting.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = neighbor_ctrl_cmds_install(bsc_gsmnet);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      fprintf(stderr, "Failed to install neighbor control commands. Exiting.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (rf_ctrl)</span><br><span>                 osmo_talloc_replace_string(bsc_gsmnet, &bsc_gsmnet->rf_ctrl_name, rf_ctrl);</span><br><span> </span><br><span>diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am</span><br><span>index b6ba421..2cc57a4 100644</span><br><span>--- a/tests/bsc/Makefile.am</span><br><span>+++ b/tests/bsc/Makefile.am</span><br><span>@@ -8,6 +8,7 @@</span><br><span>    -ggdb3 \</span><br><span>     $(LIBOSMOCORE_CFLAGS) \</span><br><span>      $(LIBOSMOGSM_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+        $(LIBOSMOCTRL_CFLAGS) \</span><br><span>      $(LIBOSMOABIS_CFLAGS) \</span><br><span>      $(LIBOSMOLEGACYMGCP_CFLAGS) \</span><br><span>        $(LIBOSMOSIGTRAN_CFLAGS) \</span><br><span>@@ -59,6 +60,7 @@</span><br><span>       $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span>         $(LIBOSMOVTY_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+  $(LIBOSMOCTRL_LIBS) \</span><br><span>        $(LIBOSMOABIS_LIBS) \</span><br><span>        $(LIBOSMOLEGACYMGCP_LIBS) \</span><br><span>  $(LIBRARY_GSM) \</span><br><span>diff --git a/tests/ctrl/osmo-bsc-neigh-test.cfg b/tests/ctrl/osmo-bsc-neigh-test.cfg</span><br><span>new file mode 100644</span><br><span>index 0000000..3931c08</span><br><span>--- /dev/null</span><br><span>+++ b/tests/ctrl/osmo-bsc-neigh-test.cfg</span><br><span>@@ -0,0 +1,97 @@</span><br><span style="color: hsl(120, 100%, 40%);">+! osmo-bsc default configuration</span><br><span style="color: hsl(120, 100%, 40%);">+! (assumes STP to run on 127.0.0.1 and uses default point codes)</span><br><span style="color: hsl(120, 100%, 40%);">+!</span><br><span style="color: hsl(120, 100%, 40%);">+log file /tmp/osmo-bsc-neigh.log</span><br><span style="color: hsl(120, 100%, 40%);">+ logging filter all 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging color 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging print category 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging timestamp 1</span><br><span style="color: hsl(120, 100%, 40%);">+ logging level set-all debug</span><br><span style="color: hsl(120, 100%, 40%);">+e1_input</span><br><span style="color: hsl(120, 100%, 40%);">+ e1_line 0 driver ipa</span><br><span style="color: hsl(120, 100%, 40%);">+network</span><br><span style="color: hsl(120, 100%, 40%);">+ network country code 1</span><br><span style="color: hsl(120, 100%, 40%);">+ mobile network code 1</span><br><span style="color: hsl(120, 100%, 40%);">+ encryption a5 0</span><br><span style="color: hsl(120, 100%, 40%);">+ neci 1</span><br><span style="color: hsl(120, 100%, 40%);">+ paging any use tch 0</span><br><span style="color: hsl(120, 100%, 40%);">+ handover 0</span><br><span style="color: hsl(120, 100%, 40%);">+ handover algorithm 1</span><br><span style="color: hsl(120, 100%, 40%);">+ handover1 window rxlev averaging 10</span><br><span style="color: hsl(120, 100%, 40%);">+ handover1 window rxqual averaging 1</span><br><span style="color: hsl(120, 100%, 40%);">+ handover1 window rxlev neighbor averaging 10</span><br><span style="color: hsl(120, 100%, 40%);">+ handover1 power budget interval 6</span><br><span style="color: hsl(120, 100%, 40%);">+ handover1 power budget hysteresis 3</span><br><span style="color: hsl(120, 100%, 40%);">+ handover1 maximum distance 9999</span><br><span style="color: hsl(120, 100%, 40%);">+ periodic location update 30</span><br><span style="color: hsl(120, 100%, 40%);">+ neighbor bind 127.0.0.1 5000</span><br><span style="color: hsl(120, 100%, 40%);">+ bts 0</span><br><span style="color: hsl(120, 100%, 40%);">+  type sysmobts</span><br><span style="color: hsl(120, 100%, 40%);">+  band DCS1800</span><br><span style="color: hsl(120, 100%, 40%);">+  cell_identity 6969</span><br><span style="color: hsl(120, 100%, 40%);">+  location_area_code 1</span><br><span style="color: hsl(120, 100%, 40%);">+  base_station_id_code 63</span><br><span style="color: hsl(120, 100%, 40%);">+  ms max power 15</span><br><span style="color: hsl(120, 100%, 40%);">+  cell reselection hysteresis 4</span><br><span style="color: hsl(120, 100%, 40%);">+  rxlev access min 0</span><br><span style="color: hsl(120, 100%, 40%);">+  radio-link-timeout 32</span><br><span style="color: hsl(120, 100%, 40%);">+  channel allocator ascending</span><br><span style="color: hsl(120, 100%, 40%);">+  rach tx integer 9</span><br><span style="color: hsl(120, 100%, 40%);">+  rach max transmission 7</span><br><span style="color: hsl(120, 100%, 40%);">+  channel-description attach 1</span><br><span style="color: hsl(120, 100%, 40%);">+  channel-description bs-pa-mfrms 5</span><br><span style="color: hsl(120, 100%, 40%);">+  channel-description bs-ag-blks-res 1</span><br><span style="color: hsl(120, 100%, 40%);">+  early-classmark-sending forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+  ipa unit-id 6969 0</span><br><span style="color: hsl(120, 100%, 40%);">+  oml ipa stream-id 255 line 0</span><br><span style="color: hsl(120, 100%, 40%);">+  codec-support fr</span><br><span style="color: hsl(120, 100%, 40%);">+  gprs mode gprs</span><br><span style="color: hsl(120, 100%, 40%);">+  neighbor cgi-ps 23 42 423 2 5 arfcn 23 bsic 32</span><br><span style="color: hsl(120, 100%, 40%);">+  trx 0</span><br><span style="color: hsl(120, 100%, 40%);">+   rf_locked 0</span><br><span style="color: hsl(120, 100%, 40%);">+   arfcn 871</span><br><span style="color: hsl(120, 100%, 40%);">+   nominal power 23</span><br><span style="color: hsl(120, 100%, 40%);">+   ! to use full TRX power, set max_power_red 0</span><br><span style="color: hsl(120, 100%, 40%);">+   max_power_red 20</span><br><span style="color: hsl(120, 100%, 40%);">+   rsl e1 tei 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 0</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config CCCH+SDCCH4</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 1</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 2</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 3</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 4</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 5</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 6</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+   timeslot 7</span><br><span style="color: hsl(120, 100%, 40%);">+    phys_chan_config TCH/F</span><br><span style="color: hsl(120, 100%, 40%);">+    hopping enabled 0</span><br><span style="color: hsl(120, 100%, 40%);">+msc 0</span><br><span style="color: hsl(120, 100%, 40%);">+ type normal</span><br><span style="color: hsl(120, 100%, 40%);">+ allow-emergency allow</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 12_2k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 10_2k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 7_95k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 7_40k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 6_70k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 5_90k allowed</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 5_15k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ amr-config 4_75k forbidden</span><br><span style="color: hsl(120, 100%, 40%);">+ mgw remote-ip 127.0.0.1</span><br><span style="color: hsl(120, 100%, 40%);">+ mgw remote-port 2427</span><br><span style="color: hsl(120, 100%, 40%);">+ mgw local-port 2727</span><br><span style="color: hsl(120, 100%, 40%);">+ mgw endpoint-range 1 31</span><br><span style="color: hsl(120, 100%, 40%);">+bsc</span><br><span style="color: hsl(120, 100%, 40%);">+ mid-call-timeout 0</span><br><span>diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py</span><br><span>index 5d2af85..a0f230e 100755</span><br><span>--- a/tests/ctrl_test_runner.py</span><br><span>+++ b/tests/ctrl_test_runner.py</span><br><span>@@ -488,11 +488,34 @@</span><br><span>         self.assertEqual(r['var'], 'mcc')</span><br><span>         self.assertEqual(r['value'], '002')</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-def add_bsc_test(suite, workdir):</span><br><span style="color: hsl(120, 100%, 40%);">+class TestCtrlBSCNeighbor(TestCtrlBase):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def tearDown(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        TestCtrlBase.tearDown(self)</span><br><span style="color: hsl(120, 100%, 40%);">+        os.unlink("tmp_dummy_sock")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def ctrl_command(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        return ["./src/osmo-bsc/osmo-bsc", "-r", "tmp_dummy_sock", "-c",</span><br><span style="color: hsl(120, 100%, 40%);">+                "tests/ctrl/osmo-bsc-neigh-test.cfg"]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def ctrl_app(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        return (5000, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def testCtrlNeighborResolution(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci')</span><br><span style="color: hsl(120, 100%, 40%);">+        self.assertEqual(r['mtype'], 'ERROR')</span><br><span style="color: hsl(120, 100%, 40%);">+        self.assertEqual(r['error'], 'The format is <src_lac>,<src_cell_id>,<dst_arfcn>,<dst_bsic>')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        r = self.do_get('neighbor_resolve_cgi_ps_from_lac_ci.1.6969.23.32')</span><br><span style="color: hsl(120, 100%, 40%);">+        self.assertEqual(r['mtype'], 'GET_REPLY')</span><br><span style="color: hsl(120, 100%, 40%);">+        self.assertEqual(r['var'], 'neighbor_resolve_cgi_ps_from_lac_ci.1.6969.23.32')</span><br><span style="color: hsl(120, 100%, 40%);">+        self.assertEqual(r['value'], '23,42,423,2,5')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def add_bsc_test(suite, workdir, klass):</span><br><span>     if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):</span><br><span>         print("Skipping the BSC test")</span><br><span>         return</span><br><span style="color: hsl(0, 100%, 40%);">-    test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlBSC)</span><br><span style="color: hsl(120, 100%, 40%);">+    test = unittest.TestLoader().loadTestsFromTestCase(klass)</span><br><span>     suite.addTest(test)</span><br><span> </span><br><span> if __name__ == '__main__':</span><br><span>@@ -525,6 +548,7 @@</span><br><span>     os.chdir(workdir)</span><br><span>     print("Running tests for specific control commands")</span><br><span>     suite = unittest.TestSuite()</span><br><span style="color: hsl(0, 100%, 40%);">-    add_bsc_test(suite, workdir)</span><br><span style="color: hsl(120, 100%, 40%);">+    add_bsc_test(suite, workdir, TestCtrlBSC)</span><br><span style="color: hsl(120, 100%, 40%);">+    add_bsc_test(suite, workdir, TestCtrlBSCNeighbor)</span><br><span>     res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)</span><br><span>     sys.exit(len(res.errors) + len(res.failures))</span><br><span>diff --git a/tests/gsm0408/Makefile.am b/tests/gsm0408/Makefile.am</span><br><span>index a00da46..571e7e6 100644</span><br><span>--- a/tests/gsm0408/Makefile.am</span><br><span>+++ b/tests/gsm0408/Makefile.am</span><br><span>@@ -7,6 +7,7 @@</span><br><span>         -Wall \</span><br><span>      $(LIBOSMOCORE_CFLAGS) \</span><br><span>      $(LIBOSMOGSM_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+        $(LIBOSMOCTRL_CFLAGS) \</span><br><span>      $(LIBOSMOABIS_CFLAGS) \</span><br><span>      $(NULL)</span><br><span> </span><br><span>@@ -46,5 +47,6 @@</span><br><span>      $(top_builddir)/src/osmo-bsc/nm_rcarrier_fsm.o \</span><br><span>     $(LIBOSMOCORE_LIBS) \</span><br><span>        $(LIBOSMOGSM_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+  $(LIBOSMOCTRL_LIBS) \</span><br><span>        $(LIBOSMOABIS_LIBS) \</span><br><span>        $(NULL)</span><br><span>diff --git a/tests/neighbor_ident.vty b/tests/neighbor_ident.vty</span><br><span>index ce414e1..48af8bf 100644</span><br><span>--- a/tests/neighbor_ident.vty</span><br><span>+++ b/tests/neighbor_ident.vty</span><br><span>@@ -14,6 +14,10 @@</span><br><span> OsmoBSC# configure terminal</span><br><span> OsmoBSC(config)# network</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+OsmoBSC(config-net)# neighbor bind 1.2.3.4 ?</span><br><span style="color: hsl(120, 100%, 40%);">+  <0-65535>  Port to bind the service to</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> OsmoBSC(config-net)# bts 0</span><br><span> OsmoBSC(config-net-bts)# type sysmobts</span><br><span> OsmoBSC(config-net-bts)# base_station_id_code 10</span><br><span>@@ -84,9 +88,11 @@</span><br><span>   neighbor lac <0-65535></span><br><span>   neighbor lac-ci <0-65535> <0-65535></span><br><span>   neighbor cgi <0-999> <0-999> <0-65535> <0-65535></span><br><span style="color: hsl(120, 100%, 40%);">+  neighbor cgi-ps <0-999> <0-999> <0-65535> <0-255> <0-65535></span><br><span>   neighbor lac <0-65535> arfcn <0-1023> bsic (<0-63>|any)</span><br><span>   neighbor lac-ci <0-65535> <0-65535> arfcn <0-1023> bsic (<0-63>|any)</span><br><span>   neighbor cgi <0-999> <0-999> <0-65535> <0-65535> arfcn <0-1023> bsic (<0-63>|any)</span><br><span style="color: hsl(120, 100%, 40%);">+  neighbor cgi-ps <0-999> <0-999> <0-65535> <0-255> <0-65535> arfcn <0-1023> bsic (<0-63>|any)</span><br><span>   no neighbor bts <0-255></span><br><span>   no neighbor arfcn <0-1023> bsic (<0-63>|any)</span><br><span>   no neighbors</span><br><span>@@ -100,6 +106,7 @@</span><br><span>   lac     Add Neighbor cell by LAC</span><br><span>   lac-ci  Add Neighbor cell by LAC and CI</span><br><span>   cgi     Add Neighbor cell by cgi</span><br><span style="color: hsl(120, 100%, 40%);">+  cgi-ps  Add Neighbor cell by cgi (Packet Switch, with RAC)</span><br><span> </span><br><span> OsmoBSC(config-net-bts)# neighbor bts ?</span><br><span>   <0-255>  BTS number</span><br><span>@@ -348,12 +355,16 @@</span><br><span> OsmoBSC(config-net-bts)# neighbor lac-ci 789 10 arfcn 423 bsic any</span><br><span> % BTS 0 to ARFCN 423 (any BSIC) now has 1 remote BSS Cell Identifier List entry</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+OsmoBSC(config-net-bts)# neighbor cgi-ps 23 42 423 2 5 arfcn 23 bsic 32</span><br><span style="color: hsl(120, 100%, 40%);">+% BTS 0 to ARFCN 23 BSIC 32 now has 1 remote BSS Cell Identifier List entry</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> OsmoBSC(config-net-bts)# no neighbors</span><br><span> % Removed local neighbor bts 0 to bts 1</span><br><span> % Removed local neighbor bts 0 to bts 2</span><br><span> % Removed remote BSS neighbor BTS 0 to ARFCN 23 BSIC 42</span><br><span> % Removed remote BSS neighbor BTS 0 to ARFCN 123 BSIC 45</span><br><span> % Removed remote BSS neighbor BTS 0 to ARFCN 423 (any BSIC)</span><br><span style="color: hsl(120, 100%, 40%);">+% Removed remote BSS neighbor BTS 0 to ARFCN 23 BSIC 32</span><br><span> </span><br><span> OsmoBSC(config-net-bts)# show running-config</span><br><span> ... !neighbor </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21848">change 21848</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bsc/+/21848"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ib07c9d23026332a207d4b7a0f7b4e76c0094e379 </div>
<div style="display:none"> Gerrit-Change-Number: 21848 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>