Re: [PATCH 7/7] time: Implement in icera
- From: ttuttle <ttuttle chromium org>
- To: networkmanager-list gnome org
- Subject: Re: [PATCH 7/7] time: Implement in icera
- Date: Tue, 24 Jan 2012 13:21:00 -0500
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\"",
> + ×tamp->year,
> + ×tamp->month,
> + ×tamp->day,
> + ×tamp->hour,
> + ×tamp->minute,
> + ×tamp->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]