[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