diff options
author | Thomas Sailer <t.sailer@alumni.ethz.ch> | 2016-02-13 14:19:13 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-02-13 14:27:51 +0100 |
commit | 95876c6f576875503f20f7e3ad27440bffd9067c (patch) | |
tree | 8f1b0b454d8c93aa063dddbc634048d38ecc1b9e /src | |
parent | a33615d6cb087c646de3b1899fbed0f7284f9340 (diff) |
helpers: move +CRSM parsing to mm_3gpp_parse_crsm_response
Also added test cases.
Signed-off-by: Thomas Sailer <t.sailer@alumni.ethz.ch>
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-sim.c | 117 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 51 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 8 | ||||
-rw-r--r-- | src/tests/test-modem-helpers.c | 54 |
4 files changed, 151 insertions, 79 deletions
diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c index 104e7f8d..6a790916 100644 --- a/src/mm-base-sim.c +++ b/src/mm-base-sim.c @@ -944,36 +944,27 @@ static gchar * parse_iccid (const gchar *response, GError **error) { - gchar buf[21]; - const gchar *str; - gint sw1; - gint sw2; - gboolean success = FALSE; - - memset (buf, 0, sizeof (buf)); - str = mm_strip_tag (response, "+CRSM:"); - if (sscanf (str, "%d,%d,\"%20c\"", &sw1, &sw2, (char *) &buf) == 3) - success = TRUE; - else { - /* May not include quotes... */ - if (sscanf (str, "%d,%d,%20c", &sw1, &sw2, (char *) &buf) == 3) - success = TRUE; - } - - if (!success) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Could not parse the CRSM response"); + guint sw1 = 0; + guint sw2 = 0; + gchar *hex = 0; + gchar *ret; + + if (!mm_3gpp_parse_crsm_response (response, + &sw1, + &sw2, + &hex, + error)) return NULL; - } if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || (sw1 == 0x92) || (sw1 == 0x9f)) { - return mm_3gpp_parse_iccid (buf, error); + ret = mm_3gpp_parse_iccid (hex, error); + g_free (hex); + return ret; } else { + g_free (hex); g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, @@ -1101,27 +1092,16 @@ static guint parse_mnc_length (const gchar *response, GError **error) { - gint sw1; - gint sw2; - gboolean success = FALSE; - gchar hex[51]; - - memset (hex, 0, sizeof (hex)); - if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - else { - /* May not include quotes... */ - if (sscanf (response, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - } + guint sw1 = 0; + guint sw2 = 0; + gchar *hex = 0; - if (!success) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Could not parse the CRSM response"); + if (!mm_3gpp_parse_crsm_response (response, + &sw1, + &sw2, + &hex, + error)) return 0; - } if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || @@ -1131,15 +1111,6 @@ parse_mnc_length (const gchar *response, guint32 mnc_len; gchar *bin; - /* Make sure the buffer is only hex characters */ - while (buflen < sizeof (hex) && hex[buflen]) { - if (!isxdigit (hex[buflen])) { - hex[buflen] = 0x0; - break; - } - buflen++; - } - /* Convert hex string to binary */ bin = mm_utils_hexstr2bin (hex, &buflen); if (!bin || buflen < 4) { @@ -1149,9 +1120,12 @@ parse_mnc_length (const gchar *response, "SIM returned malformed response '%s'", hex); g_free (bin); + g_free (hex); return 0; } + g_free (hex); + /* MNC length is byte 4 of this SIM file */ mnc_len = bin[3] & 0xFF; if (mnc_len == 2 || mnc_len == 3) { @@ -1168,6 +1142,7 @@ parse_mnc_length (const gchar *response, return 0; } + g_free (hex); g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, @@ -1238,27 +1213,16 @@ static gchar * parse_spn (const gchar *response, GError **error) { - gint sw1; - gint sw2; - gboolean success = FALSE; - gchar hex[51]; - - memset (hex, 0, sizeof (hex)); - if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - else { - /* May not include quotes... */ - if (sscanf (response, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - } + guint sw1 = 0; + guint sw2 = 0; + gchar *hex = 0; - if (!success) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Could not parse the CRSM response"); + if (!mm_3gpp_parse_crsm_response (response, + &sw1, + &sw2, + &hex, + error)) return NULL; - } if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || @@ -1268,15 +1232,6 @@ parse_spn (const gchar *response, gchar *bin; gchar *utf8; - /* Make sure the buffer is only hex characters */ - while (buflen < sizeof (hex) && hex[buflen]) { - if (!isxdigit (hex[buflen])) { - hex[buflen] = 0x0; - break; - } - buflen++; - } - /* Convert hex string to binary */ bin = mm_utils_hexstr2bin (hex, &buflen); if (!bin) { @@ -1285,9 +1240,12 @@ parse_spn (const gchar *response, MM_CORE_ERROR_FAILED, "SIM returned malformed response '%s'", hex); + g_free (hex); return NULL; } + g_free (hex); + /* Remove the FF filler at the end */ while (buflen > 1 && bin[buflen - 1] == (char)0xff) buflen--; @@ -1298,6 +1256,7 @@ parse_spn (const gchar *response, return utf8; } + g_free (hex); g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index dec53c34..ed365786 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -1342,6 +1342,57 @@ done: return info; } +/*****************************************************************************/ + +/* AT+CRSM response parser */ +gboolean +mm_3gpp_parse_crsm_response (const gchar *reply, + guint *sw1, + guint *sw2, + gchar **hex, + GError **error) +{ + GRegex *r; + GMatchInfo *match_info; + + g_assert (sw1 != NULL); + g_assert (sw2 != NULL); + g_assert (hex != NULL); + + *sw1 = 0; + *sw2 = 0; + *hex = NULL; + + if (!reply || !g_str_has_prefix (reply, "+CRSM:")) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing +CRSM prefix"); + return FALSE; + } + + r = g_regex_new ("\\+CRSM:\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*\"?([0-9a-fA-F]+)\"?", + G_REGEX_RAW, 0, error); + if (!r) + return FALSE; + + if (g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, NULL) && + mm_get_uint_from_match_info (match_info, 1, sw1) && + mm_get_uint_from_match_info (match_info, 2, sw2)) + *hex = mm_get_string_unquoted_from_match_info (match_info, 3); + + g_match_info_free (match_info); + g_regex_unref (r); + + if (*hex == NULL) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse CRSM query result '%s'", + reply); + return FALSE; + } + + return TRUE; +} + /*************************************************************************/ static MMSmsStorage diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 3be7c7be..975a493b 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -203,6 +203,14 @@ MM3gppPduInfo *mm_3gpp_parse_cmgr_read_response (const gchar *reply, guint index, GError **error); + +/* AT+CRSM response parser */ +gboolean mm_3gpp_parse_crsm_response (const gchar *reply, + guint *sw1, + guint *sw2, + gchar **hex, + GError **error); + /* Additional 3GPP-specific helpers */ MMModem3gppFacility mm_3gpp_acronym_to_facility (const gchar *str); diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index d1833e5a..db84f016 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -2631,6 +2631,58 @@ test_cclk_response (void) } } + +/*****************************************************************************/ +/* Test +CRSM responses */ + +typedef struct { + const gchar *str; + gboolean ret; + guint sw1; + guint sw2; + gchar *hex; +} CrsmTest; + +static const CrsmTest crsm_tests[] = { + { "+CRSM: 144, 0, 0054485552415941FFFFFFFFFFFFFFFFFF", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" }, + { "+CRSM: 144, 0,0054485552415941FFFFFFFFFFFFFFFFFF", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" }, + { "+CRSM: 144, 0, \"0054485552415941FFFFFFFFFFFFFFFFFF\"", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" }, + { "+CRSM: 144, 0,\"0054485552415941FFFFFFFFFFFFFFFFFF\"", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" }, + { NULL, FALSE, 0, 0, NULL } +}; + +static void +test_crsm_response (void) +{ + guint i; + + for (i = 0; crsm_tests[i].str; i++) { + GError *error = NULL; + guint sw1 = 0; + guint sw2 = 0; + gchar *hex = 0; + gboolean ret; + + ret = mm_3gpp_parse_crsm_response (crsm_tests[i].str, + &sw1, + &sw2, + &hex, + &error); + + g_assert (ret == crsm_tests[i].ret); + g_assert (ret == (error ? FALSE : TRUE)); + + g_clear_error (&error); + + g_assert (sw1 == crsm_tests[i].sw1); + g_assert (sw2 == crsm_tests[i].sw2); + + g_assert_cmpstr (crsm_tests[i].hex, ==, hex); + + g_free(hex); + } +} + /*****************************************************************************/ void @@ -2805,6 +2857,8 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_cclk_response, NULL)); + g_test_suite_add (suite, TESTCASE (test_crsm_response, NULL)); + result = g_test_run (); reg_test_data_free (reg_data); |