ms: Log MS active/idle state in 'show ms' VTY commands

Change-Id: Ibcd34055c9ae390510c5c3ba26621fd96d2368fd
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index 720617e..0018252 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -219,6 +219,8 @@
 {
 	unsigned long delay_rel_sec = osmo_tdef_get(ms->bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1);
 
+	osmo_gettimeofday(&ms->tv_idle_start, NULL);
+
 	ms_set_reserved_slots(ms, NULL, 0, 0);
 	ms->first_common_ts = NULL;
 
@@ -251,6 +253,7 @@
 
 	LOGPMS(ms, DMS, LOGL_DEBUG, "Cancel scheduled MS release\n");
 
+	timerclear(&ms->tv_idle_start);
 	osmo_timer_del(&ms->release_timer);
 }
 
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index b2b3274..ef1cc4e 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -80,6 +80,8 @@
 
 	struct osmo_use_count use_count;
 	struct osmo_timer_list release_timer;
+	/* Time at which MS became idle and waiting to be released by release_timer: */
+	struct timeval tv_idle_start;
 
 	int64_t last_cs_not_low;
 
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index fe51203..b7fcc8f 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -148,6 +148,16 @@
 	uint8_t slots;
 
 	vty_out(vty, "MS TLLI=%08x, IMSI=%s%s", ms_tlli(ms), ms_imsi(ms), VTY_NEWLINE);
+	if (osmo_timer_pending(&ms->release_timer)) {
+		struct timeval tv_now, tv_res1, tv_res2;
+		osmo_gettimeofday(&tv_now, NULL);
+		timersub(&tv_now, &ms->tv_idle_start, &tv_res1);
+		osmo_timer_remaining(&ms->release_timer, &tv_now, &tv_res2);
+		vty_out(vty, "  State:                  IDLE for %lus, release in %lus%s",
+			tv_res1.tv_sec, tv_res2.tv_sec, VTY_NEWLINE);
+	} else {
+		vty_out(vty, "  State:                  ACTIVE%s", VTY_NEWLINE);
+	}
 	vty_out(vty, "  Timing advance (TA):    %d%s", ms_ta(ms), VTY_NEWLINE);
 	vty_out(vty, "  Coding scheme uplink:   %s%s", mcs_name(ms_current_cs_ul(ms)),
 		VTY_NEWLINE);