aboutsummaryrefslogtreecommitdiffstats
path: root/src/db_hlr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/db_hlr.c')
-rw-r--r--src/db_hlr.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/db_hlr.c b/src/db_hlr.c
index 030a6a7..b13763a 100644
--- a/src/db_hlr.c
+++ b/src/db_hlr.c
@@ -884,3 +884,106 @@ out:
return ret;
}
+
+static int _db_ind_run(struct db_context *dbc, sqlite3_stmt *stmt, const char *vlr, bool reset)
+{
+ int rc;
+
+ if (!db_bind_text(stmt, "$vlr", vlr))
+ return -EIO;
+
+ /* execute the statement */
+ rc = sqlite3_step(stmt);
+ if (reset)
+ db_remove_reset(stmt);
+ return rc;
+}
+
+static int _db_ind_add(struct db_context *dbc, const char *vlr)
+{
+ sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_ADD];
+ if (_db_ind_run(dbc, stmt, vlr, true) != SQLITE_DONE) {
+ LOGP(DDB, LOGL_ERROR, "Cannot create IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr, -1));
+ return -EIO;
+ }
+ return 0;
+}
+
+static int _db_ind_del(struct db_context *dbc, const char *vlr)
+{
+ sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_DEL];
+ _db_ind_run(dbc, stmt, vlr, true);
+ /* We don't really care about the result. If it didn't exist, then that was the goal anyway. */
+ return 0;
+}
+
+static int _db_ind_get(struct db_context *dbc, const char *vlr, unsigned int *ind)
+{
+ int ret = 0;
+ sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_SELECT];
+ int rc = _db_ind_run(dbc, stmt, vlr, false);
+ if (rc == SQLITE_DONE) {
+ /* Does not exist yet */
+ ret = -ENOENT;
+ goto out;
+ } else if (rc != SQLITE_ROW) {
+ LOGP(DDB, LOGL_ERROR, "Error executing SQL: %d\n", rc);
+ ret = -EIO;
+ goto out;
+ }
+
+ OSMO_ASSERT(ind);
+ *ind = sqlite3_column_int64(stmt, 0);
+out:
+ db_remove_reset(stmt);
+ return ret;
+}
+
+int _db_ind(struct db_context *dbc, const struct osmo_gsup_peer_id *vlr,
+ unsigned int *ind, bool del)
+{
+ const char *vlr_name = NULL;
+ int rc;
+
+ switch (vlr->type) {
+ case OSMO_GSUP_PEER_ID_IPA_NAME:
+ if (vlr->ipa_name.len < 2 || vlr->ipa_name.val[vlr->ipa_name.len - 1] != '\0') {
+ LOGP(DDB, LOGL_ERROR, "Expecting VLR ipa_name to be zero terminated; found %s\n",
+ osmo_ipa_name_to_str(&vlr->ipa_name));
+ return -ENOTSUP;
+ }
+ vlr_name = (const char*)vlr->ipa_name.val;
+ break;
+ default:
+ LOGP(DDB, LOGL_ERROR, "Unsupported osmo_gsup_peer_id type: %s\n",
+ osmo_gsup_peer_id_type_name(vlr->type));
+ return -ENOTSUP;
+ }
+
+ if (del)
+ return _db_ind_del(dbc, vlr_name);
+
+ rc = _db_ind_get(dbc, vlr_name, ind);
+ if (!rc)
+ return 0;
+
+ /* Does not exist yet, create. */
+ rc = _db_ind_add(dbc, vlr_name);
+ if (rc) {
+ LOGP(DDB, LOGL_ERROR, "Error creating IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr_name, -1));
+ return rc;
+ }
+
+ /* To be sure, query again from scratch. */
+ return _db_ind_get(dbc, vlr_name, ind);
+}
+
+int db_ind(struct db_context *dbc, const struct osmo_gsup_peer_id *vlr, unsigned int *ind)
+{
+ return _db_ind(dbc, vlr, ind, false);
+}
+
+int db_ind_del(struct db_context *dbc, const struct osmo_gsup_peer_id *vlr)
+{
+ return _db_ind(dbc, vlr, NULL, true);
+}