modem-helpers: new CGDCONT=? test response parser
This commit is contained in:
@@ -644,6 +644,88 @@ mm_3gpp_parse_cops_test_response (const gchar *reply,
|
|||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_3gpp_pdp_context_format_free (MM3gppPdpContextFormat *format)
|
||||||
|
{
|
||||||
|
g_slice_free (MM3gppPdpContextFormat, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_3gpp_pdp_context_format_list_free (GList *pdp_format_list)
|
||||||
|
{
|
||||||
|
g_list_free_full (pdp_format_list, (GDestroyNotify) mm_3gpp_pdp_context_format_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
GList *
|
||||||
|
mm_3gpp_parse_cgdcont_test_response (const gchar *response,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GRegex *r;
|
||||||
|
GMatchInfo *match_info;
|
||||||
|
GError *inner_error = NULL;
|
||||||
|
GList *list = NULL;
|
||||||
|
|
||||||
|
if (!response || !g_str_has_prefix (response, "+CGDCONT:")) {
|
||||||
|
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing +CGDCONT prefix");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = g_regex_new ("\\+CGDCONT:\\s*\\((\\d+)-(\\d+)\\),\\(?\"(\\S+)\"",
|
||||||
|
G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
|
||||||
|
0, &inner_error);
|
||||||
|
g_assert (r != NULL);
|
||||||
|
|
||||||
|
g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
|
||||||
|
while (!inner_error && g_match_info_matches (match_info)) {
|
||||||
|
gchar *pdp_type_str;
|
||||||
|
guint min_cid;
|
||||||
|
guint max_cid;
|
||||||
|
MMBearerIpFamily pdp_type;
|
||||||
|
|
||||||
|
/* Read PDP type */
|
||||||
|
pdp_type_str = mm_get_string_unquoted_from_match_info (match_info, 3);
|
||||||
|
pdp_type = mm_3gpp_get_ip_family_from_pdp_type (pdp_type_str);
|
||||||
|
if (pdp_type == MM_BEARER_IP_FAMILY_NONE)
|
||||||
|
mm_dbg ("Unhandled PDP type in CGDCONT=? reply: '%s'", pdp_type_str);
|
||||||
|
else {
|
||||||
|
/* Read min CID */
|
||||||
|
if (!mm_get_uint_from_match_info (match_info, 1, &min_cid))
|
||||||
|
mm_warn ("Invalid min CID in CGDCONT=? reply for PDP type '%s'", pdp_type_str);
|
||||||
|
else {
|
||||||
|
/* Read max CID */
|
||||||
|
if (!mm_get_uint_from_match_info (match_info, 2, &max_cid))
|
||||||
|
mm_warn ("Invalid max CID in CGDCONT=? reply for PDP type '%s'", pdp_type_str);
|
||||||
|
else {
|
||||||
|
MM3gppPdpContextFormat *format;
|
||||||
|
|
||||||
|
format = g_slice_new (MM3gppPdpContextFormat);
|
||||||
|
format->pdp_type = pdp_type;
|
||||||
|
format->min_cid = min_cid;
|
||||||
|
format->max_cid = max_cid;
|
||||||
|
|
||||||
|
list = g_list_prepend (list, format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (pdp_type_str);
|
||||||
|
g_match_info_next (match_info, &inner_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_match_info_free (match_info);
|
||||||
|
g_regex_unref (r);
|
||||||
|
|
||||||
|
if (inner_error) {
|
||||||
|
mm_warn ("Unexpected error matching +CGDCONT response: '%s'", inner_error->message);
|
||||||
|
g_error_free (inner_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mm_3gpp_pdp_context_free (MM3gppPdpContext *pdp)
|
mm_3gpp_pdp_context_free (MM3gppPdpContext *pdp)
|
||||||
{
|
{
|
||||||
|
@@ -98,6 +98,16 @@ void mm_3gpp_network_info_list_free (GList *info_list);
|
|||||||
GList *mm_3gpp_parse_cops_test_response (const gchar *reply,
|
GList *mm_3gpp_parse_cops_test_response (const gchar *reply,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/* AT+CGDCONT=? (PDP context format) test parser */
|
||||||
|
typedef struct {
|
||||||
|
guint min_cid;
|
||||||
|
guint max_cid;
|
||||||
|
MMBearerIpFamily pdp_type;
|
||||||
|
} MM3gppPdpContextFormat;
|
||||||
|
void mm_3gpp_pdp_context_format_list_free (GList *pdp_format_list);
|
||||||
|
GList *mm_3gpp_parse_cgdcont_test_response (const gchar *reply,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
/* AT+CGDCONT? (PDP context query) response parser */
|
/* AT+CGDCONT? (PDP context query) response parser */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
guint cid;
|
guint cid;
|
||||||
|
@@ -1455,6 +1455,92 @@ test_cind_response_moto_v3m (void *f, gpointer d)
|
|||||||
test_cind_results ("Motorola V3m", reply, &expected[0], G_N_ELEMENTS (expected));
|
test_cind_results ("Motorola V3m", reply, &expected[0], G_N_ELEMENTS (expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Test CGDCONT test responses */
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cgdcont_test_results (const gchar *desc,
|
||||||
|
const gchar *reply,
|
||||||
|
MM3gppPdpContextFormat *expected_results,
|
||||||
|
guint32 expected_results_len)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
GError *error = NULL;
|
||||||
|
GList *results;
|
||||||
|
|
||||||
|
g_print ("\nTesting %s +CGDCONT test response...\n", desc);
|
||||||
|
|
||||||
|
results = mm_3gpp_parse_cgdcont_test_response (reply, &error);
|
||||||
|
g_assert (results);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
|
||||||
|
|
||||||
|
for (l = results; l; l = g_list_next (l)) {
|
||||||
|
MM3gppPdpContextFormat *format = l->data;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; !found && i < expected_results_len; i++) {
|
||||||
|
MM3gppPdpContextFormat *expected;
|
||||||
|
|
||||||
|
expected = &expected_results[i];
|
||||||
|
if (format->pdp_type == expected->pdp_type) {
|
||||||
|
found = TRUE;
|
||||||
|
|
||||||
|
g_assert_cmpuint (format->min_cid, ==, expected->min_cid);
|
||||||
|
g_assert_cmpuint (format->max_cid, ==, expected->max_cid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (found == TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_3gpp_pdp_context_format_list_free (results);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cgdcont_test_response_single (void *f, gpointer d)
|
||||||
|
{
|
||||||
|
const gchar *reply = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)";
|
||||||
|
static MM3gppPdpContextFormat expected[] = {
|
||||||
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV4 }
|
||||||
|
};
|
||||||
|
|
||||||
|
test_cgdcont_test_results ("Single", reply, &expected[0], G_N_ELEMENTS (expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cgdcont_test_response_multiple (void *f, gpointer d)
|
||||||
|
{
|
||||||
|
const gchar *reply =
|
||||||
|
"+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
||||||
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
||||||
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n";
|
||||||
|
static MM3gppPdpContextFormat expected[] = {
|
||||||
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV4 },
|
||||||
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV6 },
|
||||||
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV4V6 }
|
||||||
|
};
|
||||||
|
|
||||||
|
test_cgdcont_test_results ("Multiple", reply, &expected[0], G_N_ELEMENTS (expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cgdcont_test_response_multiple_and_ignore (void *f, gpointer d)
|
||||||
|
{
|
||||||
|
const gchar *reply =
|
||||||
|
"+CGDCONT: (1-16),\"IP\",,,(0-2),(0-4)\r\n"
|
||||||
|
"+CGDCONT: (1-16),\"PPP\",,,(0-2),(0-4)\r\n"
|
||||||
|
"+CGDCONT: (1-16),\"IPV6\",,,(0-2),(0-4)\r\n";
|
||||||
|
static MM3gppPdpContextFormat expected[] = {
|
||||||
|
{ 1, 16, MM_BEARER_IP_FAMILY_IPV4 },
|
||||||
|
/* PPP is ignored */
|
||||||
|
{ 1, 16, MM_BEARER_IP_FAMILY_IPV6 }
|
||||||
|
};
|
||||||
|
|
||||||
|
test_cgdcont_test_results ("Multiple and Ignore", reply, &expected[0], G_N_ELEMENTS (expected));
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Test CGDCONT read responses */
|
/* Test CGDCONT read responses */
|
||||||
|
|
||||||
@@ -1950,6 +2036,10 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
g_test_suite_add (suite, TESTCASE (test_cpms_response_cinterion, NULL));
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_cinterion, NULL));
|
||||||
|
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_single, NULL));
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_multiple, NULL));
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_multiple_and_ignore, NULL));
|
||||||
|
|
||||||
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_nokia, NULL));
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_nokia, NULL));
|
||||||
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_samsung, NULL));
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_samsung, NULL));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user