libmsc: move subscriber expiration timer T3212 to libvlr

Since the split of OsmoNiTB, OsmoMSC does not deal with the radio
access network directly. Therefore the only purpose of T3212 is to
control subscriber expiration in the local VLR. The timeout value
indicated in System Information Type 3 needs to be configured
separately in the BSC/RNC.

This means that we don't need to store it in deci-hours anymore.
Let's move T3212 to the group of VLR specific timers, so it can
be configured and introspected using the generic 'timer' command,
and deprecate the old '[no] periodic location update' command.

It should be also noted that in the old code subscriber expiration
timeout was actually set to twice the T3212 value plus one minute.
After this change, we apply the configured value 'as-is', but
keep the old behaviour for 'periodic location update' command.

Change-Id: I9b12066599a7c834a53a93acf5902d91273bc74f
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
index a1489f2..887ceb8 100644
--- a/src/libvlr/vlr.c
+++ b/src/libvlr/vlr.c
@@ -64,7 +64,7 @@
 
 /* 3GPP TS 24.008, table 11.2 Mobility management timers (network-side) */
 struct osmo_tdef msc_tdefs_vlr[] = {
-	/* TODO: also define T3212 here */
+	{ .T = 3212, .default_val = 60, .unit = OSMO_TDEF_M, .desc = "Subscriber expiration timeout" },
 	{ .T = 3250, .default_val = 12, .desc = "TMSI Reallocation procedure" },
 	{ .T = 3260, .default_val = 12, .desc = "Authentication procedure" },
 	{ .T = 3270, .default_val = 12, .desc = "Identification procedure" },
@@ -75,6 +75,9 @@
  * TODO: we should start using osmo_tdef_fsm_inst_state_chg() */
 uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer)
 {
+	/* NOTE: since we usually do not need more than one instance of the VLR,
+	 * and since libosmocore's osmo_tdef API does not (yet) support dynamic
+	 * configuration, we always use the global instance of msc_tdefs_vlr. */
 	return osmo_tdef_get(msc_tdefs_vlr, timer, OSMO_TDEF_S, 0);
 }
 
@@ -496,14 +499,11 @@
 
 void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub)
 {
-	struct gsm_network *net = vsub->vlr->user_ctx; /* XXX move t3212 into struct vlr_instance? */
 	struct timespec now;
 
-	/* The T3212 timeout value field is coded as the binary representation of the timeout
-	 * value for periodic updating in decihours. Mark the subscriber as inactive if it missed
-	 * two consecutive location updates. Timeout is twice the t3212 value plus one minute. */
+	/* Mark the subscriber as inactive if it stopped to do periodical location updates. */
 	if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
-		vsub->expire_lu = now.tv_sec + (net->t3212 * 60 * 6 * 2) + 60;
+		vsub->expire_lu = now.tv_sec + vlr_timer(vsub->vlr, 3212);
 	} else {
 		LOGP(DVLR, LOGL_ERROR,
 		     "%s: Could not enable Location Update expiry: unable to read current time\n", vlr_subscr_name(vsub));
@@ -516,13 +516,11 @@
 {
 	struct vlr_instance *vlr = data;
 	struct vlr_subscr *vsub, *vsub_tmp;
-	struct gsm_network *net;
 	struct timespec now;
 
 	/* Periodic location update might be disabled from the VTY,
 	 * so we shall not expire subscribers until explicit IMSI Detach. */
-	net = vlr->user_ctx; /* XXX move t3212 into struct vlr_instance? */
-	if (!net->t3212)
+	if (!vlr_timer(vlr, 3212))
 		goto done;
 
 	if (llist_empty(&vlr->subscribers))
@@ -1263,6 +1261,9 @@
 	/* defaults */
 	vlr->cfg.assign_tmsi = true;
 
+	/* reset shared timer definitions */
+	osmo_tdefs_reset(msc_tdefs_vlr);
+
 	/* osmo_auth_fsm.c */
 	OSMO_ASSERT(osmo_fsm_register(&vlr_auth_fsm) == 0);
 	/* osmo_lu_fsm.c */