vty: 'show bts': print neighbor cells

Print out the current neighbor cell list, works both for manual and
automatically populated modes.

Examples of output for various configs:

  Neighbor Cells: Automatic, ARFCNs: (none)
  Neighbor Cells: Automatic, ARFCNs: 868 (1)
  Neighbor Cells: Manual, ARFCNs: 123 125 (2)
  Neighbor Cells: Manual/separate SI5, ARFCNs: 123 125 (2) SI5: 321 (1)

Change-Id: I57dae0e01b81a6f028b39f3edcaf430251ca8fe2
diff --git a/src/libbsc/bsc_vty.c b/src/libbsc/bsc_vty.c
index d344028..64a92b2 100644
--- a/src/libbsc/bsc_vty.c
+++ b/src/libbsc/bsc_vty.c
@@ -266,6 +266,22 @@
 		e1l->tei, e1l->sapi, VTY_NEWLINE);
 }
 
+static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv)
+{
+	int count = 0;
+	int i;
+	for (i = 0; i < 1024; i++) {
+		if (!bitvec_get_bit_pos(bv, i))
+			continue;
+		vty_out(vty, " %u", i);
+		count ++;
+	}
+	if (!count)
+		vty_out(vty, " (none)");
+	else
+		vty_out(vty, " (%d)", count);
+}
+
 static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
 {
 	struct pchan_load pl;
@@ -387,6 +403,28 @@
 		e1isl_dump_vty(vty, bts->oml_link);
 	}
 
+	vty_out(vty, "  Neighbor Cells: ");
+	switch (bts->neigh_list_manual_mode) {
+	default:
+	case NL_MODE_AUTOMATIC:
+		vty_out(vty, "Automatic");
+		/* generate_bcch_chan_list() should populate si_common.neigh_list */
+		break;
+	case NL_MODE_MANUAL:
+		vty_out(vty, "Manual");
+		break;
+	case NL_MODE_MANUAL_SI5SEP:
+		vty_out(vty, "Manual/separate SI5");
+		break;
+	}
+	vty_out(vty, ", ARFCNs:");
+	vty_out_neigh_list(vty, &bts->si_common.neigh_list);
+	if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
+		vty_out(vty, " SI5:");
+		vty_out_neigh_list(vty, &bts->si_common.si5_neigh_list);
+	}
+	vty_out(vty, "%s", VTY_NEWLINE);
+
 	/* FIXME: chan_desc */
 	memset(&pl, 0, sizeof(pl));
 	bts_chan_load(&pl, bts);