aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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);