core: add +CIND parsing helpers
This commit is contained in:
@@ -884,3 +884,126 @@ mm_create_device_identifier (guint vid,
|
|||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -69,5 +69,11 @@ char *mm_create_device_identifier (guint vid,
|
|||||||
const char *manf,
|
const char *manf,
|
||||||
gboolean debug);
|
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 */
|
#endif /* MM_MODEM_HELPERS_H */
|
||||||
|
|
||||||
|
@@ -1077,6 +1077,78 @@ test_devid_item (void *f, gpointer d)
|
|||||||
g_assert (!strcmp (devid, item->devid));
|
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 *
|
static TestData *
|
||||||
test_data_new (void)
|
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_buslink_support_response, data));
|
||||||
g_test_suite_add (suite, TESTCASE (test_cscs_blackberry_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) {
|
while (item->devid) {
|
||||||
g_test_suite_add (suite, TESTCASE (test_devid_item, (gconstpointer) item));
|
g_test_suite_add (suite, TESTCASE (test_devid_item, (gconstpointer) item));
|
||||||
item++;
|
item++;
|
||||||
|
Reference in New Issue
Block a user