diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-08-04 10:38:40 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-10-12 11:29:52 +0200 |
commit | 81715ee591599d0774b43006691998bb461f8fa9 (patch) | |
tree | e57ef65a1f3e4bf482617d9509675167f484cee3 /plugins/ublox/mm-modem-helpers-ublox.c | |
parent | bc07ec0835a524970e1c35b055788b35da9b0d23 (diff) |
ublox: new +UIPADDR=N response parser
Diffstat (limited to 'plugins/ublox/mm-modem-helpers-ublox.c')
-rw-r--r-- | plugins/ublox/mm-modem-helpers-ublox.c | 97 |
1 files changed, 97 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; +} |