ns2: Dump frame relay state to VTY during "show ns"

When doing a "show ns", let's also dump the state of the frame
relay network, with all its links and DLCs (if any).

Change-Id: I798af3e97dc014b6e0fcde86560a1809852f7510
Related: OS#4877
diff --git a/include/osmocom/gprs/frame_relay.h b/include/osmocom/gprs/frame_relay.h
index 8ab9790..81b42a6 100644
--- a/include/osmocom/gprs/frame_relay.h
+++ b/include/osmocom/gprs/frame_relay.h
@@ -33,6 +33,7 @@
 
 struct osmo_tdef;
 struct msgb;
+struct vty;
 
 enum osmo_fr_role {
 	FR_ROLE_USER_EQUIPMENT,
@@ -132,6 +133,7 @@
 /* allocate a frame relay network */
 struct osmo_fr_network *osmo_fr_network_alloc(void *ctx);
 void osmo_fr_network_free(struct osmo_fr_network *net);
+void osmo_fr_network_dump_vty(struct vty *vty, const struct osmo_fr_network *net);
 
 /* allocate a frame relay link in a given network */
 struct osmo_fr_link *osmo_fr_link_alloc(struct osmo_fr_network *net, enum osmo_fr_role role, const char *name);
diff --git a/src/gb/frame_relay.c b/src/gb/frame_relay.c
index 84cd17f..4d1df67 100644
--- a/src/gb/frame_relay.c
+++ b/src/gb/frame_relay.c
@@ -1014,3 +1014,38 @@
 	}
 	return NULL;
 }
+
+
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/tdef_vty.h>
+
+static void fr_dlc_dump_vty(struct vty *vty, const struct osmo_fr_dlc *dlc)
+{
+	vty_out(vty, "  FR DLC %05u: %s%s%s%s", dlc->dlci,
+		dlc->active ? "ACTIVE" : "INACTIVE",
+		dlc->add ? " ADDED" : "", dlc->del ? " DELETED" : "", VTY_NEWLINE);
+}
+
+static void fr_link_dump_vty(struct vty *vty, const struct osmo_fr_link *link)
+{
+	const struct osmo_fr_dlc *dlc;
+
+	vty_out(vty, "FR Link '%s': Role %s, LastRxSeq %u, LastTxSeq %u%s",
+		link->name, link->role == FR_ROLE_USER_EQUIPMENT ? "USER" : "NETWORK",
+		link->last_rx_seq, link->last_tx_seq, VTY_NEWLINE);
+	llist_for_each_entry(dlc, &link->dlc_list, list) {
+		fr_dlc_dump_vty(vty, dlc);
+	}
+}
+
+void osmo_fr_network_dump_vty(struct vty *vty, const struct osmo_fr_network *net)
+{
+	struct osmo_fr_link *link;
+
+	vty_out(vty, "FR Network: N391 %u, N392 %u, N393 %u%s",
+		net->n391, net->n392, net->n393, VTY_NEWLINE);
+	osmo_tdef_vty_out_all(vty, net->T_defs, "    ");
+	llist_for_each_entry(link, &net->links, list) {
+		fr_link_dump_vty(vty, link);
+	}
+}
diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c
index b678db4..1ef22f5 100644
--- a/src/gb/gprs_ns2_vty.c
+++ b/src/gb/gprs_ns2_vty.c
@@ -1922,6 +1922,8 @@
 {
 	dump_ns_entities(vty, vty_nsi, false, false);
 	dump_ns_bind(vty, vty_nsi, false);
+	if (vty_fr_network && llist_count(&vty_fr_network->links))
+		osmo_fr_network_dump_vty(vty, vty_fr_network);
 	return CMD_SUCCESS;
 }