diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-modem-helpers.c | 123 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 6 | ||||
-rw-r--r-- | src/tests/test-modem-helpers.c | 75 |
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++; |