[PATCH 2/2] move +CRSM parsing to mm_3gpp_parse_crsm_response; add test cases
Aleksander Morgado
aleksander at aleksander.es
Sat Feb 13 13:36:58 UTC 2016
On 13/02/16 14:19, Thomas Sailer wrote:
> From: Thomas Sailer <t.sailer at alumni.ethz.ch>
>
> Signed-off-by: Thomas Sailer <t.sailer at alumni.ethz.ch>
> ---
> src/mm-base-sim.c | 117 +++++++++++++----------------------------
> src/mm-modem-helpers.c | 51 ++++++++++++++++++
> src/mm-modem-helpers.h | 8 +++
> src/tests/test-modem-helpers.c | 54 +++++++++++++++++++
> 4 files changed, 151 insertions(+), 79 deletions(-)
>
Fixed up the commit message a bit, and removed some trailing whitespaces
in the patch, then commited to git master.
I've also pushed a follow up commit which ignores possible errors in the
g_regex_new(); we don't need that as the pattern is fixed.
Thanks!
> diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c
> index 104e7f8..6a79091 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 dec53c3..ed36578 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 3be7c7b..975a493 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 d1833e5..445515f 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);
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list