aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-modem-helpers.c123
-rw-r--r--src/mm-modem-helpers.h6
-rw-r--r--src/tests/test-modem-helpers.c75
3 files changed, 204 insertions, 0 deletions
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index af53dbee..30dc54bb 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -884,3 +884,126 @@ mm_create_device_identifier (guint vid,
return ret;
}
+/*************************************************************************/
+
+struct CindResponse {
+ char *desc;
+ gint min;
+ gint max;
+};
+
+static CindResponse *
+cind_response_new (const char *desc, gint min, gint max)
+{
+ CindResponse *r;
+ char *p;
+
+ g_return_val_if_fail (desc != NULL, NULL);
+
+ r = g_malloc0 (sizeof (CindResponse));
+
+ /* Strip quotes */
+ r->desc = p = g_malloc0 (strlen (desc) + 1);
+ while (*desc) {
+ if (*desc != '"' && !isspace (*desc))
+ *p++ = tolower (*desc);
+ desc++;
+ }
+
+ r->max = max;
+ r->min = min;
+ return r;
+}
+
+static void
+cind_response_free (CindResponse *r)
+{
+ g_return_if_fail (r != NULL);
+
+ g_free (r->desc);
+ memset (r, 0, sizeof (CindResponse));
+ g_free (r);
+}
+
+const char *
+cind_response_get_desc (CindResponse *r)
+{
+ g_return_val_if_fail (r != NULL, NULL);
+
+ return r->desc;
+}
+
+gint
+cind_response_get_min (CindResponse *r)
+{
+ g_return_val_if_fail (r != NULL, 0);
+
+ return r->min;
+}
+
+gint
+cind_response_get_max (CindResponse *r)
+{
+ g_return_val_if_fail (r != NULL, 0);
+
+ return r->max;
+}
+
+#define CIND_TAG "+CIND:"
+
+GHashTable *
+mm_parse_cind_response (const char *reply, GError **error)
+{
+ GHashTable *hash;
+ GRegex *r;
+ GMatchInfo *match_info;
+
+ g_return_val_if_fail (reply != NULL, NULL);
+
+ /* Strip whitespace and response tag */
+ if (g_str_has_prefix (reply, CIND_TAG))
+ reply += strlen (CIND_TAG);
+ while (isspace (*reply))
+ reply++;
+
+ r = g_regex_new ("\\(([^,]*),\\((\\d+)[-,](\\d+)\\)", G_REGEX_UNGREEDY, 0, NULL);
+ if (!r) {
+ g_set_error_literal (error,
+ MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
+ "Could not parse scan results.");
+ return NULL;
+ }
+
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cind_response_free);
+
+ if (g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, NULL)) {
+ while (g_match_info_matches (match_info)) {
+ CindResponse *resp;
+ char *desc, *tmp;
+ gint min = 0, max = 0;
+
+ desc = g_match_info_fetch (match_info, 1);
+
+ tmp = g_match_info_fetch (match_info, 2);
+ min = atoi (tmp);
+ g_free (tmp);
+
+ tmp = g_match_info_fetch (match_info, 3);
+ max = atoi (tmp);
+ g_free (tmp);
+
+ resp = cind_response_new (desc, min, max);
+ if (resp)
+ g_hash_table_insert (hash, g_strdup (resp->desc), resp);
+
+ g_free (desc);
+
+ g_match_info_next (match_info, NULL);
+ }
+ g_match_info_free (match_info);
+ }
+ g_regex_unref (r);
+
+ return hash;
+}
+
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index 3843e7ad..21f174a2 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -69,5 +69,11 @@ char *mm_create_device_identifier (guint vid,
const char *manf,
gboolean debug);
+typedef struct CindResponse CindResponse;
+GHashTable *mm_parse_cind_response (const char *reply, GError **error);
+const char *cind_response_get_desc (CindResponse *r);
+gint cind_response_get_min (CindResponse *r);
+gint cind_response_get_max (CindResponse *r);
+
#endif /* MM_MODEM_HELPERS_H */
diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
index e1cafe7a..db18b25d 100644
--- a/src/tests/test-modem-helpers.c
+++ b/src/tests/test-modem-helpers.c
@@ -1077,6 +1077,78 @@ test_devid_item (void *f, gpointer d)
g_assert (!strcmp (devid, item->devid));
}
+typedef struct {
+ const char *desc;
+ const gint min;
+ const gint max;
+} CindEntry;
+
+static void
+test_cind_results (const char *desc,
+ const char *reply,
+ CindEntry *expected_results,
+ guint32 expected_results_len)
+{
+ guint i;
+ GError *error = NULL;
+ GHashTable *results;
+
+ g_print ("\nTesting %s +CIND response...\n", desc);
+
+ results = mm_parse_cind_response (reply, &error);
+ g_assert (results);
+ g_assert (error == NULL);
+
+ g_assert (g_hash_table_size (results) == expected_results_len);
+
+ for (i = 0; i < expected_results_len; i++) {
+ CindEntry *expected = &expected_results[i];
+ CindEntry *compare;
+
+ compare = g_hash_table_lookup (results, expected->desc);
+ g_assert (compare);
+
+ g_assert_cmpint (expected->min, ==, compare->min);
+ g_assert_cmpint (expected->max, ==, compare->max);
+ }
+
+ g_hash_table_destroy (results);
+}
+
+static void
+test_cind_response_linktop_lw273 (void *f, gpointer d)
+{
+ const char *reply = "+CIND: (\"battchg\",(0-5)),(\"signal\",(0-5)),(\"batterywarning\",(0-1)),(\"chargerconnected\",(0-1)),(\"service\",(0-1)),(\"sounder\",(0-1)),(\"message\",(0-1)),()";
+ static CindEntry expected[] = {
+ { "battchg", 0, 5 },
+ { "signal", 0, 5 },
+ { "batterywarning", 0, 1 },
+ { "chargerconnected", 0, 1 },
+ { "service", 0, 1 },
+ { "sounder", 0, 1 },
+ { "message", 0, 1 }
+ };
+
+ test_cind_results ("LW273", reply, &expected[0], ARRAY_LEN (expected));
+}
+
+static void
+test_cind_response_moto_v3m (void *f, gpointer d)
+{
+ const char *reply = "+CIND: (\"Voice Mail\",(0,1)),(\"service\",(0,1)),(\"call\",(0,1)),(\"Roam\",(0-2)),(\"signal\",(0-5)),(\"callsetup\",(0-3)),(\"smsfull\",(0,1))";
+ static CindEntry expected[] = {
+ { "voicemail", 0, 1 },
+ { "service", 0, 1 },
+ { "call", 0, 1 },
+ { "roam", 0, 2 },
+ { "signal", 0, 5 },
+ { "callsetup", 0, 3 },
+ { "smsfull", 0, 1 }
+ };
+
+ test_cind_results ("Motorola V3m", reply, &expected[0], ARRAY_LEN (expected));
+}
+
static TestData *
test_data_new (void)
{
@@ -1175,6 +1247,9 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_cscs_buslink_support_response, data));
g_test_suite_add (suite, TESTCASE (test_cscs_blackberry_support_response, data));
+ g_test_suite_add (suite, TESTCASE (test_cind_response_linktop_lw273, data));
+ g_test_suite_add (suite, TESTCASE (test_cind_response_moto_v3m, data));
+
while (item->devid) {
g_test_suite_add (suite, TESTCASE (test_devid_item, (gconstpointer) item));
item++;