aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-04-09 13:50:45 -0700
committerDan Williams <dcbw@redhat.com>2010-04-09 13:50:45 -0700
commit0d381e2f11cbc3bdb7c7e69bc4c7169a9d247d3c (patch)
tree767e21734f1f8287d57df02359bf1339b7c0f8e5
parentb51a9d27e5a793b4e33bfdd7999e7204c408f154 (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.am6
-rw-r--r--src/mm-charsets.c21
-rw-r--r--src/mm-generic-gsm.c37
-rw-r--r--src/mm-modem-helpers.c72
-rw-r--r--src/mm-modem-helpers.h4
-rw-r--r--src/tests/test-modem-helpers.c66
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);