diff options
author | Dan Williams <dcbw@redhat.com> | 2010-04-09 13:50:45 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-04-09 13:50:45 -0700 |
commit | 0d381e2f11cbc3bdb7c7e69bc4c7169a9d247d3c (patch) | |
tree | 767e21734f1f8287d57df02359bf1339b7c0f8e5 | |
parent | b51a9d27e5a793b4e33bfdd7999e7204c408f154 (diff) |
gsm: fix CSCS=? parsing and add testcases
Some devices (at least one Blackberry we know about) don't include
the () around the response. Handle that and add testcases for it.
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/mm-charsets.c | 21 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 37 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 72 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 4 | ||||
-rw-r--r-- | src/tests/test-modem-helpers.c | 66 |
6 files changed, 151 insertions, 55 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index fd72239f..2fe97121 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,9 @@ libmodem_helpers_la_SOURCES = \ mm-errors.c \ mm-errors.h \ mm-modem-helpers.c \ - mm-modem-helpers.h + mm-modem-helpers.h \ + mm-charsets.c \ + mm-charsets.h sbin_PROGRAMS = modem-manager @@ -58,8 +60,6 @@ modem_manager_SOURCES = \ main.c \ mm-callback-info.c \ mm-callback-info.h \ - mm-charsets.c \ - mm-charsets.h \ $(auth_sources) \ mm-manager.c \ mm-manager.h \ diff --git a/src/mm-charsets.c b/src/mm-charsets.c index c2fa2298..abe54a1c 100644 --- a/src/mm-charsets.c +++ b/src/mm-charsets.c @@ -23,21 +23,22 @@ typedef struct { const char *gsm_name; + const char *other_name; const char *iconv_from_name; const char *iconv_to_name; MMModemCharset charset; } CharsetEntry; static CharsetEntry charset_map[] = { - { "UTF-8", "UTF-8", "UTF-8//TRANSLIT", MM_MODEM_CHARSET_UTF8 }, - { "UCS2", "UCS-2BE", "UCS-2BE//TRANSLIT", MM_MODEM_CHARSET_UCS2 }, - { "IRA", "ASCII", "ASCII//TRANSLIT", MM_MODEM_CHARSET_IRA }, - { "GSM", NULL, NULL, MM_MODEM_CHARSET_GSM }, - { "8859-1", "ISO8859-1", "ISO8859-1//TRANSLIT", MM_MODEM_CHARSET_8859_1 }, - { "PCCP437", NULL, NULL, MM_MODEM_CHARSET_PCCP437 }, - { "PCDN", NULL, NULL, MM_MODEM_CHARSET_PCDN }, - { "HEX", NULL, NULL, MM_MODEM_CHARSET_HEX }, - { NULL, NULL, NULL, MM_MODEM_CHARSET_UNKNOWN } + { "UTF-8", "UTF8", "UTF-8", "UTF-8//TRANSLIT", MM_MODEM_CHARSET_UTF8 }, + { "UCS2", NULL, "UCS-2BE", "UCS-2BE//TRANSLIT", MM_MODEM_CHARSET_UCS2 }, + { "IRA", "ASCII", "ASCII", "ASCII//TRANSLIT", MM_MODEM_CHARSET_IRA }, + { "GSM", NULL, NULL, NULL, MM_MODEM_CHARSET_GSM }, + { "8859-1", NULL, "ISO8859-1", "ISO8859-1//TRANSLIT", MM_MODEM_CHARSET_8859_1 }, + { "PCCP437", NULL, NULL, NULL, MM_MODEM_CHARSET_PCCP437 }, + { "PCDN", NULL, NULL, NULL, MM_MODEM_CHARSET_PCDN }, + { "HEX", NULL, NULL, NULL, MM_MODEM_CHARSET_HEX }, + { NULL, NULL, NULL, NULL, MM_MODEM_CHARSET_UNKNOWN } }; const char * @@ -66,6 +67,8 @@ mm_modem_charset_from_string (const char *string) while (iter->gsm_name) { if (strcasestr (string, iter->gsm_name)) return iter->charset; + if (iter->other_name && strcasestr (string, iter->other_name)) + return iter->charset; iter++; } return MM_MODEM_CHARSET_UNKNOWN; diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index 66ebc489..003ee2ac 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -2676,9 +2676,6 @@ get_charsets_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMGenericGsmPrivate *priv; - GRegex *r = NULL; - GMatchInfo *match_info; - const char *p; info->error = mm_modem_check_removed (info->modem, error); if (info->error) { @@ -2688,41 +2685,13 @@ get_charsets_done (MMAtSerialPort *port, priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); - /* Find the first '(' */ - p = strchr (response->str, '('); - if (!p) - goto done; - p++; - - /* Now parse each charset */ - r = g_regex_new ("\\s*([^,\\)]+)\\s*", 0, 0, NULL); - if (!r) - goto done; - - if (!g_regex_match_full (r, p, strlen (p), 0, 0, &match_info, NULL)) - goto done; - priv->charsets = MM_MODEM_CHARSET_UNKNOWN; - - while (g_match_info_matches (match_info)) { - char *str; - - str = g_match_info_fetch (match_info, 1); - priv->charsets |= mm_modem_charset_from_string (str); - g_free (str); - - g_match_info_next (match_info, NULL); - } - g_match_info_free (match_info); - - mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->charsets), NULL); - -done: - if (!info->error && !priv->charsets) { + if (!mm_gsm_parse_cscs_support_response (response->str, &priv->charsets)) { info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Failed to parse the supported character sets response"); - } + } else + mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->charsets), NULL); mm_callback_info_schedule (info); } diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 1f7a7888..36d89314 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -23,6 +23,22 @@ #include "mm-errors.h" #include "mm-modem-helpers.h" +const char * +mm_strip_tag (const char *str, const char *cmd) +{ + const char *p = str; + + if (p) { + if (!strncmp (p, cmd, strlen (cmd))) + p += strlen (cmd); + while (isspace (*p)) + p++; + } + return p; +} + +/*************************************************************************/ + static void save_scan_value (GHashTable *hash, const char *key, GMatchInfo *info, guint32 num) { @@ -702,17 +718,55 @@ mm_cdma_parse_speri_response (const char *reply, /*************************************************************************/ -const char * -mm_strip_tag (const char *str, const char *cmd) +gboolean +mm_gsm_parse_cscs_support_response (const char *reply, + MMModemCharset *out_charsets) { - const char *p = str; + MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; + GRegex *r; + GMatchInfo *match_info; + char *p, *str; + gboolean success = FALSE; - if (p) { - if (!strncmp (p, cmd, strlen (cmd))) - p += strlen (cmd); - while (isspace (*p)) - p++; + g_return_val_if_fail (reply != NULL, FALSE); + g_return_val_if_fail (out_charsets != NULL, FALSE); + + /* Find the first '(' or '"'; the general format is: + * + * +CSCS: ("IRA","GSM","UCS2") + * + * but some devices (some Blackberries) don't include the (). + */ + p = strchr (reply, '('); + if (p) + p++; + else { + p = strchr (reply, '"'); + if (!p) + return FALSE; } - return p; + + /* Now parse each charset */ + r = g_regex_new ("\\s*([^,\\)]+)\\s*", 0, 0, NULL); + if (!r) + return FALSE; + + if (g_regex_match_full (r, p, strlen (p), 0, 0, &match_info, NULL)) { + while (g_match_info_matches (match_info)) { + str = g_match_info_fetch (match_info, 1); + charsets |= mm_modem_charset_from_string (str); + g_free (str); + + g_match_info_next (match_info, NULL); + success = TRUE; + } + g_match_info_free (match_info); + } + g_regex_unref (r); + + if (success) + *out_charsets = charsets; + + return success; } diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 0ef16074..d747a68a 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -18,6 +18,7 @@ #define MM_MODEM_HELPERS_H #include "mm-modem-cdma.h" +#include "mm-charsets.h" #define MM_SCAN_TAG_STATUS "status" #define MM_SCAN_TAG_OPER_LONG "operator-long" @@ -51,5 +52,8 @@ gboolean mm_cdma_parse_speri_response (const char *reply, gboolean *out_roaming, const char **out_desc); +gboolean mm_gsm_parse_cscs_support_response (const char *reply, + MMModemCharset *out_charsets); + #endif /* MM_MODEM_HELPERS_H */ diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index addeee3e..f93dbd6d 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -690,6 +690,67 @@ test_creg_cgreg_multi2_unsolicited (void *f, gpointer d) test_creg_match ("Multi CREG/CGREG #2", FALSE, reply, data, &result); } +static void +test_cscs_icon225_support_response (void *f, gpointer d) +{ + const char *reply = "\r\n+CSCS: (\"IRA\",\"GSM\",\"UCS2\")\r\n"; + MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; + gboolean success; + + success = mm_gsm_parse_cscs_support_response (reply, &charsets); + g_assert (success); + + g_assert (charsets == (MM_MODEM_CHARSET_IRA | + MM_MODEM_CHARSET_GSM | + MM_MODEM_CHARSET_UCS2)); +} + +static void +test_cscs_sierra_mercury_support_response (void *f, gpointer d) +{ + const char *reply = "\r\n+CSCS: (\"IRA\",\"GSM\",\"UCS2\",\"PCCP437\")\r\n"; + MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; + gboolean success; + + success = mm_gsm_parse_cscs_support_response (reply, &charsets); + g_assert (success); + + g_assert (charsets == (MM_MODEM_CHARSET_IRA | + MM_MODEM_CHARSET_GSM | + MM_MODEM_CHARSET_UCS2 | + MM_MODEM_CHARSET_PCCP437)); +} + +static void +test_cscs_buslink_support_response (void *f, gpointer d) +{ + const char *reply = "\r\n+CSCS: (\"8859-1\",\"ASCII\",\"GSM\",\"UCS2\",\"UTF8\")\r\n"; + MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; + gboolean success; + + success = mm_gsm_parse_cscs_support_response (reply, &charsets); + g_assert (success); + + g_assert (charsets == (MM_MODEM_CHARSET_8859_1 | + MM_MODEM_CHARSET_IRA | + MM_MODEM_CHARSET_GSM | + MM_MODEM_CHARSET_UCS2 | + MM_MODEM_CHARSET_UTF8)); +} + +static void +test_cscs_blackberry_support_response (void *f, gpointer d) +{ + const char *reply = "\r\n+CSCS: \"IRA\"\r\n"; + MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN; + gboolean success; + + success = mm_gsm_parse_cscs_support_response (reply, &charsets); + g_assert (success); + + g_assert (charsets == MM_MODEM_CHARSET_IRA); +} + static TestData * test_data_new (void) { @@ -775,6 +836,11 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi_unsolicited, data)); g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi2_unsolicited, data)); + g_test_suite_add (suite, TESTCASE (test_cscs_icon225_support_response, data)); + g_test_suite_add (suite, TESTCASE (test_cscs_sierra_mercury_support_response, data)); + g_test_suite_add (suite, TESTCASE (test_cscs_buslink_support_response, data)); + g_test_suite_add (suite, TESTCASE (test_cscs_blackberry_support_response, data)); + result = g_test_run (); test_data_free (data); |