diff options
Diffstat (limited to 'plugins/huawei/mm-modem-helpers-huawei.c')
-rw-r--r-- | plugins/huawei/mm-modem-helpers-huawei.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c index 656c6de0..7612e64d 100644 --- a/plugins/huawei/mm-modem-helpers-huawei.c +++ b/plugins/huawei/mm-modem-helpers-huawei.c @@ -1033,3 +1033,154 @@ mm_huawei_parse_syscfgex_response (const gchar *response, g_strfreev (split); return NULL; } + +/*****************************************************************************/ +/* ^NWTIME response parser */ + +gboolean mm_huawei_parse_nwtime_response (const gchar *response, + gchar **iso8601p, + MMNetworkTimezone **tzp, + GError **error) +{ + GRegex *r; + GMatchInfo *match_info = NULL; + GError *match_error = NULL; + guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, dt = 0; + gint tz = 0; + gboolean ret = FALSE; + + g_assert (iso8601p || tzp); /* at least one */ + + r = g_regex_new ("\\^NWTIME:\\s*(\\d+)/(\\d+)/(\\d+),(\\d+):(\\d+):(\\d*)([\\-\\+\\d]+),(\\d+)$", 0, 0, NULL); + g_assert (r != NULL); + + if (!g_regex_match_full (r, response, -1, 0, 0, &match_info, &match_error)) { + if (match_error) { + g_propagate_error (error, match_error); + g_prefix_error (error, "Could not parse ^NWTIME results: "); + } else { + g_set_error_literal (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Couldn't match ^NWTIME reply"); + } + } else { + /* Remember that g_match_info_get_match_count() includes match #0 */ + g_assert (g_match_info_get_match_count (match_info) >= 9); + + if (mm_get_uint_from_match_info (match_info, 1, &year) && + mm_get_uint_from_match_info (match_info, 2, &month) && + mm_get_uint_from_match_info (match_info, 3, &day) && + mm_get_uint_from_match_info (match_info, 4, &hour) && + mm_get_uint_from_match_info (match_info, 5, &minute) && + mm_get_uint_from_match_info (match_info, 6, &second) && + mm_get_int_from_match_info (match_info, 7, &tz) && + mm_get_uint_from_match_info (match_info, 8, &dt)) { + /* adjust year */ + if (year < 100) + year += 2000; + /* + * tz = timezone offset in 15 minute intervals + * dt = daylight adjustment, 0 = none, 1 = 1 hour, 2 = 2 hours + * other values are marked reserved. + */ + if (iso8601p) { + /* Return ISO-8601 format date/time string */ + *iso8601p = mm_new_iso8601_time (year, month, day, hour, + minute, second, + TRUE, (tz * 15) + (dt * 60)); + } + if (tzp) { + *tzp = mm_network_timezone_new (); + mm_network_timezone_set_offset (*tzp, tz * 15); + mm_network_timezone_set_dst_offset (*tzp, dt * 60); + } + + ret = TRUE; + } else { + g_set_error_literal (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse ^NWTIME reply"); + } + } + + if (match_info) + g_match_info_free (match_info); + g_regex_unref (r); + + return ret; +} + +/*****************************************************************************/ +/* ^TIME response parser */ + +gboolean mm_huawei_parse_time_response (const gchar *response, + gchar **iso8601p, + MMNetworkTimezone **tzp, + GError **error) +{ + GRegex *r; + GMatchInfo *match_info = NULL; + GError *match_error = NULL; + guint year, month, day, hour, minute, second; + gboolean ret = FALSE; + + g_assert (iso8601p || tzp); /* at least one */ + + /* TIME response cannot ever provide TZ info */ + if (tzp) { + g_set_error_literal (error, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "^TIME does not provide timezone information"); + return FALSE; + } + + /* Already in ISO-8601 format, but verify just to be sure */ + r = g_regex_new ("\\^TIME:\\s*(\\d+)/(\\d+)/(\\d+)\\s*(\\d+):(\\d+):(\\d*)$", 0, 0, NULL); + g_assert (r != NULL); + + if (!g_regex_match_full (r, response, -1, 0, 0, &match_info, &match_error)) { + if (match_error) { + g_propagate_error (error, match_error); + g_prefix_error (error, "Could not parse ^TIME results: "); + } else { + g_set_error_literal (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Couldn't match ^TIME reply"); + } + } else { + /* Remember that g_match_info_get_match_count() includes match #0 */ + g_assert (g_match_info_get_match_count (match_info) >= 7); + + if (mm_get_uint_from_match_info (match_info, 1, &year) && + mm_get_uint_from_match_info (match_info, 2, &month) && + mm_get_uint_from_match_info (match_info, 3, &day) && + mm_get_uint_from_match_info (match_info, 4, &hour) && + mm_get_uint_from_match_info (match_info, 5, &minute) && + mm_get_uint_from_match_info (match_info, 6, &second)) { + /* adjust year */ + if (year < 100) + year += 2000; + /* Return ISO-8601 format date/time string */ + if (iso8601p) + *iso8601p = mm_new_iso8601_time (year, month, day, hour, + minute, second, FALSE, 0); + ret = TRUE; + } else { + g_set_error_literal (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse ^TIME reply"); + } + } + + if (match_info) + g_match_info_free (match_info); + g_regex_unref (r); + + return ret; +} + |