helpers: implement CGDCONT reply parsing
New method to parse the PDP query reply, and build a list of structs with the found info.
This commit is contained in:
@@ -308,6 +308,83 @@ mm_3gpp_parse_scan_response (const gchar *reply,
|
|||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_3gpp_pdp_context_free (MM3gppPdpContext *pdp)
|
||||||
|
{
|
||||||
|
g_free (pdp->pdp_type);
|
||||||
|
g_free (pdp->apn);
|
||||||
|
g_free (pdp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_3gpp_pdp_context_list_free (GList *list)
|
||||||
|
{
|
||||||
|
g_list_foreach (list, (GFunc)mm_3gpp_pdp_context_free, NULL);
|
||||||
|
g_list_free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
mm_3gpp_pdp_context_cmp (MM3gppPdpContext *a,
|
||||||
|
MM3gppPdpContext *b)
|
||||||
|
{
|
||||||
|
return (a->cid - b->cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
GList *
|
||||||
|
mm_3gpp_parse_pdp_query_response (const gchar *reply,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GError *inner_error = NULL;
|
||||||
|
GRegex *r;
|
||||||
|
GMatchInfo *match_info;
|
||||||
|
GList *list;
|
||||||
|
|
||||||
|
if (!reply[0])
|
||||||
|
/* No APNs configured, all done */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
list = NULL;
|
||||||
|
r = g_regex_new ("\\+CGDCONT:\\s*(\\d+)\\s*,([^,\\)]*),([^,\\)]*),([^,\\)]*)",
|
||||||
|
G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
|
||||||
|
0, &inner_error);
|
||||||
|
if (r) {
|
||||||
|
g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &inner_error);
|
||||||
|
|
||||||
|
while (!inner_error &&
|
||||||
|
g_match_info_matches (match_info)) {
|
||||||
|
MM3gppPdpContext *pdp;
|
||||||
|
gchar *cid;
|
||||||
|
|
||||||
|
pdp = g_new0 (MM3gppPdpContext, 1);
|
||||||
|
cid = g_match_info_fetch (match_info, 1);
|
||||||
|
pdp->cid = (guint)atoi (cid);
|
||||||
|
pdp->pdp_type = get_unquoted_scan_value (match_info, 2);
|
||||||
|
pdp->apn = get_unquoted_scan_value (match_info, 3);
|
||||||
|
g_free (cid);
|
||||||
|
|
||||||
|
list = g_list_prepend (list, pdp);
|
||||||
|
|
||||||
|
g_match_info_next (match_info, &inner_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_match_info_free (match_info);
|
||||||
|
g_regex_unref (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inner_error) {
|
||||||
|
mm_3gpp_pdp_context_list_free (list);
|
||||||
|
g_propagate_error (error, inner_error);
|
||||||
|
g_prefix_error (error, "Couldn't properly parse list of PDP contexts. ");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = g_list_sort (list, (GCompareFunc)mm_3gpp_pdp_context_cmp);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
|
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
|
||||||
#define CREG1 "\\+(CREG|CGREG):\\s*0*([0-9])"
|
#define CREG1 "\\+(CREG|CGREG):\\s*0*([0-9])"
|
||||||
|
|
||||||
|
@@ -32,10 +32,20 @@ typedef struct {
|
|||||||
} MM3gppNetworkInfo;
|
} MM3gppNetworkInfo;
|
||||||
|
|
||||||
void mm_3gpp_network_info_list_free (GList *info_list);
|
void mm_3gpp_network_info_list_free (GList *info_list);
|
||||||
|
|
||||||
GList *mm_3gpp_parse_scan_response (const gchar *reply,
|
GList *mm_3gpp_parse_scan_response (const gchar *reply,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/* PDP context query results */
|
||||||
|
typedef struct {
|
||||||
|
guint cid;
|
||||||
|
gchar *pdp_type;
|
||||||
|
gchar *apn;
|
||||||
|
} MM3gppPdpContext;
|
||||||
|
|
||||||
|
void mm_3gpp_pdp_context_list_free (GList *pdp_list);
|
||||||
|
GList *mm_3gpp_parse_pdp_query_response (const gchar *reply,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
GPtrArray *mm_gsm_creg_regex_get (gboolean solicited);
|
GPtrArray *mm_gsm_creg_regex_get (gboolean solicited);
|
||||||
|
|
||||||
void mm_gsm_creg_regex_destroy (GPtrArray *array);
|
void mm_gsm_creg_regex_destroy (GPtrArray *array);
|
||||||
|
@@ -1177,6 +1177,57 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cgdcont_results (const gchar *desc,
|
||||||
|
const gchar *reply,
|
||||||
|
MM3gppPdpContext *expected_results,
|
||||||
|
guint32 expected_results_len)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
GError *error = NULL;
|
||||||
|
GList *results;
|
||||||
|
|
||||||
|
g_print ("\nTesting %s +CGDCONT response...\n", desc);
|
||||||
|
|
||||||
|
results = mm_3gpp_parse_pdp_query_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)) {
|
||||||
|
MM3gppPdpContext *pdp = l->data;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; !found && i < expected_results_len; i++) {
|
||||||
|
MM3gppPdpContext *expected;
|
||||||
|
|
||||||
|
expected = &expected_results[i];
|
||||||
|
if (pdp->cid == expected->cid) {
|
||||||
|
found = TRUE;
|
||||||
|
|
||||||
|
g_assert_cmpstr (pdp->pdp_type, ==, expected->pdp_type);
|
||||||
|
g_assert_cmpstr (pdp->apn, ==, expected->apn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (found == TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_3gpp_pdp_context_list_free (results);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cgdcont_response_nokia (void *f, gpointer d)
|
||||||
|
{
|
||||||
|
const gchar *reply = "+CGDCONT: 1,\"IP\",,,0,0";
|
||||||
|
static MM3gppPdpContext expected[] = {
|
||||||
|
{ 1, "IP", "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
test_cgdcont_results ("Nokia", reply, &expected[0], G_N_ELEMENTS (expected));
|
||||||
|
}
|
||||||
|
|
||||||
static TestData *
|
static TestData *
|
||||||
test_data_new (void)
|
test_data_new (void)
|
||||||
{
|
{
|
||||||
@@ -1297,6 +1348,8 @@ int main (int argc, char **argv)
|
|||||||
item++;
|
item++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_response_nokia, NULL));
|
||||||
|
|
||||||
result = g_test_run ();
|
result = g_test_run ();
|
||||||
|
|
||||||
test_data_free (data);
|
test_data_free (data);
|
||||||
|
Reference in New Issue
Block a user