diff options
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 25 | ||||
-rw-r--r-- | openbsc/src/bsc_hack.c | 23 | ||||
-rw-r--r-- | openbsc/src/db.c | 38 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08.c | 21 |
4 files changed, 72 insertions, 35 deletions
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index e8dbf87f0..b8932e901 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; @@ -48,6 +56,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/bsc_hack.c b/openbsc/src/bsc_hack.c index 13438b9cb..384da54b8 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -696,14 +696,7 @@ SYSTEM INFORMATION TYPE 3 cell not barred for access call reestablishment not allowed Access Control Class = 0000 - SI 3 Rest Octets - Cell Bar Qualify (CBQ): 0 - Cell Reselect Offset = 0 dB - Temporary Offset = 0 dB - Penalty Time = 20 s - System Information 2ter Indicator (2TI): 0 = not available - Early Classmark Sending Control (ECSC): 0 = forbidden - Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH + SI 3 Rest Octets (not present) */ static u_int8_t si3[] = { /* header */0x49, 0x06, 0x1B, @@ -713,7 +706,7 @@ static u_int8_t si3[] = { /* option*/0x28, /* selection*/0x62, 0x00, /* rach */0xD5, 0x00, 0x00, - /* reset*/0x80, 0x00, 0x00, 0x2B + /* rest */ 0x2B, 0x2B, 0x2B, 0x2B }; /* @@ -734,24 +727,20 @@ SYSTEM INFORMATION TYPE 4 cell not barred for access call reestablishment not allowed Access Control Class = 0000 - Channel Description + CBCH Channel Description Type = SDCCH/4[2] Timeslot Number: 0 Training Sequence Code: 7h ARFCN: 1 - SI Rest Octets - Cell Bar Qualify (CBQ): 0 - Cell Reselect Offset = 0 dB - Temporary Offset = 0 dB - Penalty Time = 20 s + SI Rest Octets (not present) */ static u_int8_t si4[] = { /* header */0x41, 0x06, 0x1C, /* lai */0x00, 0xF1, 0x10, 0x00, 0x01, /* sel */0x62, 0x00, /* rach*/0xD5, 0x00, 0x00, - /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00, - 0x2B, 0x2B, 0x2B + /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, + /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B }; /* diff --git a/openbsc/src/db.c b/openbsc/src/db.c index 2d9974955..fb589003d 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 (" @@ -295,6 +299,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; @@ -329,6 +364,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 4ec713d9f..f012f3c90 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; } |