ublox: new +UIPADDR=N response parser
This commit is contained in:
@@ -142,3 +142,100 @@ mm_ublox_parse_ubmconf_response (const gchar *response,
|
||||
*out_mode = mode;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* UIPADDR=N response parser */
|
||||
|
||||
gboolean
|
||||
mm_ublox_parse_uipaddr_response (const gchar *response,
|
||||
guint *out_cid,
|
||||
gchar **out_if_name,
|
||||
gchar **out_ipv4_address,
|
||||
gchar **out_ipv4_subnet,
|
||||
gchar **out_ipv6_global_address,
|
||||
gchar **out_ipv6_link_local_address,
|
||||
GError **error)
|
||||
{
|
||||
GRegex *r;
|
||||
GMatchInfo *match_info;
|
||||
GError *inner_error = NULL;
|
||||
guint cid = 0;
|
||||
gchar *if_name = NULL;
|
||||
gchar *ipv4_address = NULL;
|
||||
gchar *ipv4_subnet = NULL;
|
||||
gchar *ipv6_global_address = NULL;
|
||||
gchar *ipv6_link_local_address = NULL;
|
||||
|
||||
/* Response may be e.g.:
|
||||
* +UIPADDR: 1,"ccinet0","5.168.120.13","255.255.255.0","",""
|
||||
* +UIPADDR: 2,"ccinet1","","","2001::2:200:FF:FE00:0/64","FE80::200:FF:FE00:0/64"
|
||||
* +UIPADDR: 3,"ccinet2","5.10.100.2","255.255.255.0","2001::1:200:FF:FE00:0/64","FE80::200:FF:FE00:0/64"
|
||||
*
|
||||
* We assume only ONE line is returned; because we request +UIPADDR with a specific N CID.
|
||||
*/
|
||||
r = g_regex_new ("\\+UIPADDR: (\\d+),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*)(?:\\r\\n)?", 0, 0, NULL);
|
||||
g_assert (r != NULL);
|
||||
|
||||
g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
|
||||
if (inner_error)
|
||||
goto out;
|
||||
|
||||
if (!g_match_info_matches (match_info)) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, "Couldn't match +UIPADDR response");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_cid && !mm_get_uint_from_match_info (match_info, 1, &cid)) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing cid");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_if_name && !(if_name = mm_get_string_unquoted_from_match_info (match_info, 2))) {
|
||||
inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing interface name");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Remaining strings are optional */
|
||||
|
||||
if (out_ipv4_address)
|
||||
ipv4_address = mm_get_string_unquoted_from_match_info (match_info, 3);
|
||||
|
||||
if (out_ipv4_subnet)
|
||||
ipv4_subnet = mm_get_string_unquoted_from_match_info (match_info, 4);
|
||||
|
||||
if (out_ipv6_global_address)
|
||||
ipv6_global_address = mm_get_string_unquoted_from_match_info (match_info, 5);
|
||||
|
||||
if (out_ipv6_link_local_address)
|
||||
ipv6_link_local_address = mm_get_string_unquoted_from_match_info (match_info, 6);
|
||||
|
||||
out:
|
||||
|
||||
if (match_info)
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (r);
|
||||
|
||||
if (inner_error) {
|
||||
g_free (if_name);
|
||||
g_free (ipv4_address);
|
||||
g_free (ipv4_subnet);
|
||||
g_free (ipv6_global_address);
|
||||
g_free (ipv6_link_local_address);
|
||||
g_propagate_error (error, inner_error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (out_cid)
|
||||
*out_cid = cid;
|
||||
if (out_if_name)
|
||||
*out_if_name = if_name;
|
||||
if (out_ipv4_address)
|
||||
*out_ipv4_address = ipv4_address;
|
||||
if (out_ipv4_subnet)
|
||||
*out_ipv4_subnet = ipv4_subnet;
|
||||
if (out_ipv6_global_address)
|
||||
*out_ipv6_global_address = ipv6_global_address;
|
||||
if (out_ipv6_link_local_address)
|
||||
*out_ipv6_link_local_address = ipv6_link_local_address;
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -45,4 +45,16 @@ gboolean mm_ublox_parse_ubmconf_response (const gchar *response,
|
||||
MMUbloxNetworkingMode *out_mode,
|
||||
GError **error);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* UIPADDR=N response parser */
|
||||
|
||||
gboolean mm_ublox_parse_uipaddr_response (const gchar *response,
|
||||
guint *out_cid,
|
||||
gchar **out_if_name,
|
||||
gchar **out_ipv4_address,
|
||||
gchar **out_ipv4_subnet,
|
||||
gchar **out_ipv6_global_address,
|
||||
gchar **out_ipv6_link_local_address,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_MODEM_HELPERS_UBLOX_H */
|
||||
|
@@ -102,6 +102,85 @@ test_ubmconf_response (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test UIPADDR=N responses */
|
||||
|
||||
typedef struct {
|
||||
const gchar *str;
|
||||
guint cid;
|
||||
const gchar *if_name;
|
||||
const gchar *ipv4_address;
|
||||
const gchar *ipv4_subnet;
|
||||
const gchar *ipv6_global_address;
|
||||
const gchar *ipv6_link_local_address;
|
||||
} UipaddrResponseTest;
|
||||
|
||||
static const UipaddrResponseTest uipaddr_response_tests[] = {
|
||||
{
|
||||
.str = "+UIPADDR: 1,\"ccinet0\",\"5.168.120.13\",\"255.255.255.0\",\"\",\"\"",
|
||||
.cid = 1,
|
||||
.if_name = "ccinet0",
|
||||
.ipv4_address = "5.168.120.13",
|
||||
.ipv4_subnet = "255.255.255.0",
|
||||
},
|
||||
{
|
||||
.str = "+UIPADDR: 2,\"ccinet1\",\"\",\"\",\"2001::1:200:FF:FE00:0/64\",\"FE80::200:FF:FE00:0/64\"",
|
||||
.cid = 2,
|
||||
.if_name = "ccinet1",
|
||||
.ipv6_global_address = "2001::1:200:FF:FE00:0/64",
|
||||
.ipv6_link_local_address = "FE80::200:FF:FE00:0/64",
|
||||
},
|
||||
{
|
||||
.str = "+UIPADDR: 3,\"ccinet2\",\"5.10.100.2\",\"255.255.255.0\",\"2001::1:200:FF:FE00:0/64\",\"FE80::200:FF:FE00:0/64\"",
|
||||
.cid = 3,
|
||||
.if_name = "ccinet2",
|
||||
.ipv4_address = "5.10.100.2",
|
||||
.ipv4_subnet = "255.255.255.0",
|
||||
.ipv6_global_address = "2001::1:200:FF:FE00:0/64",
|
||||
.ipv6_link_local_address = "FE80::200:FF:FE00:0/64",
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
test_uipaddr_response (void)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (uipaddr_response_tests); i++) {
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
guint cid = G_MAXUINT;
|
||||
gchar *if_name = NULL;
|
||||
gchar *ipv4_address = NULL;
|
||||
gchar *ipv4_subnet = NULL;
|
||||
gchar *ipv6_global_address = NULL;
|
||||
gchar *ipv6_link_local_address = NULL;
|
||||
|
||||
success = mm_ublox_parse_uipaddr_response (uipaddr_response_tests[i].str,
|
||||
&cid,
|
||||
&if_name,
|
||||
&ipv4_address,
|
||||
&ipv4_subnet,
|
||||
&ipv6_global_address,
|
||||
&ipv6_link_local_address,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_assert_cmpuint (uipaddr_response_tests[i].cid, ==, cid);
|
||||
g_assert_cmpstr (uipaddr_response_tests[i].if_name, ==, if_name);
|
||||
g_assert_cmpstr (uipaddr_response_tests[i].ipv4_address, ==, ipv4_address);
|
||||
g_assert_cmpstr (uipaddr_response_tests[i].ipv4_subnet, ==, ipv4_subnet);
|
||||
g_assert_cmpstr (uipaddr_response_tests[i].ipv6_global_address, ==, ipv6_global_address);
|
||||
g_assert_cmpstr (uipaddr_response_tests[i].ipv6_link_local_address, ==, ipv6_link_local_address);
|
||||
|
||||
g_free (if_name);
|
||||
g_free (ipv4_address);
|
||||
g_free (ipv4_subnet);
|
||||
g_free (ipv6_global_address);
|
||||
g_free (ipv6_link_local_address);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
@@ -133,6 +212,7 @@ int main (int argc, char **argv)
|
||||
|
||||
g_test_add_func ("/MM/ublox/uusbconf/response", test_uusbconf_response);
|
||||
g_test_add_func ("/MM/ublox/ubmconf/response", test_ubmconf_response);
|
||||
g_test_add_func ("/MM/ublox/uipaddr/response", test_uipaddr_response);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Reference in New Issue
Block a user