aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2013-09-26 11:07:16 -0700
committerAleksander Morgado <aleksander@lanedo.com>2013-09-26 20:23:51 +0200
commitb5ef861d12c7533d89a18454b03e8e3301164bea (patch)
treed49cbf5d285f623de42879a271c0b388dba4a8b1
parentb786ac0debc7aa5e9a6b0f00bd61e15d9daea049 (diff)
modem-helpers,sim: auto-detect if ICCID response is character swapped
This patch modifies mm_3gpp_parse_iccid() to auto-detect if an ICCID response is character swapped or not by comparsing the major industry identifier part of the ICCID response to the known value (89) for telecommunication purposes. This addresses the issue where the same AT command (e.g. AT^ICCID used by the huawei plugin) does not report ICCID in a consistent format.
-rw-r--r--plugins/huawei/mm-sim-huawei.c3
-rw-r--r--plugins/sierra/mm-sim-sierra.c3
-rw-r--r--src/mm-modem-helpers.c19
-rw-r--r--src/mm-modem-helpers.h2
-rw-r--r--src/mm-sim.c3
-rw-r--r--src/tests/test-modem-helpers.c36
6 files changed, 52 insertions, 14 deletions
diff --git a/plugins/huawei/mm-sim-huawei.c b/plugins/huawei/mm-sim-huawei.c
index 7963180d..7bf4106c 100644
--- a/plugins/huawei/mm-sim-huawei.c
+++ b/plugins/huawei/mm-sim-huawei.c
@@ -87,8 +87,7 @@ iccid_read_ready (MMBaseModem *modem,
if (!p)
goto error;
- /* Huawei ^ICCID response must be character swapped */
- parsed = mm_3gpp_parse_iccid (p, TRUE, NULL);
+ parsed = mm_3gpp_parse_iccid (p, NULL);
if (parsed) {
g_simple_async_result_set_op_res_gpointer (simple, parsed, g_free);
g_simple_async_result_complete (simple);
diff --git a/plugins/sierra/mm-sim-sierra.c b/plugins/sierra/mm-sim-sierra.c
index 05c88eb4..d8a4715f 100644
--- a/plugins/sierra/mm-sim-sierra.c
+++ b/plugins/sierra/mm-sim-sierra.c
@@ -82,8 +82,7 @@ iccid_read_ready (MMBaseModem *modem,
return;
}
- /* Sierra !ICCID response is already character swapped */
- parsed = mm_3gpp_parse_iccid (p, FALSE, &local);
+ parsed = mm_3gpp_parse_iccid (p, &local);
if (parsed)
g_simple_async_result_set_op_res_gpointer (simple, parsed, g_free);
else
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index cf80f07b..9c86ebc2 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -1892,8 +1892,9 @@ mm_3gpp_get_ip_family_from_pdp_type (const gchar *pdp_type)
/*************************************************************************/
char *
-mm_3gpp_parse_iccid (const char *raw_iccid, gboolean swap, GError **error)
+mm_3gpp_parse_iccid (const char *raw_iccid, GError **error)
{
+ gboolean swap;
char *buf, *swapped = NULL;
gsize len = 0;
int f_pos = -1, i;
@@ -1934,6 +1935,22 @@ mm_3gpp_parse_iccid (const char *raw_iccid, gboolean swap, GError **error)
goto error;
}
+ /* The leading two digits of an ICCID is the major industry identifier and
+ * should be '89' for telecommunication purposes according to ISO/IEC 7812.
+ */
+ if (buf[0] == '8' && buf[1] == '9') {
+ swap = FALSE;
+ } else if (buf[0] == '9' && buf[1] == '8') {
+ swap = TRUE;
+ } else {
+ /* FIXME: Instead of erroring out, revisit this solution if we find any SIM
+ * that doesn't use '89' as the major industry identifier of the ICCID.
+ */
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Invalid ICCID response (leading two digits are not 89)");
+ goto error;
+ }
+
/* Ensure if there's an 'F' that it's second-to-last if swap = TRUE,
* otherwise last if swap = FALSE */
if (f_pos >= 0) {
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index 355453a5..0ec59aff 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -204,7 +204,7 @@ gboolean mm_3gpp_parse_operator_id (const gchar *operator_id,
const gchar *mm_3gpp_get_pdp_type_from_ip_family (MMBearerIpFamily family);
MMBearerIpFamily mm_3gpp_get_ip_family_from_pdp_type (const gchar *pdp_type);
-char *mm_3gpp_parse_iccid (const char *raw_iccid, gboolean swap, GError **error);
+char *mm_3gpp_parse_iccid (const char *raw_iccid, GError **error);
/*****************************************************************************/
/* CDMA specific helpers and utilities */
diff --git a/src/mm-sim.c b/src/mm-sim.c
index b2b011be..53235bc4 100644
--- a/src/mm-sim.c
+++ b/src/mm-sim.c
@@ -973,8 +973,7 @@ parse_iccid (const gchar *response,
(sw1 == 0x91) ||
(sw1 == 0x92) ||
(sw1 == 0x9f)) {
- /* +CRSM response must be character-swapped */
- return mm_3gpp_parse_iccid (buf, TRUE, error);
+ return mm_3gpp_parse_iccid (buf, error);
} else {
g_set_error (error,
MM_CORE_ERROR,
diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
index 28d9b12a..88ed0353 100644
--- a/src/tests/test-modem-helpers.c
+++ b/src/tests/test-modem-helpers.c
@@ -1533,7 +1533,7 @@ test_iccid_parse_quoted_swap_19_digit (void *f, gpointer d)
char *parsed;
GError *error = NULL;
- parsed = mm_3gpp_parse_iccid (raw_iccid, TRUE, &error);
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
g_assert_no_error (error);
g_assert_cmpstr (parsed, ==, expected);
}
@@ -1546,7 +1546,7 @@ test_iccid_parse_unquoted_swap_20_digit (void *f, gpointer d)
char *parsed;
GError *error = NULL;
- parsed = mm_3gpp_parse_iccid (raw_iccid, TRUE, &error);
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
g_assert_no_error (error);
g_assert_cmpstr (parsed, ==, expected);
}
@@ -1559,7 +1559,7 @@ test_iccid_parse_unquoted_unswapped_19_digit (void *f, gpointer d)
char *parsed;
GError *error = NULL;
- parsed = mm_3gpp_parse_iccid (raw_iccid, FALSE, &error);
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
g_assert_no_error (error);
g_assert_cmpstr (parsed, ==, expected);
}
@@ -1572,7 +1572,7 @@ test_iccid_parse_quoted_unswapped_20_digit (void *f, gpointer d)
char *parsed;
GError *error = NULL;
- parsed = mm_3gpp_parse_iccid (raw_iccid, FALSE, &error);
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
g_assert_no_error (error);
g_assert_cmpstr (parsed, ==, expected);
}
@@ -1584,7 +1584,7 @@ test_iccid_parse_short (void *f, gpointer d)
char *parsed;
GError *error = NULL;
- parsed = mm_3gpp_parse_iccid (raw_iccid, TRUE, &error);
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
}
@@ -1595,7 +1595,29 @@ test_iccid_parse_invalid_chars (void *f, gpointer d)
char *parsed;
GError *error = NULL;
- parsed = mm_3gpp_parse_iccid (raw_iccid, TRUE, &error);
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
+ g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
+}
+
+static void
+test_iccid_parse_quoted_invalid_mii (void *f, gpointer d)
+{
+ const char *raw_iccid = "\"0044200053671052499\"";
+ char *parsed;
+ GError *error = NULL;
+
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
+ g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
+}
+
+static void
+test_iccid_parse_unquoted_invalid_mii (void *f, gpointer d)
+{
+ const char *raw_iccid = "0044200053671052499";
+ char *parsed;
+ GError *error = NULL;
+
+ parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
}
@@ -2398,6 +2420,8 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_unswapped_20_digit, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_short, NULL));
g_test_suite_add (suite, TESTCASE (test_iccid_parse_invalid_chars, NULL));
+ g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_invalid_mii, NULL));
+ g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_invalid_mii, NULL));
while (item->devid) {
g_test_suite_add (suite, TESTCASE (test_devid_item, (gconstpointer) item));