diff options
Diffstat (limited to 'openbsc/src/libmsc/gsm_subscriber.c')
-rw-r--r-- | openbsc/src/libmsc/gsm_subscriber.c | 58 |
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); |