Re: [PATCH 7/7] time: Implement in icera



Note to self: This causes a double-free if the *TLTS response is
invalid.  Working on a fix.

On Fri, Jan 20, 2012 at 15:21, Thomas Tuttle <ttuttle chromium org> wrote:
> 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]