aboutsummaryrefslogtreecommitdiffstats
path: root/src/libvlr/vlr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libvlr/vlr.c')
-rw-r--r--src/libvlr/vlr.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
index 2d232be74..5a908765d 100644
--- a/src/libvlr/vlr.c
+++ b/src/libvlr/vlr.c
@@ -22,6 +22,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/timer.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/apn.h>
@@ -460,6 +461,59 @@ int vlr_subscr_changed(struct vlr_subscr *vsub)
return 0;
}
+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 timeval now;
+
+ /* Table 10.5.33: The T3212 timeout value 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 */
+ if (osmo_gettimeofday(&now, NULL) == 0) {
+ LOGP(DVLR, LOGL_DEBUG, "IMSI=%s id=%llu: current time is %llu\n", vsub->imsi, vsub->id, (unsigned long long)now.tv_sec);
+ vsub->expire_lu = now.tv_sec + (net->t3212 * 60 * 6 * 2) + 60;
+ LOGP(DVLR, LOGL_DEBUG, "IMSI=%s id=%llu: Location Update expiry at %llu\n",
+ vsub->imsi, vsub->id, (unsigned long long)vsub->expire_lu);
+ } else {
+ LOGP(DVLR, LOGL_ERROR,
+ "IMSI=%s id=%llu: Could not enable Location Update expiry: unable to read current time\n",
+ vsub->imsi, vsub->id);
+ vsub->expire_lu = GSM_SUBSCRIBER_NO_EXPIRATION; /* XXX */
+ }
+}
+
+void
+vlr_subscr_expire_lu(void *data)
+{
+ struct vlr_instance *vlr = data;
+ struct vlr_subscr *vsub;
+ struct timeval now;
+
+ LOGP(DVLR, LOGL_ERROR, "Hi");
+ if (llist_empty(&vlr->subscribers))
+ return;
+
+ if (osmo_gettimeofday(&now, NULL) != 0) {
+ LOGP(DVLR, LOGL_ERROR, "Skipping Location Update expiry: Could not read current time\n");
+ return;
+ }
+
+ llist_for_each_entry(vsub, &vlr->subscribers, list) {
+ if (vsub->expire_lu == GSM_SUBSCRIBER_NO_EXPIRATION)
+ continue;
+ if (vsub->expire_lu < now.tv_sec)
+ continue;
+
+ LOGP(DVLR, LOGL_DEBUG, "IMSI=%s id=%llu: Location Update expired\n", vsub->imsi, vsub->id);
+ vlr_subscr_rx_imsi_detach(vsub);
+ }
+
+ osmo_timer_schedule(&vlr->lu_expire_timer, GSM_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
+}
+
/***********************************************************************
* PDP context data
***********************************************************************/
@@ -1093,12 +1147,14 @@ bool vlr_subscr_expire(struct vlr_subscr *vsub)
return false;
}
+/* See TS 32.012 version 9.10.0 4.3.2.1 "Process Detach_IMSI_VLR" */
int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub)
{
/* paranoia: should any LU or PARQ FSMs still be running, stop them. */
vlr_subscr_cancel_attach_fsm(vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION);
vsub->imsi_detached_flag = true;
+ vsub->expire_lu = GSM_SUBSCRIBER_NO_EXPIRATION;
/* balancing the get from vlr_lu_compl_fsm_success() */
vlr_subscr_expire(vsub);
@@ -1139,6 +1195,8 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
INIT_LLIST_HEAD(&vlr->operations);
memcpy(&vlr->ops, ops, sizeof(vlr->ops));
+ osmo_timer_setup(&vlr->lu_expire_timer, vlr_subscr_expire_lu, vlr);
+
/* defaults */
vlr->cfg.assign_tmsi = true;
@@ -1165,6 +1223,7 @@ int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr,
return -ENOMEM;
vlr->gsup_client->data = vlr;
+ osmo_timer_schedule(&vlr->lu_expire_timer, GSM_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
return 0;
}