aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ublox/mm-modem-helpers-ublox.c97
-rw-r--r--plugins/ublox/mm-modem-helpers-ublox.h12
-rw-r--r--plugins/ublox/tests/test-modem-helpers-ublox.c80
3 files changed, 189 insertions, 0 deletions
diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c
index 857bfe8c..0b0461c9 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.c
+++ b/plugins/ublox/mm-modem-helpers-ublox.c
@@ -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;
+}
diff --git a/plugins/ublox/mm-modem-helpers-ublox.h b/plugins/ublox/mm-modem-helpers-ublox.h
index e8b9f22b..c97724da 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.h
+++ b/plugins/ublox/mm-modem-helpers-ublox.h
@@ -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 */
diff --git a/plugins/ublox/tests/test-modem-helpers-ublox.c b/plugins/ublox/tests/test-modem-helpers-ublox.c
index 078d1c1a..d1e5e497 100644
--- a/plugins/ublox/tests/test-modem-helpers-ublox.c
+++ b/plugins/ublox/tests/test-modem-helpers-ublox.c
@@ -103,6 +103,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
_mm_log (const char *loc,
@@ -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 ();
}