From patchwork Thu Mar 31 07:23:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Yanitskiy X-Patchwork-Id: 603952 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by ozlabs.org (Postfix) with ESMTP id 3qbGJ25mRFz9sDH for ; Thu, 31 Mar 2016 18:25:21 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=kxJZCYyu; dkim-atps=neutral Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id D7E3C1C27A; Thu, 31 Mar 2016 07:25:16 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from mail-lb0-x22f.google.com (mail-lb0-x22f.google.com [IPv6:2a00:1450:4010:c04::22f]) by lists.osmocom.org (Postfix) with ESMTP id 82FB51C262 for ; Thu, 31 Mar 2016 07:25:13 +0000 (UTC) Received: by mail-lb0-x22f.google.com with SMTP id qe11so46711097lbc.3 for ; Thu, 31 Mar 2016 00:25:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mlgZyeDvWSwmksqgIbHGh9yDrz92gvP0tOf3ItHPfGI=; b=kxJZCYyu0RRIYpv1gSwPxOAE9hrXj0MCGqBYEGGIovfobEeOfzj/JYLgi56I79OQa+ 8s0qyjWgMqU9fcOLp+l4wk2ThsvL+cj0dK5WWdo1Wj7oStnfFR8CnOG6xyXHbxng2TZr OfWKnWLu8ihx74eWkHbBiJqKDdgsh0SSAOBY4SA/MTYJ7TcA8Q5KXjGe+ESd2KQNkZ3l QXWoKxlLjmlzUd9JrkpRDeA2/5xDGImAHCvh08MfnG0ebiHFUX2P3vNqZA+yFE6cdwm/ XCnoWmPFR/32TEcLobSbOzfwADVcaExNXprqz5yoh0p4Sce+pbUBAUPEa7D7B+3DkAbg Fa4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mlgZyeDvWSwmksqgIbHGh9yDrz92gvP0tOf3ItHPfGI=; b=GJ8OXEr4lxUzLaVoXqeYmpvLiDyYDOxfZ0w3jPkqljzXGk94bUb4HCGUUVy/JY8THX O9V48s+u7E4+4MtW8orjogZysau32m8G4ny9ca3v0csHsCjk9d7T4AEV86IHyhVAYVnE xnDh+acfw8E2iLrrAyngB1ksWPIxD6D1rmRCtkJAeX1W+8d5UMfFcAWZtt+f0EJBuXKV hlovOjc41KgXeU1pSk+kehCqoMSYhgXKBSTARgMyHC/IusK9au0NJLjc4LXstKDtT2R0 wqWDfeLeKbCAGV/1oUxWZ7Cu6PQLt2cQVzXZHVVj3qj9JocHcSM8CQyvYDiYrHZlWzZc 6wrA== X-Gm-Message-State: AD7BkJKhpnC1d/AjxgZ4qdI7+2O35VBy5ZqTUilTeeQUQ5rhXm9RT3FXO3/F9NoSmksRdQ== X-Received: by 10.112.55.200 with SMTP id u8mr5782212lbp.51.1459409113089; Thu, 31 Mar 2016 00:25:13 -0700 (PDT) Received: from localhost.localdomain ([212.164.216.34]) by smtp.gmail.com with ESMTPSA id iy8sm1108596lbc.20.2016.03.31.00.25.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 31 Mar 2016 00:25:12 -0700 (PDT) From: Vadim Yanitskiy To: laforge@gnumonks.org, holger@freyther.de Subject: [PATCH] move to hex TMSI representation Date: Thu, 31 Mar 2016 13:23:56 +0600 Message-Id: <1459409036-15607-1-git-send-email-axilirator@gmail.com> X-Mailer: git-send-email 2.8.0 In-Reply-To: References: X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Development of OpenBSC, OsmoBSC, OsmoNITB, OsmoCSCN" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vadim Yanitskiy , openbsc@lists.osmocom.org Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" In OpenBSC, we traditionally displayed a TMSI in its integer representation, which is quite unusual in the telecom world. A TMSI is normally printed as a series of 8 hex digits. This patch aligns OpenBSC with the telecom industry standard and should be applied with corresponding patch for libosmocore. - Use hex representation in VTY - Increased DB SCHEMA_REVISION - Implemented DB migration code db_test is temporary broken because incremental migration isn't implemented yet (WIP). Signed-off-by: Vadim Yanitskiy --- openbsc/include/openbsc/gsm_subscriber.h | 2 +- openbsc/src/libmsc/db.c | 155 +++++++++++++++++++++++++----- openbsc/src/libmsc/vty_interface_layer3.c | 3 +- openbsc/tests/gsm0408/gsm0408_test.c | 2 +- 4 files changed, 133 insertions(+), 29 deletions(-) diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 7d6c776..785dc36 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -14,7 +14,7 @@ #define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 /* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */ -#define tmsi_from_string(str) strtoul(str, NULL, 10) +#define tmsi_from_string(str) strtoul(str + 2, NULL, 16) #define GSM_SUBSCRIBER_NO_EXPIRATION 0x0 diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 0935fc5..04aee79 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -47,7 +47,7 @@ static char *db_basename = NULL; static char *db_dirname = NULL; static dbi_conn conn; -#define SCHEMA_REVISION "4" +#define SCHEMA_REVISION "5" enum { SCHEMA_META, @@ -83,7 +83,7 @@ static const char *create_stmts[] = { "name TEXT, " "extension TEXT UNIQUE, " "authorized INTEGER NOT NULL DEFAULT 0, " - "tmsi TEXT UNIQUE, " + "tmsi INTEGER UNIQUE, " "lac INTEGER NOT NULL DEFAULT 0, " "expire_lu TIMESTAMP DEFAULT NULL" ")", @@ -212,6 +212,7 @@ static int update_db_revision_2(void) } dbi_result_free(result); + LOGP(DDB, LOGL_NOTICE, "Migration complete.\n"); return 0; } @@ -357,6 +358,7 @@ static int update_db_revision_3(void) else dbi_result_free(result); + LOGP(DDB, LOGL_NOTICE, "Migration complete.\n"); return 0; rollback: @@ -369,6 +371,108 @@ rollback: return -EINVAL; } +static int update_db_revision_4(void) +{ + dbi_result result; + + LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 4\n"); + + result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to begin transaction " + "(upgrade from rev 4)\n"); + return -EINVAL; + } + dbi_result_free(result); + + /* Rename old Subscriber table to be able create a new one */ + result = dbi_conn_query(conn, + "ALTER TABLE Subscriber RENAME TO Subscriber_4"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to rename the old Subscriber table " + "(upgrade from rev 4).\n"); + goto rollback; + } + dbi_result_free(result); + + /* Create new Subscriber table */ + result = dbi_conn_query(conn, create_stmts[SCHEMA_SUBSCRIBER]); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to create a new Subscriber table " + "(upgrade from rev 4).\n"); + goto rollback; + } + dbi_result_free(result); + + /* Copy subscriber data into the new table */ + result = dbi_conn_query(conn, + "INSERT INTO Subscriber " + "SELECT * FROM Subscriber_4"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to copy subscriber data into the new table " + "(upgrade from rev 4).\n"); + goto rollback; + } + dbi_result_free(result); + + /* Remove the temporary table */ + result = dbi_conn_query(conn, "DROP TABLE Subscriber_4"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to drop the old Subscriber table " + "(upgrade from rev 4).\n"); + goto rollback; + } + dbi_result_free(result); + + /* We're done. Bump DB Meta revision to 5 */ + result = dbi_conn_query(conn, + "UPDATE Meta " + "SET value = '5' " + "WHERE key = 'revision'"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to update DB schema revision " + "(upgrade from rev 4).\n"); + goto rollback; + } + dbi_result_free(result); + + result = dbi_conn_query(conn, "COMMIT TRANSACTION"); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to commit the transaction " + "(upgrade from rev 4)\n"); + return -EINVAL; + } + + /* Shrink DB file size by actually wiping out Subscriber_4 table data */ + result = dbi_conn_query(conn, "VACUUM"); + if (!result) + LOGP(DDB, LOGL_ERROR, + "VACUUM failed. Ignoring it " + "(upgrade from rev 4).\n"); + else + dbi_result_free(result); + + LOGP(DDB, LOGL_NOTICE, "Migration complete.\n"); + return 0; + +rollback: + result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); + if (!result) + LOGP(DDB, LOGL_ERROR, + "Rollback failed " + "(upgrade from rev 4).\n"); + else + dbi_result_free(result); + return -EINVAL; +} + static int check_db_revision(void) { dbi_result result; @@ -388,20 +492,18 @@ static int check_db_revision(void) dbi_result_free(result); return -EINVAL; } - if (!strcmp(rev_s, "2")) { - if (update_db_revision_2()) { - LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%s'.\n", rev_s); - dbi_result_free(result); - return -EINVAL; - } - } else if (!strcmp(rev_s, "3")) { - if (update_db_revision_3()) { - LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%s'.\n", rev_s); - dbi_result_free(result); - return -EINVAL; - } - } else if (!strcmp(rev_s, SCHEMA_REVISION)) { + + if (!strcmp(rev_s, SCHEMA_REVISION)) { /* everything is fine */ + } else if (!strcmp(rev_s, "2")) { + if (update_db_revision_2()) + goto error; + } else if (!strcmp(rev_s, "3")) { + if (update_db_revision_3()) + goto error; + } else if (!strcmp(rev_s, "4")) { + if (update_db_revision_4()) + goto error; } else { LOGP(DDB, LOGL_FATAL, "Invalid database schema revision '%s'.\n", rev_s); dbi_result_free(result); @@ -410,6 +512,11 @@ static int check_db_revision(void) dbi_result_free(result); return 0; + +error: + LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%s'.\n", rev_s); + dbi_result_free(result); + return -EINVAL; } static int db_configure(void) @@ -808,10 +915,6 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) if (string) strncpy(subscr->imsi, string, GSM_IMSI_LENGTH-1); - string = dbi_result_get_string(result, "tmsi"); - if (string) - subscr->tmsi = tmsi_from_string(string); - string = dbi_result_get_string(result, "name"); if (string) strncpy(subscr->name, string, GSM_NAME_LENGTH); @@ -820,7 +923,8 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) if (string) strncpy(subscr->extension, string, GSM_EXTENSION_LENGTH); - subscr->lac = dbi_result_get_ulonglong(result, "lac"); + subscr->tmsi = dbi_result_get_ulonglong(result, "tmsi"); + subscr->lac = dbi_result_get_ulonglong(result, "lac"); if (!dbi_result_field_is_null(result, "expire_lu")) subscr->expire_lu = dbi_result_get_datetime(result, "expire_lu"); @@ -828,7 +932,6 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) subscr->expire_lu = GSM_SUBSCRIBER_NO_EXPIRATION; subscr->authorized = dbi_result_get_ulonglong(result, "authorized"); - } #define BASE_QUERY "SELECT * FROM Subscriber " @@ -893,9 +996,10 @@ struct gsm_subscriber *db_get_subscriber(enum gsm_subscriber_field field, subscr->id = dbi_result_get_ulonglong(result, "id"); db_set_from_query(subscr, result); - DEBUGP(DDB, "Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', LAC %hu, AUTH %u\n", - subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension, - subscr->lac, subscr->authorized); + DEBUGP(DDB, "Found Subscriber: ID %llu, IMSI %s, NAME '%s', " + "TMSI 0x%08x, EXTEN '%s', LAC %hu, AUTH %u\n", + subscr->id, subscr->imsi, subscr->name, subscr->tmsi, + subscr->extension, subscr->lac, subscr->authorized); dbi_result_free(result); get_equipment_by_subscr(subscr); @@ -998,7 +1102,6 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber) } dbi_result_free(result); - return 0; } @@ -1225,7 +1328,7 @@ int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber) } if (!dbi_result_next_row(result)) { dbi_result_free(result); - DEBUGP(DDB, "Allocated TMSI %u for IMSI %s.\n", + DEBUGP(DDB, "Allocated TMSI 0x%08x for IMSI %s.\n", subscriber->tmsi, subscriber->imsi); return db_sync_subscriber(subscriber); } diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index f49c53a..9879a53 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -189,7 +189,8 @@ static struct gsm_subscriber *get_subscr_by_argv(struct gsm_network *gsmnet, else if (!strcmp(type, "imsi")) return subscr_get_by_imsi(gsmnet->subscr_group, id); else if (!strcmp(type, "tmsi")) - return subscr_get_by_tmsi(gsmnet->subscr_group, atoi(id)); + return subscr_get_by_tmsi(gsmnet->subscr_group, + tmsi_from_string(id)); else if (!strcmp(type, "id")) return subscr_get_by_id(gsmnet->subscr_group, atoi(id)); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 781ef61..8ed57ca 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -93,7 +93,7 @@ static void test_mi_functionality(void) /* tmsi code */ mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi); gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len - 2); - COMPARE((uint32_t)strtoul(mi_parsed, NULL, 10), ==, tmsi); + COMPARE((uint32_t)tmsi_from_string(mi_parsed), ==, tmsi); /* imsi code */ mi_len = gsm48_generate_mid_from_imsi(mi, imsi_odd);