aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/gsm_subscriber.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libmsc/gsm_subscriber.c')
-rw-r--r--openbsc/src/libmsc/gsm_subscriber.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c
index 7ff44075c..6abb0d832 100644
--- a/openbsc/src/libmsc/gsm_subscriber.c
+++ b/openbsc/src/libmsc/gsm_subscriber.c
@@ -1,7 +1,7 @@
/* The concept of a subscriber for the MSC, roughly HLR/VLR functionality */
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
*
* All Rights Reserved
*
@@ -37,6 +37,7 @@
#include <openbsc/paging.h>
#include <openbsc/signal.h>
#include <openbsc/db.h>
+#include <openbsc/chan_alloc.h>
void *tall_sub_req_ctx;
@@ -323,6 +324,21 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
return db_get_subscriber(net, GSM_SUBSCRIBER_ID, buf);
}
+int subscr_update_expire_lu(struct gsm_subscriber *s, struct gsm_bts *bts)
+{
+ int rc;
+
+ /* Table 10.5.33: 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 */
+ s->expire_lu = time(NULL) +
+ (bts->si_common.chan_desc.t3212 * 60 * 6 * 2) + 60;
+ rc = db_sync_subscriber(s);
+ db_subscriber_update(s);
+ return rc;
+}
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason)
{
@@ -335,24 +351,19 @@ int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason)
/* Indicate "attached to LAC" */
s->lac = bts->location_area_code;
+ LOGP(DMM, LOGL_INFO, "Subscriber %s ATTACHED LAC=%u\n",
+ subscr_name(s), s->lac);
+
/* FIXME: We should allow 0 for T3212 as well to disable the
* location update period. In that case we will need a way to
* indicate that in the database and then reenable that value in
* VTY.
*/
-
- /* Table 10.5.33: 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 */
- s->expire_lu = time(NULL) +
- (bts->si_common.chan_desc.t3212 * 60 * 6 * 2) + 60;
-
- LOGP(DMM, LOGL_INFO, "Subscriber %s ATTACHED LAC=%u\n",
- subscr_name(s), s->lac);
- rc = db_sync_subscriber(s);
- db_subscriber_update(s);
+ /*
+ * The below will set a new expire_lu but as a side-effect
+ * the new lac will be saved in the database.
+ */
+ rc = subscr_update_expire_lu(s, bts);
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_ATTACHED, s);
break;
case GSM_SUBSCRIBER_UPDATE_DETACHED:
@@ -383,8 +394,23 @@ void subscr_update_from_db(struct gsm_subscriber *sub)
static void subscr_expire_callback(void *data, long long unsigned int id)
{
struct gsm_network *net = data;
- struct gsm_subscriber *s =
- subscr_get_by_id(net, id);
+ struct gsm_subscriber *s = subscr_get_by_id(net, id);
+ struct gsm_subscriber_connection *conn = connection_for_subscr(s);
+
+ /*
+ * The subscriber is active and the phone stopped the timer. As
+ * we don't want to periodically update the database for active
+ * subscribers we will just do it when the subscriber was selected
+ * for expiration. This way on the next around another subscriber
+ * will be selected.
+ */
+ if (conn && conn->expire_timer_stopped) {
+ LOGP(DMM, LOGL_DEBUG, "Not expiring subscriber %s (ID %llu)\n",
+ subscr_name(s), id);
+ subscr_update_expire_lu(s, conn->bts);
+ return;
+ }
+
LOGP(DMM, LOGL_NOTICE, "Expiring inactive subscriber %s (ID %llu)\n",
subscr_name(s), id);