diff options
author | Ben Chan <benchan@chromium.org> | 2013-09-26 11:07:16 -0700 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-09-26 20:23:51 +0200 |
commit | b5ef861d12c7533d89a18454b03e8e3301164bea (patch) | |
tree | d49cbf5d285f623de42879a271c0b388dba4a8b1 | |
parent | b786ac0debc7aa5e9a6b0f00bd61e15d9daea049 (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.c | 3 | ||||
-rw-r--r-- | plugins/sierra/mm-sim-sierra.c | 3 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 19 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 2 | ||||
-rw-r--r-- | src/mm-sim.c | 3 | ||||
-rw-r--r-- | src/tests/test-modem-helpers.c | 36 |
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)); |