[PATCH] modem-helpers, sim: auto-detect if ICCID response is character swapped

Ben Chan benchan at chromium.org
Wed Sep 25 17:33:15 PDT 2013


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.
---
 plugins/huawei/mm-sim-huawei.c |  3 +--
 plugins/sierra/mm-sim-sierra.c |  3 +--
 src/mm-modem-helpers.c         | 16 +++++++++++++++-
 src/mm-modem-helpers.h         |  2 +-
 src/mm-sim.c                   |  3 +--
 src/tests/test-modem-helpers.c | 36 ++++++++++++++++++++++++++++++------
 6 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/plugins/huawei/mm-sim-huawei.c b/plugins/huawei/mm-sim-huawei.c
index 7963180..7bf4106 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 05c88eb..d8a4715 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 cf80f07..bd70f93 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,19 @@ 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 {
+      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 355453a..0ec59af 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 b2b011b..53235bc 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 28d9b12..88ed035 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));
-- 
1.8.4



More information about the ModemManager-devel mailing list