vty: Add 'show ms all' command

This command lists the entries of the ms_store by a line per MS.
Beside TLLI and IMSI, some measurement and state information is
shown.

A ms_list() getter method is added to GprsMsStorage to obtain a list
of the MsGprs objects.

The following VTY command is added to the 'enable' node:

 - show ms all

Sponsored-by: On-Waves ehf
diff --git a/src/gprs_ms_storage.h b/src/gprs_ms_storage.h
index 3552602..ad1e656 100644
--- a/src/gprs_ms_storage.h
+++ b/src/gprs_ms_storage.h
@@ -39,6 +39,7 @@
 	GprsMs *get_ms(uint32_t tlli, uint32_t old_tlli = 0, const char *imsi = 0) const;
 	GprsMs *create_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir);
 
+	const LListHead<GprsMs>& ms_list() const {return m_list;}
 private:
 	BTS *m_bts;
 	LListHead<GprsMs> m_list;
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index 7add393..8c2a8d8 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -531,6 +531,15 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(show_ms_all,
+      show_ms_all_cmd,
+      "show ms all",
+      SHOW_STR "information about MSs\n" "All TBFs\n")
+{
+	struct gprs_rlcmac_bts *bts = bts_main_data();
+	return pcu_vty_show_ms_all(vty, bts);
+}
+
 static const char pcu_copyright[] =
 	"Copyright (C) 2012 by Ivan Kluchnikov <kluchnikovi@gmail.com> and \r\n"
 	"                      Andreas Eversberg <jolly@eversberg.eu>\r\n"
@@ -587,6 +596,7 @@
 
 	install_element_ve(&show_bts_stats_cmd);
 	install_element_ve(&show_tbf_cmd);
+	install_element_ve(&show_ms_all_cmd);
 
 	return 0;
 }
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index b43e3e4..9783c4d 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -23,6 +23,10 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include "pcu_vty_functions.h"
+#include "bts.h"
+#include "gprs_ms_storage.h"
+#include "gprs_ms.h"
+#include "cxx_linuxlist.h"
 
 extern "C" {
 #  include <osmocom/vty/command.h>
@@ -34,3 +38,20 @@
 {
 	return CMD_SUCCESS;
 }
+
+int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data)
+{
+	BTS *bts = bts_data->bts;
+	LListHead<GprsMs> *ms_iter;
+
+	llist_for_each(ms_iter, &bts->ms_store().ms_list()) {
+		GprsMs *ms = ms_iter->entry();
+
+		vty_out(vty, "MS TLLI=%08x, TA=%d, CS-UL=%d, CS-DL=%d, IMSI=%s%s",
+			ms->tlli(),
+			ms->ta(), ms->current_cs_ul(), ms->current_cs_dl(),
+			ms->imsi(),
+			VTY_NEWLINE);
+	}
+	return CMD_SUCCESS;
+}
diff --git a/src/pcu_vty_functions.h b/src/pcu_vty_functions.h
index 1500635..89c5f82 100644
--- a/src/pcu_vty_functions.h
+++ b/src/pcu_vty_functions.h
@@ -25,8 +25,10 @@
 #endif
 
 struct vty;
+struct gprs_rlcmac_bts;
 
 int pcu_vty_config_write_pcu_ext(struct vty *vty);
+int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data);
 
 #ifdef __cplusplus
 }