diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2019-11-20 02:36:35 +0100 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2019-11-27 03:19:06 +0100 |
commit | 07e1602d2dd13d0884ccd623d9f7955b921fa702 (patch) | |
tree | 02a08050da1f6a69bbae0b1571abc8cc6a7c205e /src | |
parent | abdfdb8a4a58d36e8ac8e54736589df753225da7 (diff) |
db v4: add column last_lu_seen_ps
Location Updating procedures from both CS and PS overwrite the same
last_lu_seen field of a subscriber. For upcoming D-GSM it will be important to
distinguish those, because only CS attaches qualify for MSISDN lookup.
Add column last_lu_seen_ps, and upon PS LU, do not overwrite last_lu_seen, so
that last_lu_seen now only reflects CS LU.
In the VTY, dump both LU dates distinctively.
Change-Id: Id7fc50567211a0870ac0524f6dee94d4513781ba
Diffstat (limited to 'src')
-rw-r--r-- | src/db.c | 23 | ||||
-rw-r--r-- | src/db_hlr.c | 46 | ||||
-rw-r--r-- | src/hlr_vty_subscr.c | 14 |
3 files changed, 61 insertions, 22 deletions
@@ -28,7 +28,7 @@ #include "db_bootstrap.h" /* This constant is currently duplicated in sql/hlr.sql and must be kept in sync! */ -#define CURRENT_SCHEMA_VERSION 3 +#define CURRENT_SCHEMA_VERSION 4 #define SEL_COLUMNS \ "id," \ @@ -45,7 +45,8 @@ "lmsi," \ "ms_purged_cs," \ "ms_purged_ps," \ - "last_lu_seen" + "last_lu_seen," \ + "last_lu_seen_ps" \ static const char *stmt_sql[] = { [DB_STMT_SEL_BY_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi = ?", @@ -79,6 +80,7 @@ static const char *stmt_sql[] = { " VALUES($subscriber_id, $algo_id_3g, $k, $op, $opc, $ind_bitlen)", [DB_STMT_AUC_3G_DELETE] = "DELETE FROM auc_3g WHERE subscriber_id = $subscriber_id", [DB_STMT_SET_LAST_LU_SEEN] = "UPDATE subscriber SET last_lu_seen = datetime($val, 'unixepoch') WHERE id = $subscriber_id", + [DB_STMT_SET_LAST_LU_SEEN_PS] = "UPDATE subscriber SET last_lu_seen_ps = datetime($val, 'unixepoch') WHERE id = $subscriber_id", [DB_STMT_EXISTS_BY_IMSI] = "SELECT 1 FROM subscriber WHERE imsi = $imsi", [DB_STMT_EXISTS_BY_MSISDN] = "SELECT 1 FROM subscriber WHERE msisdn = $msisdn", }; @@ -423,11 +425,28 @@ static int db_upgrade_v3(struct db_context *dbc) return rc; } +static int db_upgrade_v4(struct db_context *dbc) +{ + int rc; + const char *statements[] = { + "ALTER TABLE subscriber ADD COLUMN last_lu_seen_ps TIMESTAMP default NULL", + "PRAGMA user_version = 4", + }; + + rc = db_run_statements(dbc, statements, ARRAY_SIZE(statements)); + if (rc != SQLITE_DONE) { + LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 4\n"); + return rc; + } + return rc; +} + typedef int (*db_upgrade_func_t)(struct db_context *dbc); static db_upgrade_func_t db_upgrade_path[] = { db_upgrade_v1, db_upgrade_v2, db_upgrade_v3, + db_upgrade_v4, }; static int db_get_user_version(struct db_context *dbc) diff --git a/src/db_hlr.c b/src/db_hlr.c index e52b5ed..b3e3887 100644 --- a/src/db_hlr.c +++ b/src/db_hlr.c @@ -438,14 +438,36 @@ out: return ret; } +static void parse_last_lu_seen(time_t *dst, const char *last_lu_seen_str, const char *imsi, const char *label) +{ + struct tm tm = {0}; + time_t val; + if (!last_lu_seen_str || last_lu_seen_str[0] == '\0') + return; + + if (strptime(last_lu_seen_str, DB_LAST_LU_SEEN_FMT, &tm) == NULL) { + LOGP(DAUC, LOGL_ERROR, "IMSI-%s: Last LU Seen %s: Cannot parse timestamp '%s'\n", + imsi, label, last_lu_seen_str); + return; + } + + errno = 0; + val = mktime(&tm); + if (val == -1) { + LOGP(DAUC, LOGL_ERROR, "IMSI-%s: Last LU Seen %s: Cannot convert timestamp '%s' to time_t: %s\n", + imsi, label, last_lu_seen_str, strerror(errno)); + val = 0; + } + + *dst = val; +} + /* Common code for db_subscr_get_by_*() functions. */ static int db_sel(struct db_context *dbc, sqlite3_stmt *stmt, struct hlr_subscriber *subscr, const char **err) { int rc; int ret = 0; - const char *last_lu_seen_str; - struct tm tm = {0}; /* execute the statement */ rc = sqlite3_step(stmt); @@ -479,20 +501,10 @@ static int db_sel(struct db_context *dbc, sqlite3_stmt *stmt, struct hlr_subscri subscr->lmsi = sqlite3_column_int(stmt, 11); subscr->ms_purged_cs = sqlite3_column_int(stmt, 12); subscr->ms_purged_ps = sqlite3_column_int(stmt, 13); - last_lu_seen_str = (const char *)sqlite3_column_text(stmt, 14); - if (last_lu_seen_str && last_lu_seen_str[0] != '\0') { - if (strptime(last_lu_seen_str, DB_LAST_LU_SEEN_FMT, &tm) == NULL) { - LOGP(DAUC, LOGL_ERROR, "Cannot parse last LU timestamp '%s' of subscriber with IMSI='%s': %s\n", - last_lu_seen_str, subscr->imsi, strerror(errno)); - } else { - subscr->last_lu_seen = mktime(&tm); - if (subscr->last_lu_seen == -1) { - LOGP(DAUC, LOGL_ERROR, "Cannot convert LU timestamp '%s' to time_t: %s\n", - last_lu_seen_str, strerror(errno)); - subscr->last_lu_seen = 0; - } - } - } + parse_last_lu_seen(&subscr->last_lu_seen, (const char *)sqlite3_column_text(stmt, 14), + subscr->imsi, "CS"); + parse_last_lu_seen(&subscr->last_lu_seen_ps, (const char *)sqlite3_column_text(stmt, 15), + subscr->imsi, "PS"); out: db_remove_reset(stmt); @@ -770,7 +782,7 @@ int db_subscr_lu(struct db_context *dbc, int64_t subscr_id, goto out; } - stmt = dbc->stmt[DB_STMT_SET_LAST_LU_SEEN]; + stmt = dbc->stmt[is_ps? DB_STMT_SET_LAST_LU_SEEN_PS : DB_STMT_SET_LAST_LU_SEEN]; if (!db_bind_int64(stmt, "$subscriber_id", subscr_id)) return -EIO; diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c index d2c4c81..b561636 100644 --- a/src/hlr_vty_subscr.c +++ b/src/hlr_vty_subscr.c @@ -47,12 +47,20 @@ get_datestr(const time_t *t, char *datebuf) return s; } +static void dump_last_lu_seen(struct vty *vty, const char *domain_label, time_t last_lu_seen) +{ + char datebuf[26]; /* for ctime_r(3) */ + if (!last_lu_seen) + return; + vty_out(vty, " last LU seen on %s: %s UTC%s", domain_label, get_datestr(&last_lu_seen, datebuf), + VTY_NEWLINE); +} + static void subscr_dump_full_vty(struct vty *vty, struct hlr_subscriber *subscr) { int rc; struct osmo_sub_auth_data aud2g; struct osmo_sub_auth_data aud3g; - char datebuf[26]; /* for ctime_r(3) */ vty_out(vty, " ID: %"PRIu64"%s", subscr->id, VTY_NEWLINE); @@ -87,8 +95,8 @@ static void subscr_dump_full_vty(struct vty *vty, struct hlr_subscriber *subscr) vty_out(vty, " PS disabled%s", VTY_NEWLINE); if (subscr->ms_purged_ps) vty_out(vty, " PS purged%s", VTY_NEWLINE); - if (subscr->last_lu_seen) - vty_out(vty, " last LU seen: %s UTC%s", get_datestr(&subscr->last_lu_seen, datebuf), VTY_NEWLINE); + dump_last_lu_seen(vty, "CS", subscr->last_lu_seen); + dump_last_lu_seen(vty, "PS", subscr->last_lu_seen_ps); if (!*subscr->imsi) return; |