aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h25
-rw-r--r--openbsc/src/db.c38
-rw-r--r--openbsc/src/gsm_04_08.c21
3 files changed, 66 insertions, 18 deletions
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index dc4f6d7a..4a231155 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -11,6 +11,18 @@
#define GSM_NAME_LENGTH 128
#define GSM_EXTENSION_LENGTH 128
+struct gsm_equipment {
+ long long unsigned int id;
+ char imei[GSM_IMEI_LENGTH];
+ char name[GSM_NAME_LENGTH];
+
+ struct gsm48_classmark1 classmark1;
+ u_int8_t classmark2_len;
+ u_int8_t classmark2[3];
+ u_int8_t classmark3_len;
+ u_int8_t classmark3[14];
+};
+
struct gsm_subscriber {
struct gsm_network *net;
long long unsigned int id;
@@ -21,18 +33,14 @@ struct gsm_subscriber {
char extension[GSM_EXTENSION_LENGTH];
int authorized;
+ /* Every user can only have one equipment in use at any given
+ * point in time */
+ struct gsm_equipment equipment;
+
/* for internal management */
int use_count;
struct llist_head entry;
- /* those are properties of the equipment, but they
- * are applicable to the subscriber at the moment */
- struct gsm48_classmark1 classmark1;
- u_int8_t classmark2_len;
- u_int8_t classmark2[3];
- u_int8_t classmark3_len;
- u_int8_t classmark3[14];
-
/* pending requests */
int in_callback;
struct llist_head requests;
@@ -47,6 +55,7 @@ enum gsm_subscriber_field {
enum gsm_subscriber_update_reason {
GSM_SUBSCRIBER_UPDATE_ATTACHED,
GSM_SUBSCRIBER_UPDATE_DETACHED,
+ GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
};
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index 600699ae..543f44ce 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -1,6 +1,7 @@
/* Simple HLR/VLR database backend using dbi */
/* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -59,6 +60,9 @@ static char *create_stmts[] = {
"created TIMESTAMP NOT NULL, "
"updated TIMESTAMP NOT NULL, "
"name TEXT, "
+ "classmark1 NUMERIC, "
+ "classmark2 BLOB, "
+ "classmark3 BLOB, "
"imei NUMERIC UNIQUE NOT NULL"
")",
"CREATE TABLE IF NOT EXISTS EquipmentWatch ("
@@ -288,6 +292,37 @@ int db_sync_subscriber(struct gsm_subscriber* subscriber) {
return 0;
}
+int db_sync_equipment(struct gsm_equipment *equip)
+{
+ dbi_result result;
+ unsigned char *cm2, *cm3;
+
+ dbi_conn_quote_binary_copy(conn, equip->classmark2,
+ equip->classmark2_len, &cm2);
+ dbi_conn_quote_binary_copy(conn, equip->classmark3,
+ equip->classmark3_len, &cm3);
+
+ result = dbi_conn_queryf(conn,
+ "UPDATE Equipment SET "
+ "updated = datetime('now'), "
+ "classmark1 = %u, "
+ "classmark2 = %s, "
+ "classmark3 = %s "
+ "WHERE imei = '%s' ",
+ equip->classmark1, cm2, cm3, equip->imei);
+
+ free(cm2);
+ free(cm3);
+
+ if (!result) {
+ printf("DB: Failed to update Equipment\n");
+ return -EIO;
+ }
+
+ dbi_result_free(result);
+ return 0;
+}
+
int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber) {
dbi_result result=NULL;
char* tmsi_quoted;
@@ -322,6 +357,9 @@ int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char imei[GSM_IM
u_int64_t equipment_id, watch_id;
dbi_result result;
+ strncpy(subscriber->equipment.imei, imei,
+ sizeof(subscriber->equipment.imei)-1),
+
result = dbi_conn_queryf(conn,
"INSERT OR IGNORE INTO Equipment "
"(imei, created, updated) "
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 2312e8ab..3e2d171e 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1469,8 +1469,9 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg)
subscr_put(subscr);
}
- subscr->classmark2_len = classmark2_len;
- memcpy(subscr->classmark2, classmark2, classmark2_len);
+ subscr->equipment.classmark2_len = classmark2_len;
+ memcpy(subscr->equipment.classmark2, classmark2, classmark2_len);
+ db_sync_equipment(&subscr->equipment);
return gsm48_tx_mm_serv_ack(msg->lchan);
}
@@ -1602,8 +1603,9 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg)
DEBUGP(DRR, "<- Channel was requested by %s\n",
subscr->name ? subscr->name : subscr->imsi);
- subscr->classmark2_len = *classmark2_lv;
- memcpy(subscr->classmark2, classmark2_lv+1, *classmark2_lv);
+ subscr->equipment.classmark2_len = *classmark2_lv;
+ memcpy(subscr->equipment.classmark2, classmark2_lv+1, *classmark2_lv);
+ db_sync_equipment(&subscr->equipment);
if (!msg->lchan->subscr) {
msg->lchan->subscr = subscr;
@@ -1667,16 +1669,15 @@ static int gsm48_rx_rr_classmark(struct msgb *msg)
DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len);
}
if (subscr) {
- subscr->classmark2_len = cm2_len;
- memcpy(subscr->classmark2, cm2, cm2_len);
+ subscr->equipment.classmark2_len = cm2_len;
+ memcpy(subscr->equipment.classmark2, cm2, cm2_len);
if (cm3) {
- subscr->classmark3_len = cm3_len;
- memcpy(subscr->classmark3, cm3, cm3_len);
+ subscr->equipment.classmark3_len = cm3_len;
+ memcpy(subscr->equipment.classmark3, cm3, cm3_len);
}
+ db_sync_equipment(&subscr->equipment);
}
- /* FIXME: store the classmark2/3 values with the equipment register */
-
return 0;
}