aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libmsc/db.c')
-rw-r--r--openbsc/src/libmsc/db.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c
index bdecbb436..4acd76566 100644
--- a/openbsc/src/libmsc/db.c
+++ b/openbsc/src/libmsc/db.c
@@ -38,6 +38,8 @@
#include <osmocom/core/statistics.h>
#include <osmocom/core/rate_ctr.h>
+#include <osmocom/gsm/protocol/gsm_09_02.h>
+
/* Semi-Private-Interface (SPI) for the subscriber code */
void subscr_direct_free(struct gsm_subscriber *subscr);
@@ -174,6 +176,15 @@ static const char *create_stmts[] = {
"sres BLOB NOT NULL, "
"kc BLOB NOT NULL "
")",
+ "CREATE TABLE IF NOT EXISTS SS_Status ("
+ "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
+ "subscriber INTEGER NOT NULL, "
+ "ss_code TINYINT UNSIGNED NOT NULL, "
+ "bs_code TINYINT UNSIGNED, "
+ "ss_status TINYINT UNSIGNED NOT NULL, "
+ "UNIQUE(subscriber, ss_code, bs_code), "
+ "FOREIGN KEY(subscriber) REFERENCES Subscriber (id) ON DELETE CASCADE ON UPDATE CASCADE "
+ ")",
};
void db_error_func(dbi_conn conn, void *data)
@@ -1724,3 +1735,81 @@ int db_store_rate_ctr_group(struct rate_ctr_group *ctrg)
return 0;
}
+
+int db_ss_interrogate_status(struct gsm_subscriber *subscr, uint8_t ss_code, uint8_t bs_code, uint8_t *ss_status)
+{
+ char buf[32];
+ dbi_result result;
+
+ /* Copy the id to a string as queryf with %llu is failing */
+ sprintf(buf, "%llu", subscr->id);
+ result = dbi_conn_queryf(conn,
+ "SELECT ss_status FROM SS_Status "
+ "WHERE subscriber = %s "
+ "AND ss_code = %i AND bs_code = %i",
+ buf, ss_code, bs_code);
+
+ if (!result) {
+ LOGP(DDB,
+ LOGL_ERROR,
+ "Failed to query ss_status for subscriber %llu, "
+ "ss code 0x%02X, bs code 0x%02X\n",
+ subscr->id, ss_code, bs_code);
+ return -EIO;
+ }
+ if (!dbi_result_next_row(result)) {
+ DEBUGP(DDB,
+ "Failed to find ss_status for subscriber %llu, "
+ "ss code 0x%02X, bs code 0x%02X\n",
+ subscr->id, ss_code, bs_code);
+ dbi_result_free(result);
+ return -ENOENT;
+ }
+
+ *ss_status = dbi_result_get_uint(result, "ss_status");
+ DEBUGP(DDB,
+ "Found ss_status for subscriber %llu, "
+ "ss code 0x%02X, bs code 0x%02X: P:%d R:%d A:%d Q:%d\n",
+ subscr->id, ss_code, bs_code,
+ (*ss_status & GSM0902_SS_STATUS_P_BIT) && 1,
+ (*ss_status & GSM0902_SS_STATUS_R_BIT) && 1,
+ (*ss_status & GSM0902_SS_STATUS_A_BIT) && 1,
+ (*ss_status & GSM0902_SS_STATUS_Q_BIT) && 1);
+
+ dbi_result_free(result);
+ return 0;
+}
+
+int db_ss_set_status(struct gsm_subscriber *subscr, uint8_t ss_code, uint8_t bs_code, uint8_t ss_status)
+{
+ char buf[32];
+ dbi_result result;
+
+ /* Copy the id to a string as queryf with %llu is failing */
+ sprintf(buf, "%llu", subscr->id);
+
+ result = dbi_conn_queryf(conn,
+ "UPDATE SS_Status SET ss_status = %i "
+ "WHERE subscriber = %s AND "
+ "ss_code = %i AND bs_code = %i",
+ ss_status, buf, ss_code, bs_code);
+
+ if (!result) {
+ LOGP(DDB, LOGL_ERROR,
+ "Failed to set ss_status for subscriber %llu\n",
+ subscr->id);
+ return -EIO;
+ }
+
+ DEBUGP(DDB,
+ "Set ss_status for subscriber %llu, "
+ "ss code 0x%02X, bs code 0x%02X: P:%d R:%d A:%d Q:%d\n",
+ subscr->id, ss_code, bs_code,
+ (ss_status & GSM0902_SS_STATUS_P_BIT) && 1,
+ (ss_status & GSM0902_SS_STATUS_R_BIT) && 1,
+ (ss_status & GSM0902_SS_STATUS_A_BIT) && 1,
+ (ss_status & GSM0902_SS_STATUS_Q_BIT) && 1);
+
+ dbi_result_free(result);
+ return 0;
+}