helpers: move +CRSM parsing to mm_3gpp_parse_crsm_response
Also added test cases. Signed-off-by: Thomas Sailer <t.sailer@alumni.ethz.ch>
This commit is contained in:

committed by
Aleksander Morgado

parent
a33615d6cb
commit
95876c6f57
@@ -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;
|
||||
guint sw1 = 0;
|
||||
guint sw2 = 0;
|
||||
gchar *hex = 0;
|
||||
gchar *ret;
|
||||
|
||||
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");
|
||||
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];
|
||||
guint sw1 = 0;
|
||||
guint sw2 = 0;
|
||||
gchar *hex = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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];
|
||||
guint sw1 = 0;
|
||||
guint sw2 = 0;
|
||||
gchar *hex = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user