aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Smith <osmith@sysmocom.de>2019-01-11 15:41:29 +0100
committerHarald Welte <laforge@gnumonks.org>2019-01-24 15:29:08 +0000
commit02078b7d917fc7c8cd019d5ed357cf3110905e9b (patch)
tree0f5d1f56a7af1ba114d638bb0e12eda89a844622
parentef64b231dc4a385c471754440d89d35f091fea27 (diff)
VTY: integrate IMEI
Display the IMEI in "subscriber ... show", allow showing and modifying subscribers by their IMEI with: "subscriber imei ...". For debug purposes (and to have proper VTY tests), make it possible to change the IMEI with "subscriber ... update imei". IMEIs are saved in the database without the 15th checksum number. When the checksum gets passed, verify it and cut it off. Related: OS#2541 Depends: I02b54cf01a674a1911c5c897fbec02240f88b521 (libosmocore) Change-Id: I1af7b573ca2a1cb22497052665012d9c1acf3b30
-rw-r--r--src/hlr_vty_subscr.c75
-rw-r--r--tests/test_nodes.vty4
-rw-r--r--tests/test_subscriber.vty85
-rw-r--r--tests/test_subscriber.vty.sql3
4 files changed, 152 insertions, 15 deletions
diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c
index 92cfa2a..998d1be 100644
--- a/src/hlr_vty_subscr.c
+++ b/src/hlr_vty_subscr.c
@@ -58,6 +58,15 @@ static void subscr_dump_full_vty(struct vty *vty, struct hlr_subscriber *subscr)
vty_out(vty, " IMSI: %s%s", *subscr->imsi ? subscr->imsi : "none", VTY_NEWLINE);
vty_out(vty, " MSISDN: %s%s", *subscr->msisdn ? subscr->msisdn : "none", VTY_NEWLINE);
+
+ if (*subscr->imei) {
+ char checksum = osmo_luhn(subscr->imei, 14);
+ if (checksum == -EINVAL)
+ vty_out(vty, " IMEI: %s (INVALID LENGTH!)%s", subscr->imei, VTY_NEWLINE);
+ else
+ vty_out(vty, " IMEI: %s%c%s", subscr->imei, checksum, VTY_NEWLINE);
+ }
+
if (*subscr->vlr_number)
vty_out(vty, " VLR number: %s%s", subscr->vlr_number, VTY_NEWLINE);
if (*subscr->sgsn_number)
@@ -131,6 +140,7 @@ static void subscr_dump_full_vty(struct vty *vty, struct hlr_subscriber *subscr)
static int get_subscr_by_argv(struct vty *vty, const char *type, const char *id, struct hlr_subscriber *subscr)
{
+ char imei_buf[GSM23003_IMEI_NUM_DIGITS_NO_CHK+1];
int rc = -1;
if (strcmp(type, "imsi") == 0)
rc = db_subscr_get_by_imsi(g_hlr->dbc, id, subscr);
@@ -138,6 +148,17 @@ static int get_subscr_by_argv(struct vty *vty, const char *type, const char *id,
rc = db_subscr_get_by_msisdn(g_hlr->dbc, id, subscr);
else if (strcmp(type, "id") == 0)
rc = db_subscr_get_by_id(g_hlr->dbc, atoll(id), subscr);
+ else if (strcmp(type, "imei") == 0) {
+ /* Verify IMEI with checksum digit */
+ if (osmo_imei_str_valid(id, true)) {
+ /* Cut the checksum off */
+ osmo_strlcpy(imei_buf, id, sizeof(imei_buf));
+ id = imei_buf;
+ vty_out(vty, "%% Checksum validated and stripped for search: imei = '%s'%s", id,
+ VTY_NEWLINE);
+ }
+ rc = db_subscr_get_by_imei(g_hlr->dbc, id, subscr);
+ }
if (rc)
vty_out(vty, "%% No subscriber for %s = '%s'%s",
type, id, VTY_NEWLINE);
@@ -147,12 +168,13 @@ static int get_subscr_by_argv(struct vty *vty, const char *type, const char *id,
#define SUBSCR_CMD "subscriber "
#define SUBSCR_CMD_HELP "Subscriber management commands\n"
-#define SUBSCR_ID "(imsi|msisdn|id) IDENT"
+#define SUBSCR_ID "(imsi|msisdn|id|imei) IDENT"
#define SUBSCR_ID_HELP \
"Identify subscriber by IMSI\n" \
"Identify subscriber by MSISDN (phone number)\n" \
"Identify subscriber by database ID\n" \
- "IMSI/MSISDN/ID of the subscriber\n"
+ "Identify subscriber by IMEI\n" \
+ "IMSI/MSISDN/ID/IMEI of the subscriber\n"
#define SUBSCR SUBSCR_CMD SUBSCR_ID " "
#define SUBSCR_HELP SUBSCR_CMD_HELP SUBSCR_ID_HELP
@@ -508,6 +530,54 @@ DEFUN(subscriber_aud3g,
return CMD_SUCCESS;
}
+DEFUN(subscriber_imei,
+ subscriber_imei_cmd,
+ SUBSCR_UPDATE "imei (none|IMEI)",
+ SUBSCR_UPDATE_HELP
+ "Set IMEI of the subscriber (normally populated from MSC, no need to set this manually)\n"
+ "Forget IMEI\n"
+ "Set IMEI (use for debug only!)\n")
+{
+ struct hlr_subscriber subscr;
+ const char *id_type = argv[0];
+ const char *id = argv[1];
+ const char *imei = argv[2];
+ char imei_buf[GSM23003_IMEI_NUM_DIGITS_NO_CHK+1];
+
+ if (strcmp(imei, "none") == 0)
+ imei = NULL;
+ else {
+ /* Verify IMEI with checksum digit */
+ if (osmo_imei_str_valid(imei, true)) {
+ /* Cut the checksum off */
+ osmo_strlcpy(imei_buf, imei, sizeof(imei_buf));
+ imei = imei_buf;
+ } else if (!osmo_imei_str_valid(imei, false)) {
+ vty_out(vty, "%% IMEI invalid: '%s'%s", imei, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ if (get_subscr_by_argv(vty, id_type, id, &subscr))
+ return CMD_WARNING;
+
+ if (db_subscr_update_imei_by_imsi(g_hlr->dbc, subscr.imsi, imei)) {
+ vty_out(vty, "%% Error: cannot update IMEI for subscriber IMSI='%s'%s",
+ subscr.imsi, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (imei)
+ vty_out(vty, "%% Updated subscriber IMSI='%s' to IMEI='%s'%s",
+ subscr.imsi, imei, VTY_NEWLINE);
+ else
+ vty_out(vty, "%% Updated subscriber IMSI='%s': removed IMEI%s",
+ subscr.imsi, VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+
void hlr_vty_subscriber_init(void)
{
install_element_ve(&subscriber_show_cmd);
@@ -519,4 +589,5 @@ void hlr_vty_subscriber_init(void)
install_element(ENABLE_NODE, &subscriber_aud2g_cmd);
install_element(ENABLE_NODE, &subscriber_no_aud3g_cmd);
install_element(ENABLE_NODE, &subscriber_aud3g_cmd);
+ install_element(ENABLE_NODE, &subscriber_imei_cmd);
}
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index 6e72ed0..ee7885b 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -17,8 +17,8 @@ OsmoHLR> list
show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS
show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP
show gsup-connections
- subscriber (imsi|msisdn|id) IDENT show
- show subscriber (imsi|msisdn|id) IDENT
+ subscriber (imsi|msisdn|id|imei) IDENT show
+ show subscriber (imsi|msisdn|id|imei) IDENT
OsmoHLR> enable
OsmoHLR# list
diff --git a/tests/test_subscriber.vty b/tests/test_subscriber.vty
index d310eb3..265f8fa 100644
--- a/tests/test_subscriber.vty
+++ b/tests/test_subscriber.vty
@@ -2,15 +2,16 @@ OsmoHLR> enable
OsmoHLR# list
...
- subscriber (imsi|msisdn|id) IDENT show
- show subscriber (imsi|msisdn|id) IDENT
+ subscriber (imsi|msisdn|id|imei) IDENT show
+ show subscriber (imsi|msisdn|id|imei) IDENT
subscriber imsi IDENT create
- subscriber (imsi|msisdn|id) IDENT delete
- subscriber (imsi|msisdn|id) IDENT update msisdn (none|MSISDN)
- subscriber (imsi|msisdn|id) IDENT update aud2g none
- subscriber (imsi|msisdn|id) IDENT update aud2g (comp128v1|comp128v2|comp128v3|xor) ki KI
- subscriber (imsi|msisdn|id) IDENT update aud3g none
- subscriber (imsi|msisdn|id) IDENT update aud3g milenage k K (op|opc) OP_C [ind-bitlen] [<0-28>]
+ subscriber (imsi|msisdn|id|imei) IDENT delete
+ subscriber (imsi|msisdn|id|imei) IDENT update msisdn (none|MSISDN)
+ subscriber (imsi|msisdn|id|imei) IDENT update aud2g none
+ subscriber (imsi|msisdn|id|imei) IDENT update aud2g (comp128v1|comp128v2|comp128v3|xor) ki KI
+ subscriber (imsi|msisdn|id|imei) IDENT update aud3g none
+ subscriber (imsi|msisdn|id|imei) IDENT update aud3g milenage k K (op|opc) OP_C [ind-bitlen] [<0-28>]
+ subscriber (imsi|msisdn|id|imei) IDENT update imei (none|IMEI)
OsmoHLR# subscriber?
subscriber Subscriber management commands
@@ -19,13 +20,16 @@ OsmoHLR# subscriber ?
imsi Identify subscriber by IMSI
msisdn Identify subscriber by MSISDN (phone number)
id Identify subscriber by database ID
+ imei Identify subscriber by IMEI
OsmoHLR# subscriber imsi ?
- IDENT IMSI/MSISDN/ID of the subscriber
+ IDENT IMSI/MSISDN/ID/IMEI of the subscriber
OsmoHLR# subscriber msisdn ?
- IDENT IMSI/MSISDN/ID of the subscriber
+ IDENT IMSI/MSISDN/ID/IMEI of the subscriber
OsmoHLR# subscriber id ?
- IDENT IMSI/MSISDN/ID of the subscriber
+ IDENT IMSI/MSISDN/ID/IMEI of the subscriber
+OsmoHLR# subscriber imei ?
+ IDENT IMSI/MSISDN/ID/IMEI of the subscriber
OsmoHLR# subscriber imsi 123456789023000 show
% No subscriber for imsi = '123456789023000'
@@ -33,6 +37,9 @@ OsmoHLR# subscriber id 101 show
% No subscriber for id = '101'
OsmoHLR# subscriber msisdn 12345 show
% No subscriber for msisdn = '12345'
+OsmoHLR# subscriber imei 357613004448485 show
+% Checksum validated and stripped for search: imei = '35761300444848'
+% No subscriber for imei = '35761300444848'
OsmoHLR# show subscriber imsi 123456789023000
% No subscriber for imsi = '123456789023000'
@@ -40,6 +47,9 @@ OsmoHLR# show subscriber id 101
% No subscriber for id = '101'
OsmoHLR# show subscriber msisdn 12345
% No subscriber for msisdn = '12345'
+OsmoHLR# show subscriber imei 357613004448485
+% Checksum validated and stripped for search: imei = '35761300444848'
+% No subscriber for imei = '35761300444848'
OsmoHLR# subscriber imsi 1234567890230001 create
% Not a valid IMSI: 1234567890230001
@@ -118,6 +128,7 @@ OsmoHLR# subscriber imsi 123456789023000 update ?
msisdn Set MSISDN (phone number) of the subscriber
aud2g Set 2G authentication data
aud3g Set UMTS authentication data (3G, and 2G with UMTS AKA)
+ imei Set IMEI of the subscriber (normally populated from MSC, no need to set this manually)
OsmoHLR# subscriber imsi 123456789023000 update msisdn ?
none Remove MSISDN (phone number)
@@ -374,3 +385,55 @@ OsmoHLR# subscriber imsi 123456789023000 create
OsmoHLR# subscriber imsi 123456789023000 delete
% Deleted subscriber for IMSI '123456789023000'
+
+OsmoHLR# subscriber imsi 123456789023000 create
+% Created subscriber 123456789023000
+ ID: 101
+ IMSI: 123456789023000
+ MSISDN: none
+
+OsmoHLR# subscriber imsi 123456789023000 update imei ?
+ none Forget IMEI
+ IMEI Set IMEI (use for debug only!)
+
+OsmoHLR# subscriber imsi 123456789023000 update imei 35761300444848
+% Updated subscriber IMSI='123456789023000' to IMEI='35761300444848'
+
+OsmoHLR# subscriber imsi 123456789023000 update imei 357613004448484
+% IMEI invalid: '357613004448484'
+
+OsmoHLR# subscriber imsi 123456789023000 update imei 357613004448485
+% Updated subscriber IMSI='123456789023000' to IMEI='35761300444848'
+
+OsmoHLR# show subscriber imei 35761300444848
+ ID: 101
+ IMSI: 123456789023000
+ MSISDN: none
+ IMEI: 357613004448485
+
+OsmoHLR# show subscriber imei 357613004448485
+% Checksum validated and stripped for search: imei = '35761300444848'
+ ID: 101
+ IMSI: 123456789023000
+ MSISDN: none
+ IMEI: 357613004448485
+
+OsmoHLR# show subscriber imei 357613004448484
+% No subscriber for imei = '357613004448484'
+
+OsmoHLR# subscriber imsi 123456789023000 update imei none
+% Updated subscriber IMSI='123456789023000': removed IMEI
+
+OsmoHLR# subscriber imsi 123456789023000 show
+ ID: 101
+ IMSI: 123456789023000
+ MSISDN: none
+
+OsmoHLR# subscriber imsi 123456789023000 delete
+% Deleted subscriber for IMSI '123456789023000'
+
+OsmoHLR# show subscriber id 99
+ ID: 99
+ IMSI: 000000000000099
+ MSISDN: none
+ IMEI: 12345 (INVALID LENGTH!)
diff --git a/tests/test_subscriber.vty.sql b/tests/test_subscriber.vty.sql
index ff167aa..e2c1af2 100644
--- a/tests/test_subscriber.vty.sql
+++ b/tests/test_subscriber.vty.sql
@@ -1,3 +1,6 @@
+-- Subscriber with invalid IMEI length
+INSERT INTO subscriber (id, imsi, imei) VALUES(99, '000000000000099', '12345');
+
-- Dummy entry with ID=100 gives all subscribers created in the VTY test an
-- ID > 100, so we can pre-fill the database with IDs < 100.
INSERT INTO subscriber (id, imsi) VALUES(100, '000000000000100');