aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/db.c3
-rw-r--r--src/db.h9
-rw-r--r--src/db_hlr.c116
3 files changed, 128 insertions, 0 deletions
diff --git a/src/db.c b/src/db.c
index 463eeb4..7c25e63 100644
--- a/src/db.c
+++ b/src/db.c
@@ -41,6 +41,9 @@ static const char *stmt_sql[] = {
[DB_STMT_UPD_PURGE_PS_BY_IMSI] = "UPDATE subscriber SET ms_purged_ps=1 WHERE imsi = ?",
[DB_STMT_SET_NAM_PS_BY_IMSI] = "UPDATE subscriber SET nam_ps=1 WHERE imsi = ?",
[DB_STMT_UNSET_NAM_PS_BY_IMSI] = "UPDATE subscriber SET nam_ps=0 WHERE imsi = ?",
+ [DB_STMT_SUBSCR_CREATE] = "INSERT INTO subscriber (imsi) VALUES ($imsi)",
+ [DB_STMT_DEL_BY_ID] = "DELETE FROM subscriber WHERE id = $subscriber_id",
+ [DB_STMT_SET_MSISDN_BY_IMSI] = "UPDATE subscriber SET msisdn = $msisdn WHERE imsi = $imsi",
};
static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
diff --git a/src/db.h b/src/db.h
index 533c4d2..d7a8303 100644
--- a/src/db.h
+++ b/src/db.h
@@ -13,6 +13,9 @@ enum stmt_idx {
DB_STMT_UPD_PURGE_PS_BY_IMSI,
DB_STMT_SET_NAM_PS_BY_IMSI,
DB_STMT_UNSET_NAM_PS_BY_IMSI,
+ DB_STMT_SUBSCR_CREATE,
+ DB_STMT_DEL_BY_ID,
+ DB_STMT_SET_MSISDN_BY_IMSI,
_NUM_DB_STMT
};
@@ -73,6 +76,12 @@ struct hlr_subscriber {
bool ms_purged_ps;
};
+int db_subscr_create(struct db_context *dbc, const char *imsi);
+int db_subscr_delete_by_id(struct db_context *dbc, int64_t subscr_id);
+
+int db_subscr_update_msisdn_by_imsi(struct db_context *dbc, const char *imsi,
+ const char *msisdn);
+
int db_subscr_get_by_imsi(struct db_context *dbc, const char *imsi,
struct hlr_subscriber *subscr);
int db_subscr_ps(struct db_context *dbc, const char *imsi, bool enable);
diff --git a/src/db_hlr.c b/src/db_hlr.c
index 5db2c9e..b232dfd 100644
--- a/src/db_hlr.c
+++ b/src/db_hlr.c
@@ -19,9 +19,11 @@
#include <string.h>
#include <errno.h>
+#include <inttypes.h>
#include <osmocom/core/utils.h>
#include <osmocom/crypt/auth.h>
+#include <osmocom/gsm/gsm23003.h>
#include <sqlite3.h>
@@ -38,6 +40,120 @@
x[sizeof(x)-1] = '\0'; \
} while (0)
+int db_subscr_create(struct db_context *dbc, const char *imsi)
+{
+ sqlite3_stmt *stmt;
+ int rc;
+
+ if (!osmo_imsi_str_valid(imsi)) {
+ LOGP(DAUC, LOGL_ERROR, "Cannot create subscriber: invalid IMSI: '%s'\n",
+ imsi);
+ return -EINVAL;
+ }
+
+ stmt = dbc->stmt[DB_STMT_SUBSCR_CREATE];
+
+ if (!db_bind_text(stmt, "$imsi", imsi))
+ return -EIO;
+
+ /* execute the statement */
+ rc = sqlite3_step(stmt);
+ db_remove_reset(stmt);
+ if (rc != SQLITE_DONE) {
+ LOGHLR(imsi, LOGL_ERROR, "Cannot create subscriber: SQL error: (%d) %s\n",
+ rc, sqlite3_errmsg(dbc->db));
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int db_subscr_delete_by_id(struct db_context *dbc, int64_t subscr_id)
+{
+ int rc;
+ int ret = 0;
+
+ sqlite3_stmt *stmt = dbc->stmt[DB_STMT_DEL_BY_ID];
+
+ if (!db_bind_int64(stmt, "$subscriber_id", subscr_id))
+ return -EIO;
+
+ /* execute the statement */
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOGP(DAUC, LOGL_ERROR,
+ "Cannot delete subscriber ID=%"PRId64": SQL error: (%d) %s\n",
+ subscr_id, rc, sqlite3_errmsg(dbc->db));
+ db_remove_reset(stmt);
+ return -EIO;
+ }
+
+ /* verify execution result */
+ rc = sqlite3_changes(dbc->db);
+ if (!rc) {
+ LOGP(DAUC, LOGL_ERROR, "Cannot delete: no such subscriber: ID=%"PRId64"\n",
+ subscr_id);
+ ret = -ENOENT;
+ } else if (rc != 1) {
+ LOGP(DAUC, LOGL_ERROR, "Delete subscriber ID=%"PRId64
+ ": SQL modified %d rows (expected 1)\n", subscr_id, rc);
+ ret = -EIO;
+ }
+
+ /* FIXME: also remove authentication data from auc_2g and auc_3g */
+
+ db_remove_reset(stmt);
+ return ret;
+}
+
+int db_subscr_update_msisdn_by_imsi(struct db_context *dbc, const char *imsi,
+ const char *msisdn)
+{
+ int rc;
+ int ret = 0;
+
+ if (!osmo_msisdn_str_valid(msisdn)) {
+ LOGHLR(imsi, LOGL_ERROR,
+ "Cannot update subscriber: invalid MSISDN: '%s'\n",
+ msisdn);
+ return -EINVAL;
+ }
+
+ sqlite3_stmt *stmt = dbc->stmt[DB_STMT_SET_MSISDN_BY_IMSI];
+
+ if (!db_bind_text(stmt, "$imsi", imsi))
+ return -EIO;
+ if (!db_bind_text(stmt, "$msisdn", msisdn))
+ return -EIO;
+
+ /* execute the statement */
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ LOGHLR(imsi, LOGL_ERROR,
+ "Cannot update subscriber's MSISDN: SQL error: (%d) %s\n",
+ 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 MSISDN: no such subscriber: IMSI='%s'\n",
+ imsi);
+ ret = -ENOENT;
+ goto out;
+ } else if (rc != 1) {
+ LOGHLR(imsi, LOGL_ERROR, "Update MSISDN: SQL modified %d rows (expected 1)\n", rc);
+ ret = -EIO;
+ }
+
+out:
+ db_remove_reset(stmt);
+ return ret;
+
+}
+
int db_subscr_get_by_imsi(struct db_context *dbc, const char *imsi,
struct hlr_subscriber *subscr)
{