summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2013-04-24 14:46:23 -0500
committerDan Williams <dcbw@redhat.com>2013-04-25 15:14:14 -0500
commit2e8866c8b74c50c3c5318b13cfc78530a6130c41 (patch)
tree3a2ddd5f913952ce12089c55521921ebab77505d
parent7d3a4aba4fb0f7920e40f88836698a0a10bc7e3c (diff)
downloadModemManager-2e8866c8b74c50c3c5318b13cfc78530a6130c41.tar.gz
time: normalize GetNetworkTime() response to local time + timezone info (bgo #697372)
The GetNetworkTime() response is defined to be an ISO8601 string, which is in turn defined to be in local time. Make sure that's reflected in the documentation, and append the timezone offset to UTC where we have it. Oddly, Icera devices return their time info in UTC with an offset to the local timezone, so we have to jump through some hoops there to convert the response to localtime based on the reported offset. Some additional fixes by Aleksander Morgado <aleksander@lanedo.com>. https://bugzilla.gnome.org/show_bug.cgi?id=697372
-rw-r--r--introspection/org.freedesktop.ModemManager1.Modem.Time.xml6
-rw-r--r--plugins/icera/mm-broadband-modem-icera.c94
-rw-r--r--plugins/novatel/mm-broadband-modem-novatel.c5
-rw-r--r--plugins/sierra/mm-broadband-modem-sierra.c4
-rw-r--r--src/mm-modem-helpers.c32
-rw-r--r--src/mm-modem-helpers.h9
6 files changed, 110 insertions, 40 deletions
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Time.xml b/introspection/org.freedesktop.ModemManager1.Modem.Time.xml
index 5278c774a..0558f0292 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Time.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Time.xml
@@ -20,9 +20,11 @@
<!--
GetNetworkTime:
- @time: If the network time is known, a string containing date and time in ISO 8601 format. If the network time is unknown, the empty string.
+ @time: If the network time is known, a string containing local date,
+ time, and (if available) UTC offset in ISO 8601 format. If the network
+ time is unknown, the empty string.
- Gets the current network time.
+ Gets the current network time in local time.
This method will only work if the modem tracks, or can request, the
current network time; it will not attempt to use previously-received
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c
index bedf91ce4..e71557c4e 100644
--- a/plugins/icera/mm-broadband-modem-icera.c
+++ b/plugins/icera/mm-broadband-modem-icera.c
@@ -1493,7 +1493,9 @@ parse_tlts_query_reply (const gchar *response,
gint second;
gchar sign;
gint offset;
+ GDateTime *utc, *adjusted;
+ /* TLTS reports UTC time with the TZ offset to *local* time */
response = mm_strip_tag (response, "*TLTS: ");
if (sscanf (response,
"\"%02d/%02d/%02d,%02d:%02d:%02d%c%02d\"",
@@ -1504,42 +1506,70 @@ parse_tlts_query_reply (const gchar *response,
&minute,
&second,
&sign,
- &offset) == 8) {
- /* Offset comes in 15-min intervals */
- offset *= 15;
- /* Apply sign to offset */
- if (sign == '-')
- offset *= -1;
-
- /* If asked for it, build timezone information */
- if (tz) {
- *tz = mm_network_timezone_new ();
- mm_network_timezone_set_offset (*tz, offset);
- }
+ &offset) != 8) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Unknown *TLTS response: %s",
+ response);
+ return FALSE;
+ }
- if (iso8601) {
- /* Icera modems only report a 2-digit year, while ISO-8601 requires
- * a 4-digit year. Assume 2000.
- */
- if (year < 100)
- year += 2000;
-
- /* don't give tz info in the date/time string, we have another
- * property for that */
- *iso8601 = g_strdup_printf ("%04d/%02d/%02d %02d:%02d:%02d",
- year, month, day,
- hour, minute, second);
- }
+ /* Icera modems only report a 2-digit year, while ISO-8601 requires
+ * a 4-digit year. Assume 2000.
+ */
+ if (year < 100)
+ year += 2000;
- return TRUE;
+ /* Offset comes in 15-min units */
+ offset *= 15;
+ /* Apply sign to offset; */
+ if (sign == '-')
+ offset *= -1;
+
+ utc = g_date_time_new_utc (year, month, day, hour, minute, second);
+ if (!utc) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Invalid *TLTS date/time: %s",
+ response);
+ return FALSE;
}
- g_set_error (error,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Unknown *TLTS response: %s",
- response);
- return FALSE;
+ /* Convert UTC time to local time by adjusting by the timezone offset */
+ adjusted = g_date_time_add_minutes (utc, offset);
+ g_date_time_unref (utc);
+ if (!adjusted) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Failed to convert modem time to local time (offset %d)",
+ offset);
+ return FALSE;
+ }
+
+ /* Convert offset from minutes-to-UTC to minutes-from-UTC */
+ offset *= -1;
+
+ if (tz) {
+ *tz = mm_network_timezone_new ();
+ mm_network_timezone_set_offset (*tz, offset);
+ }
+
+ if (iso8601) {
+ *iso8601 = mm_new_iso8601_time (g_date_time_get_year (adjusted),
+ g_date_time_get_month (adjusted),
+ g_date_time_get_day_of_month (adjusted),
+ g_date_time_get_hour (adjusted),
+ g_date_time_get_minute (adjusted),
+ g_date_time_get_second (adjusted),
+ TRUE,
+ offset);
+ }
+
+ g_date_time_unref (adjusted);
+ return TRUE;
}
static MMNetworkTimezone *
diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c
index f03767523..3d84509b1 100644
--- a/plugins/novatel/mm-broadband-modem-novatel.c
+++ b/plugins/novatel/mm-broadband-modem-novatel.c
@@ -1012,9 +1012,8 @@ parse_nwltime_reply (const char *response,
mm_get_uint_from_match_info (match_info, 6, &second) &&
mm_get_int_from_match_info (match_info, 8, &utc_offset)) {
- /* Return ISO-8601 format date/time string */
- result = g_strdup_printf ("%04d/%02d/%02d %02d:%02d:%02d",
- year, month, day, hour, minute, second);
+ result = mm_new_iso8601_time (year, month, day, hour, minute, second,
+ TRUE, utc_offset * 60);
if (out_tz) {
*out_tz = mm_network_timezone_new ();
mm_network_timezone_set_offset (*out_tz, utc_offset * 60);
diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c
index 301f41eb9..7cb8e6cf1 100644
--- a/plugins/sierra/mm-broadband-modem-sierra.c
+++ b/plugins/sierra/mm-broadband-modem-sierra.c
@@ -1337,9 +1337,7 @@ parse_time (const gchar *response,
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)) {
- /* Return ISO-8601 format date/time string */
- result = g_strdup_printf ("%04d/%02d/%02d %02d:%02d:%02d",
- year, month, day, hour, minute, second);
+ result = mm_new_iso8601_time (year, month, day, hour, minute, second, FALSE, 0);
} else {
g_set_error (error,
MM_CORE_ERROR,
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index 09bb71d79..44a00a53f 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -216,6 +216,38 @@ mm_filter_current_bands (const GArray *supported_bands,
/*****************************************************************************/
+gchar *
+mm_new_iso8601_time (guint year,
+ guint month,
+ guint day,
+ guint hour,
+ guint minute,
+ guint second,
+ gboolean have_offset,
+ gint offset_minutes)
+{
+ GString *str;
+
+ str = g_string_sized_new (30);
+ g_string_append_printf (str, "%04d-%02d-%02dT%02d:%02d:%02d",
+ year, month, day, hour, minute, second);
+ if (have_offset) {
+ if (offset_minutes >=0 ) {
+ g_string_append_printf (str, "+%02d:%02d",
+ offset_minutes / 60,
+ offset_minutes % 60);
+ } else {
+ offset_minutes *= -1;
+ g_string_append_printf (str, "-%02d:%02d",
+ offset_minutes / 60,
+ offset_minutes % 60);
+ }
+ }
+ return g_string_free (str, FALSE);
+}
+
+/*****************************************************************************/
+
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
#define CREG1 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])"
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index eb02337e5..5a8ba4930 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -64,6 +64,15 @@ guint mm_netmask_to_cidr (const gchar *netmask);
GArray *mm_filter_current_bands (const GArray *supported_bands,
const GArray *current_bands);
+gchar *mm_new_iso8601_time (guint year,
+ guint month,
+ guint day,
+ guint hour,
+ guint minute,
+ guint second,
+ gboolean have_offset,
+ gint offset_minutes);
+
/*****************************************************************************/
/* 3GPP specific helpers and utilities */
/*****************************************************************************/