[GPRS] LLC: Add VTY interface for LLC
diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h
index 608fb05..21ebaa2 100644
--- a/openbsc/include/openbsc/gprs_llc.h
+++ b/openbsc/include/openbsc/gprs_llc.h
@@ -59,10 +59,49 @@
 	LL_STATUS_IND,		/* TLLI, Cause */
 };
 
+/* Section 4.5.2 Logical Link States + Annex C.2 */
+enum gprs_llc_ll_state {
+	GPRS_LLS_UNASSIGNED	= 1,	/* No TLLI yet */
+	GPRS_LLS_ASSIGNED_ADM	= 2,	/* TLLI assigned */
+	GPRS_LLS_LOCAL_EST	= 3,	/* Local Establishment */
+	GPRS_LLS_REMOTE_EST	= 4,	/* Remote Establishment */
+	GPRS_LLS_ABM		= 5,
+	GPRS_LLS_LOCAL_REL	= 6,	/* Local Release */
+	GPRS_LLS_TIMER_REC 	= 7,	/* Timer Recovery */
+};
+
+/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
+struct gprs_llc_lle {
+	struct llist_head list;
+
+	struct timer_list t200;
+	struct timer_list t201;	/* wait for acknowledgement */
+
+	enum gprs_llc_ll_state state;
+
+	uint32_t tlli;
+	uint32_t sapi;
+
+	uint8_t v_sent;
+	uint8_t v_ack;
+	uint8_t v_recv;
+
+	unsigned int n200;
+	unsigned int retrans_ctr;
+
+	/* over which BSSGP BTS ctx do we need to transmit */
+	uint16_t bvci;
+	uint16_t nsei;
+};
+
+extern struct llist_head gprs_llc_lles;
+
 /* BSSGP-UL-UNITDATA.ind */
 int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
 
 /* LL-UNITDATA.req */
 int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command);
 
+int gprs_llc_vty_init(void);
+
 #endif
diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am
index 6638dd6..d04b5cd 100644
--- a/openbsc/src/gprs/Makefile.am
+++ b/openbsc/src/gprs/Makefile.am
@@ -11,7 +11,8 @@
 
 
 libsgsn_a_SOURCES = gprs_ns.c gprs_bssgp.c gprs_llc.c gprs_gmm.c \
-		crc24.c gprs_sgsn.c gprs_bssgp_util.c gprs_bssgp_vty.c
+		crc24.c gprs_sgsn.c gprs_bssgp_util.c gprs_bssgp_vty.c \
+		gprs_llc_vty.c
 
 osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
 			gprs_ns.c gprs_ns_vty.c gprs_bssgp_util.c \
diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index 376215d..3eea82d 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -34,41 +34,7 @@
 #include <openbsc/gprs_llc.h>
 #include <openbsc/crc24.h>
 
-/* Section 4.5.2 Logical Link States + Annex C.2 */
-enum gprs_llc_ll_state {
-	GPRS_LLS_UNASSIGNED	= 1,	/* No TLLI yet */
-	GPRS_LLS_ASSIGNED_ADM	= 2,	/* TLLI assigned */
-	GPRS_LLS_LOCAL_EST	= 3,	/* Local Establishment */
-	GPRS_LLS_REMOTE_EST	= 4,	/* Remote Establishment */
-	GPRS_LLS_ABM		= 5,
-	GPRS_LLS_LOCAL_REL	= 6,	/* Local Release */
-	GPRS_LLS_TIMER_REC 	= 7,	/* Timer Recovery */
-};
-
-/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
-struct gprs_llc_lle {
-	struct llist_head list;
-	struct timer_list t200;
-	struct timer_list t201;	/* wait for acknowledgement */
-
-	enum gprs_llc_ll_state state;
-
-	uint32_t tlli;
-	uint32_t sapi;
-
-	uint8_t v_sent;
-	uint8_t v_ack;
-	uint8_t v_recv;
-
-	unsigned int n200;
-	unsigned int retrans_ctr;
-
-	/* over which BSSGP BTS ctx do we need to transmit */
-	uint16_t bvci;
-	uint16_t nsei;
-};
-
-static LLIST_HEAD(gprs_llc_lles);
+LLIST_HEAD(gprs_llc_lles);
 void *llc_tall_ctx;
 
 /* lookup LLC Entity based on DLCI (TLLI+SAPI tuple) */
diff --git a/openbsc/src/gprs/gprs_llc_vty.c b/openbsc/src/gprs/gprs_llc_vty.c
new file mode 100644
index 0000000..510ef64
--- /dev/null
+++ b/openbsc/src/gprs/gprs_llc_vty.c
@@ -0,0 +1,81 @@
+/* VTY interface for our GPRS LLC implementation */
+
+/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <arpa/inet.h>
+
+#include <openbsc/gsm_data.h>
+#include <osmocore/msgb.h>
+#include <osmocore/tlv.h>
+#include <osmocore/talloc.h>
+#include <osmocore/select.h>
+#include <osmocore/rate_ctr.h>
+#include <openbsc/debug.h>
+#include <openbsc/signal.h>
+#include <openbsc/gprs_llc.h>
+
+#include <vty/vty.h>
+#include <vty/command.h>
+
+struct value_string gprs_llc_state_strs[] = {
+	{ GPRS_LLS_UNASSIGNED, 		"TLLI Unassigned" },
+	{ GPRS_LLS_ASSIGNED_ADM,	"Assigned" },
+	{ GPRS_LLS_LOCAL_EST,		"Local Establishment" },
+	{ GPRS_LLS_REMOTE_EST,		"Remote Establishment" },
+	{ GPRS_LLS_ABM,			"Asynchronous Balanced Mode" },
+	{ GPRS_LLS_LOCAL_REL,		"Local Release" },
+	{ GPRS_LLS_TIMER_REC,		"Timer Recovery" },
+};
+
+static void vty_dump_lle(struct vty *vty, struct gprs_llc_lle *lle)
+{
+	vty_out(vty, "TLLI 0x%08x SAPI %u BVCI=%u NSEI=%u: State %s%s",
+		lle->tlli, lle->sapi, lle->bvci, lle->nsei,
+		get_value_string(gprs_llc_state_strs, lle->state), VTY_NEWLINE);
+	vty_out(vty, " Vsent=%u Vack=%u Vrecv=%u, N200=%u, Retrans Ctr=%u%s",
+		lle->v_sent, lle->v_ack, lle->v_recv, lle->n200,
+		lle->retrans_ctr, VTY_NEWLINE);
+}
+
+DEFUN(show_llc, show_llc_cmd,
+	"show llc",
+	SHOW_STR "Display information about the LLC protocol")
+{
+	struct gprs_llc_lle *lle;
+
+	vty_out(vty, "State of LLC Entities%s", VTY_NEWLINE);
+	llist_for_each_entry(lle, &gprs_llc_lles, list) {
+		vty_dump_lle(vty, lle);
+	}
+	return CMD_SUCCESS;
+}
+
+int gprs_llc_vty_init(void)
+{
+	install_element_ve(&show_llc_cmd);
+
+	return 0;
+}
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index fca392a..2a119e3 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -45,6 +45,7 @@
 #include <openbsc/sgsn.h>
 #include <openbsc/gprs_ns.h>
 #include <openbsc/gprs_bssgp.h>
+#include <openbsc/gprs_llc.h>
 
 #include <gtp.h>
 
@@ -161,6 +162,7 @@
 	bssgp_nsi = sgsn_inst.cfg.nsi = sgsn_nsi;
 	gprs_ns_vty_init(bssgp_nsi);
 	gprs_bssgp_vty_init();
+	gprs_llc_vty_init();
 	/* FIXME: register signal handler for SS_NS */
 
 	rc = sgsn_parse_config(sgsn_inst.config_file, &sgsn_inst.cfg);