Change in osmo-hlr[master]: store timestamp of last location update seen from subscriber

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Stefan Sperling gerrit-no-reply at lists.osmocom.org
Tue Dec 4 15:40:03 UTC 2018


Stefan Sperling has uploaded this change for review. ( https://gerrit.osmocom.org/12121


Change subject: store timestamp of last location update seen from subscriber
......................................................................

store timestamp of last location update seen from subscriber

Store a timestamp of the last location update seen from a subscriber
in the HLR DB. Timestamps are stored in a new 'last_lu_seen' column
in the 'subscriber' table, 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 formt, 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
---
M sql/hlr.sql
M src/db.c
M src/db.h
M src/db_hlr.c
4 files changed, 104 insertions(+), 5 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/21/12121/1

diff --git a/sql/hlr.sql b/sql/hlr.sql
index 3499109..d1db256 100644
--- a/sql/hlr.sql
+++ b/sql/hlr.sql
@@ -36,7 +36,10 @@
 	-- Chapter 2.7.5
 	ms_purged_cs	BOOLEAN NOT NULL DEFAULT 0,
 	-- Chapter 2.7.6
-	ms_purged_ps	BOOLEAN NOT NULL DEFAULT 0
+	ms_purged_ps	BOOLEAN NOT NULL DEFAULT 0,
+
+	-- Timestamp of last location update seen from subscriber
+	last_lu_seen TIMESTAMP default NULL
 );
 
 CREATE TABLE subscriber_apn (
@@ -69,4 +72,4 @@
 CREATE UNIQUE INDEX idx_subscr_imsi ON subscriber (imsi);
 
 -- Set HLR database schema version number
-PRAGMA user_version = 0;
+PRAGMA user_version = 1;
diff --git a/src/db.c b/src/db.c
index df52f9b..70b5a26 100644
--- a/src/db.c
+++ b/src/db.c
@@ -27,7 +27,7 @@
 #include "db.h"
 #include "db_bootstrap.h"
 
-#define CURRENT_SCHEMA_VERSION	0
+#define CURRENT_SCHEMA_VERSION	1
 
 #define SEL_COLUMNS \
 	"id," \
@@ -42,7 +42,8 @@
 	"nam_ps," \
 	"lmsi," \
 	"ms_purged_cs," \
-	"ms_purged_ps"
+	"ms_purged_ps," \
+	"last_lu_seen"
 
 static const char *stmt_sql[] = {
 	[DB_STMT_SEL_BY_IMSI] = "SELECT " SEL_COLUMNS " FROM subscriber WHERE imsi = ?",
@@ -73,6 +74,7 @@
 		"INSERT INTO auc_3g (subscriber_id, algo_id_3g, k, op, opc, ind_bitlen)"
 		" 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",
 };
 
 static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
@@ -252,6 +254,41 @@
 	return true;
 }
 
+static int
+db_upgrade_v1(struct db_context *dbc)
+{
+	sqlite3_stmt *stmt;
+	int rc;
+	const char *update_stmt_sql = "ALTER TABLE subscriber ADD COLUMN last_lu_seen TIMESTAMP default NULL";
+	const char *set_schema_version_sql = "PRAGMA user_version = 1";
+
+	rc = sqlite3_prepare_v2(dbc->db, update_stmt_sql, -1, &stmt, NULL);
+	if (rc != SQLITE_OK) {
+		LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", update_stmt_sql);
+		return rc;
+	}
+	rc = sqlite3_step(stmt);
+	db_remove_reset(stmt);
+	sqlite3_finalize(stmt);
+	if (rc != SQLITE_DONE) {
+		LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version %d\n", 1);
+		return rc;
+	}
+
+	rc = sqlite3_prepare_v2(dbc->db, set_schema_version_sql, -1, &stmt, NULL);
+	if (rc != SQLITE_OK) {
+		LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", set_schema_version_sql);
+		return rc;
+	}
+	rc = sqlite3_step(stmt);
+	if (rc != SQLITE_DONE)
+		LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version %d\n", 1);
+
+	db_remove_reset(stmt);
+	sqlite3_finalize(stmt);
+	return rc;
+}
+
 static int db_get_user_version(struct db_context *dbc)
 {
 	const char *user_version_sql = "PRAGMA user_version";
@@ -346,12 +383,28 @@
 			     rc, sqlite3_errmsg(dbc->db));
 			goto out_free;
 		}
+		version = CURRENT_SCHEMA_VERSION;
 	}
 
 	LOGP(DDB, LOGL_NOTICE, "Database '%s' has HLR DB schema version %d\n", dbc->fname, version);
 
 	if (version < CURRENT_SCHEMA_VERSION && allow_upgrade) {
-		/* Future version upgrades will happen here. */
+		switch (version) {
+		case 0:
+			rc = db_upgrade_v1(dbc);
+			if (rc != SQLITE_DONE) {
+				LOGP(DDB, LOGL_ERROR, "Failed to upgrade HLR DB schema to version 1: (rc=%d) %s\n",
+				     rc, sqlite3_errmsg(dbc->db));
+				goto out_free;
+			}
+			version = 1;
+			/* fall through */
+		/* case N: ... */
+		default:
+			break;
+		}
+		LOGP(DDB, LOGL_NOTICE, "Database '%s' has been upgraded to HLR DB schema version %d\n",
+		     dbc->fname, version);
 	}
 
 	if (version != CURRENT_SCHEMA_VERSION) {
diff --git a/src/db.h b/src/db.h
index 66dfe57..5129b8d 100644
--- a/src/db.h
+++ b/src/db.h
@@ -25,6 +25,7 @@
 	DB_STMT_AUC_2G_DELETE,
 	DB_STMT_AUC_3G_INSERT,
 	DB_STMT_AUC_3G_DELETE,
+	DB_STMT_SET_LAST_LU_SEEN,
 	_NUM_DB_STMT
 };
 
diff --git a/src/db_hlr.c b/src/db_hlr.c
index 2bccc38..81897a8 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 @@
 {
 	sqlite3_stmt *stmt;
 	int rc, ret = 0;
+	struct timespec t;
 
 	stmt = dbc->stmt[is_ps ? DB_STMT_UPD_SGSN_BY_ID
 			       : DB_STMT_UPD_VLR_BY_ID];
@@ -603,13 +605,53 @@
 		     ": 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 (clock_gettime(CLOCK_MONOTONIC, &t) != 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;
+	if (!db_bind_int64(stmt, "$val", (int64_t)t.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;

-- 
To view, visit https://gerrit.osmocom.org/12121
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibeb49d45aec18451a260a6654b8c51b8fc3bec50
Gerrit-Change-Number: 12121
Gerrit-PatchSet: 1
Gerrit-Owner: Stefan Sperling <stsp at stsp.name>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20181204/b24badd8/attachment.htm>


More information about the gerrit-log mailing list