[PATCH 7/7] time: Implement in icera



Signed-off-by: Thomas Tuttle <ttuttle chromium org>
---
 plugins/mm-modem-icera.c       |   95 ++++++++++++++++++++++++++++++++++++++++
 plugins/mm-modem-icera.h       |   21 +++++++++
 plugins/mm-modem-samsung-gsm.c |   54 ++++++++++++++++++++++-
 3 files changed, 169 insertions(+), 1 deletions(-)

diff --git a/plugins/mm-modem-icera.c b/plugins/mm-modem-icera.c
index 8933142..c86dc49 100644
--- a/plugins/mm-modem-icera.c
+++ b/plugins/mm-modem-icera.c
@@ -729,6 +729,101 @@ mm_modem_icera_get_ip4_config (MMModemIcera *self,
     g_free (command);
 }
 
+static void
+invoke_mm_modem_icera_timestamp_fn (MMCallbackInfo *info)
+{
+    MMModemIceraTimestampFn callback;
+    MMModemIceraTimestamp *timestamp;
+
+    callback = (MMModemIceraTimestampFn) info->callback;
+    timestamp = (MMModemIceraTimestamp *) mm_callback_info_get_result (info);
+
+    callback (MM_MODEM_ICERA (info->modem),
+              timestamp,
+              info->error, info->user_data);
+}
+
+static MMCallbackInfo *
+mm_callback_info_icera_timestamp_new (MMModemIcera *modem,
+                                      MMModemIceraTimestampFn callback,
+                                      gpointer user_data)
+{
+    g_return_val_if_fail (modem != NULL, NULL);
+
+    return mm_callback_info_new_full (MM_MODEM (modem),
+                                      invoke_mm_modem_icera_timestamp_fn,
+				      (GCallback) callback,
+				      user_data);
+}
+
+static void
+get_local_timestamp_done (MMAtSerialPort *port,
+                          GString *response,
+                          GError *error,
+                          gpointer user_data)
+{
+    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+    MMModemIceraTimestamp *timestamp;
+    char sign;
+    int offset;
+
+    /* If the modem has already been removed, return without
+     * scheduling callback */
+    if (mm_callback_info_check_modem_removed (info))
+        return;
+
+    if (error) {
+        info->error = g_error_copy (error);
+        goto out;
+    }
+
+    timestamp = g_malloc0 (sizeof (MMModemIceraTimestamp));
+    mm_callback_info_set_result (info, timestamp, g_free);
+    if (!timestamp) {
+        mm_warn ("failed to allocate timestamp");
+        goto out;
+    }
+
+    if (g_str_has_prefix (response->str, "*TLTS: ") &&
+        sscanf (response->str + 7,
+                "\"%02d/%02d/%02d,%02d:%02d:%02d%c%02d\"",
+                &timestamp->year,
+                &timestamp->month,
+                &timestamp->day,
+                &timestamp->hour,
+                &timestamp->minute,
+                &timestamp->second,
+                &sign, &offset) == 8) {
+        if (sign == '-')
+            timestamp->tz_offset = -offset;
+        else
+            timestamp->tz_offset = offset;
+    } else {
+        mm_warn ("Unknown *TLTS response: %s", response->str);
+        mm_callback_info_set_result (info, NULL, g_free);
+        g_free (timestamp);
+    }
+
+ out:
+    mm_callback_info_schedule (info);
+}
+
+void
+mm_modem_icera_get_local_timestamp (MMModemIcera *self,
+                                    MMModemIceraTimestampFn callback,
+                                    gpointer user_data)
+{
+    MMCallbackInfo *info;
+    MMAtSerialPort *primary;
+
+    info = mm_callback_info_icera_timestamp_new (self, callback, user_data);
+
+    primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
+    g_assert (primary);
+
+    mm_at_serial_port_queue_command (primary, "*TLTS", 3, get_local_timestamp_done, info);
+}
+
 /****************************************************************/
 
 static const char *
diff --git a/plugins/mm-modem-icera.h b/plugins/mm-modem-icera.h
index 77ff200..131580c 100644
--- a/plugins/mm-modem-icera.h
+++ b/plugins/mm-modem-icera.h
@@ -43,6 +43,23 @@ struct _MMModemIcera {
     MMModemIceraPrivate * (*get_private) (MMModemIcera *icera);
 };
 
+typedef struct _MMModemIceraTimestamp MMModemIceraTimestamp;
+
+struct _MMModemIceraTimestamp {
+    int year;
+    int month;
+    int day;
+    int hour;
+    int minute;
+    int second;
+    int tz_offset;
+};
+
+typedef void (*MMModemIceraTimestampFn) (MMModemIcera *modem,
+                                         MMModemIceraTimestamp *timestamp,
+                                         GError *error,
+                                         gpointer user_data);
+
 GType mm_modem_icera_get_type (void);
 
 MMModemIceraPrivate *mm_modem_icera_init_private (void);
@@ -89,5 +106,9 @@ void mm_modem_icera_get_ip4_config (MMModemIcera *self,
                                     MMModemIp4Fn callback,
                                     gpointer user_data);
 
+void mm_modem_icera_get_local_timestamp (MMModemIcera *self,
+                                         MMModemIceraTimestampFn callback,
+                                         gpointer user_data);
+
 #endif  /* MM_MODEM_ICERA_H */
 
diff --git a/plugins/mm-modem-samsung-gsm.c b/plugins/mm-modem-samsung-gsm.c
index d04c78c..192a35b 100755
--- a/plugins/mm-modem-samsung-gsm.c
+++ b/plugins/mm-modem-samsung-gsm.c
@@ -32,19 +32,22 @@
 #include "mm-log.h"
 #include "mm-modem-icera.h"
 #include "mm-utils.h"
+#include "mm-modem-time.h"
 
 static void modem_init (MMModem *modem_class);
 static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class);
 static void modem_simple_init (MMModemSimple *class);
 static void modem_gsm_card_init (MMModemGsmCard *class);
 static void modem_icera_init (MMModemIcera *icera_class);
+static void modem_time_init (MMModemTime *class);
 
 G_DEFINE_TYPE_EXTENDED (MMModemSamsungGsm, mm_modem_samsung_gsm, MM_TYPE_GENERIC_GSM, 0,
                         G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_ICERA, modem_icera_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)
-                        G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init))
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init)
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_TIME, modem_time_init))
 
 #define MM_MODEM_SAMSUNG_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_SAMSUNG_GSM, MMModemSamsungGsmPrivate))
 
@@ -53,6 +56,9 @@ typedef struct {
 
     MMModemIceraPrivate *icera;
     char *band;
+
+    guint time_poll_source;
+    gboolean time_polling;
 } MMModemSamsungGsmPrivate;
 
 #define IPDPADDR_TAG "%IPDPADDR: "
@@ -610,6 +616,46 @@ grab_port (MMModem *modem,
     return !!port;
 }
 
+static void
+poll_timezone_done (MMModemIcera *modem,
+                    MMModemIceraTimestamp *timestamp,
+                    GError *error,
+                    gpointer user_data)
+{
+    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+    gint offset;
+
+    if (error || !timestamp) {
+        return;
+    }
+
+    mm_info ("setting timezone from local timestamp "
+             "%02d/%02d/%02d %02d:%02d:%02d %+02d.",
+            timestamp->year, timestamp->month, timestamp->day,
+            timestamp->hour, timestamp->minute, timestamp->second,
+            timestamp->tz_offset);
+
+    // Offset is in 15-minute intervals, as provided by GSM network
+    offset = 15 * timestamp->tz_offset;
+
+    mm_modem_base_set_network_timezone (MM_MODEM_BASE (modem),
+                                        &offset, NULL, NULL);
+
+    mm_callback_info_schedule (info);
+}
+
+static gboolean
+poll_timezone (MMModemTime *self, MMModemFn callback, gpointer user_data)
+{
+    MMCallbackInfo *info;
+
+    info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
+    mm_modem_icera_get_local_timestamp (MM_MODEM_ICERA (self),
+                                        poll_timezone_done,
+                                        info);
+    return TRUE;
+}
+
 static MMModemIceraPrivate *
 get_icera_private (MMModemIcera *icera)
 {
@@ -652,6 +698,12 @@ modem_gsm_card_init (MMModemGsmCard *class)
 }
 
 static void
+modem_time_init (MMModemTime *class)
+{
+    class->poll_network_timezone = poll_timezone;
+}
+
+static void
 mm_modem_samsung_gsm_init (MMModemSamsungGsm *self)
 {
 }
-- 
1.7.7.3



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]