diff options
author | Stefan Sperling <ssperling@sysmocom.de> | 2018-12-04 15:07:29 +0100 |
---|---|---|
committer | Stefan Sperling <ssperling@sysmocom.de> | 2018-12-07 11:50:06 +0100 |
commit | 638ba8cc049b35c1a6a604fb058a92cff68198e1 (patch) | |
tree | b0df5bba90af21e8699173858b9aeefff47268d1 /src/db_hlr.c | |
parent | 55f5efa5681fe7456d0c7adbee324dbeff2a283e (diff) |
store a timestamp of the last location update seen from a subscriber
Timestamps are stored in the HLR DB in the new 'last_lu_seen' column
of the 'subscriber' table, in UTC and in granularity of seconds.
At present, osmo-hlr only records these timestamps but otherwise
makes no use of them. Because the timestamps are stored in a
human-readable form, they may already provide value to external
processes which need this information. For example:
sqlite> select imsi,last_lu_seen from subscriber;
901990000000001|2018-12-04 14:17:12
I didn't bother adding additional tests because the code added
with this commit is already being exercised by several calls
to db_subscr_lu() in db_test.c.
This change requires a HLR DB schema update. Existing databases
won't be upgraded automatically. However, osmo-hlr will refuse
to operate with databases which are not upgraded.
Change-Id: Ibeb49d45aec18451a260a6654b8c51b8fc3bec50
Related: OS#2838
Diffstat (limited to 'src/db_hlr.c')
-rw-r--r-- | src/db_hlr.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/db_hlr.c b/src/db_hlr.c index 2bccc38..342698e 100644 --- a/src/db_hlr.c +++ b/src/db_hlr.c @@ -20,6 +20,7 @@ #include <string.h> #include <errno.h> #include <inttypes.h> +#include <time.h> #include <osmocom/core/utils.h> #include <osmocom/crypt/auth.h> @@ -577,6 +578,7 @@ int db_subscr_lu(struct db_context *dbc, int64_t subscr_id, { sqlite3_stmt *stmt; int rc, ret = 0; + struct timespec localtime; stmt = dbc->stmt[is_ps ? DB_STMT_UPD_SGSN_BY_ID : DB_STMT_UPD_VLR_BY_ID]; @@ -603,13 +605,54 @@ int db_subscr_lu(struct db_context *dbc, int64_t subscr_id, ": no such subscriber\n", is_ps? "SGSN" : "VLR", subscr_id); ret = -ENOENT; + goto out; } else if (rc != 1) { LOGP(DAUC, LOGL_ERROR, "Update %s number for subscriber ID=%"PRId64 ": SQL modified %d rows (expected 1)\n", is_ps? "SGSN" : "VLR", subscr_id, rc); ret = -EIO; + goto out; + } + + db_remove_reset(stmt); + + if (osmo_clock_gettime(CLOCK_REALTIME, &localtime) != 0) { + LOGP(DAUC, LOGL_ERROR, "Cannot get the current time: (%d) %s\n", errno, strerror(errno)); + ret = -errno; + goto out; + } + + stmt = dbc->stmt[DB_STMT_SET_LAST_LU_SEEN]; + + if (!db_bind_int64(stmt, "$subscriber_id", subscr_id)) + return -EIO; + /* The timestamp will be converted to UTC by SQLite. */ + if (!db_bind_int64(stmt, "$val", (int64_t)localtime.tv_sec)) { + ret = -EIO; + goto out; } + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + LOGP(DAUC, LOGL_ERROR, + "Cannot update LU timestamp for subscriber ID=%"PRId64": SQL error: (%d) %s\n", + subscr_id, rc, sqlite3_errmsg(dbc->db)); + ret = -EIO; + goto out; + } + + /* verify execution result */ + rc = sqlite3_changes(dbc->db); + if (!rc) { + LOGP(DAUC, LOGL_ERROR, "Cannot update LU timestamp for subscriber ID=%"PRId64 + ": no such subscriber\n", subscr_id); + ret = -ENOENT; + goto out; + } else if (rc != 1) { + LOGP(DAUC, LOGL_ERROR, "Update LU timestamp for subscriber ID=%"PRId64 + ": SQL modified %d rows (expected 1)\n", subscr_id, rc); + ret = -EIO; + } out: db_remove_reset(stmt); return ret; |