Nitpicking...

On Friday 03 December 2010 11:47:26 ext Antti Paila, you wrote:
> diff --git a/plugins/nettime.c b/plugins/nettime.c
> new file mode 100644
> index 0000000..0f99bb1
> --- /dev/null
> +++ b/plugins/nettime.c
> @@ -0,0 +1,293 @@
> +/*
> + *
> + *  oFono - Open Source Telephony
> + *
> + *  Copyright (C) 2008-2010  Nokia Corporation and/or its
> subsidiary(-ies). + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 
> USA + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <string.h>
> +#include <glib.h>
> +
> +#define OFONO_API_SUBJECT_TO_CHANGE
> +#include <ofono/plugin.h>
> +#include <ofono/log.h>
> +#include <ofono/nettime.h>
> +#include <ofono/types.h>
> +#include <gdbus.h>
> +#include "ofono.h"
> +
> +#include "common.h"
> +
> +#define MAX_TIME_STR_LEN 128
> +#define TIME_FORMAT "%FT%TZ"
> +
> +
> +struct nettime_data {
> +     struct ofono_network_time nw_time;
> +     time_t received;
> +};
> +
> +static void nettime_register(struct ofono_nettime_context *);
> +
> +static gboolean encode_time_format(struct ofono_network_time *time,
> +                              struct tm *tm)
> +{
> +     if (time->year < 0)
> +             return FALSE;
> +
> +     tm->tm_year = time->year - 1900;
> +     tm->tm_mon = time->mon - 1;
> +     tm->tm_mday = time->mday;
> +     tm->tm_hour = time->hour;
> +     tm->tm_min = time->min;
> +     tm->tm_sec = time->sec;
> +     tm->tm_gmtoff = time->utcoff;
> +     tm->tm_isdst = time->dst;
> +
> +     return TRUE;
> +}
> +
> +static time_t get_monotonic_time()
> +{
> +     struct timespec ts;
> +     clock_gettime(CLOCK_MONOTONIC, &ts);
> +     return ts.tv_sec;
> +}
> +
> +static struct tm *refresh_nw_time(struct tm *nw_time,
> +                             time_t received)
> +{
> +     time_t now, new_nw_time;
> +
> +     now = get_monotonic_time();
> +     new_nw_time = timegm(nw_time) + now - received;
> +     return gmtime(&new_nw_time);
> +}

Brrr, the result is somewhere in static data. This can cause quite confusing 
behaviour if/when the code is changed. I would much rather use gmtime_r().

That being said, wouldn't it be far simpler to return a second timestamp 
instead of a broken-down time structure over D-Bus? Eventually, timed/whatever 
will want a timestamp anyway to set the system clock or whatever else it wants 
to do with the NITZ.

> +static int fill_time_changed_signal(DBusMessage *signal,
> +             struct nettime_data *ntd)
> +{
> +     DBusMessageIter iter, iter_array;
> +     int time_available;
> +     char buf[MAX_TIME_STR_LEN];
> +     struct tm time_tm, *new_time_tm;
> +     const char *str = buf;
> +
> +     dbus_message_iter_init_append(signal, &iter);
> +     dbus_message_iter_open_container(&iter,
> +                                     DBUS_TYPE_ARRAY,
> +                                     "{sv}",
> +                                     &iter_array);
> +
> +     time_available = encode_time_format(&ntd->nw_time, &time_tm);
> +     if (time_available != 0) {
> +             new_time_tm = refresh_nw_time(&time_tm, ntd->received);
> +             strftime(buf, MAX_TIME_STR_LEN, TIME_FORMAT, new_time_tm);
> +
> +             ofono_dbus_dict_append(&iter_array,
> +                                     "DateAndTime",
> +                                     DBUS_TYPE_STRING,
> +                                     &str);
> +     }
> +
> +     ofono_dbus_dict_append(&iter_array,
> +                             "Timezone",
> +                             DBUS_TYPE_INT32,
> +                             &ntd->nw_time.utcoff);
> +     ofono_dbus_dict_append(&iter_array,
> +                             "DST",
> +                             DBUS_TYPE_UINT32,
> +                             &ntd->nw_time.dst);
> +     dbus_message_iter_close_container(&iter, &iter_array);
> +     return 0;
> +}

Are the time zone offset and the DST always available, but the current time 
not? This seems odd.

Passing the time over D-Bus may cause extra drift/imprecision than we already 
have. I wonder if it would make sense to provide not just the current time but 
both:
- the current time for trivial programs, and
- the system boot time (i.e. nw_time - received) for smarter programs;
  this value cannot drift.

> +static DBusMessage *create_time_changed_signal(
> +                     struct ofono_nettime_context *context)
> +{
> +     DBusMessage *signal;
> +     struct nettime_data *ntd = context->data;
> +     const char *path = ofono_modem_get_path(context->modem);
> +
> +     if (path == NULL) {
> +             ofono_error("Fetching path for modem failed");
> +             return NULL;
> +     }
> +
> +     signal = dbus_message_new_signal(path, OFONO_NETWORK_TIME_INTERFACE,
> +                                     "NetworkTimeChanged");
> +     fill_time_changed_signal(signal, ntd);
> +
> +     return signal;
> +}
> +
> +static void init_time(struct ofono_nettime_context *context)
> +{
> +     struct nettime_data *nettime_data;
> +     context->data = g_try_new0(struct nettime_data, 1);

Hmm, if you don't check the result, I suspect you should g_new0() instead.

> +     nettime_data = context->data;
> +     nettime_data->nw_time.year = -1;
> +}
> +
> +static int nettime_probe(struct ofono_nettime_context *context)
> +{
> +     ofono_debug("Network Time Probe for modem: %p", context->modem);
> +
> +     init_time(context);
> +
> +     nettime_register(context);
> +     return 0;
> +}
> +
> +static void nettime_remove(struct ofono_nettime_context *context)
> +{
> +     DBusConnection *conn;
> +     const char *path;
> +
> +     ofono_debug("Network Time Remove for modem: %p", context->modem);
> +
> +     g_free(context->data);
> +
> +     conn = ofono_dbus_get_connection();
> +     path = ofono_modem_get_path(context->modem);
> +
> +     if (!g_dbus_unregister_interface(conn,
> +                                     path,
> +                                     OFONO_NETWORK_TIME_INTERFACE))
> +             ofono_error("Could not unregister %s interface",
> +                             OFONO_NETWORK_TIME_INTERFACE);
> +
> +     ofono_modem_remove_interface(context->modem,
> +                     OFONO_NETWORK_TIME_INTERFACE);
> +}
> +
> +static void nettime_info_received(struct ofono_nettime_context *context,
> +                             struct ofono_network_time *info)
> +{
> +     DBusMessage *nt_signal;
> +     struct nettime_data *ntd = context->data;
> +
> +     if (info == NULL)
> +             return;
> +
> +     ofono_debug("Received a network time notification on modem: %p",
> +                     context->modem);
> +
> +     ntd->nw_time = *info;
> +     ntd->received = get_monotonic_time();

That works. But I would do the gmtime() conversion here, and store the result 
once and for all, instead of copying the raw data and recompute the conversion 
every time.

> +     nt_signal = create_time_changed_signal(context);
> +     if (nt_signal == NULL) {
> +             ofono_error("Failed to create NetworkTimeChanged signal");
> +             return;
> +     }
> +
> +     g_dbus_send_message(ofono_dbus_get_connection(), nt_signal);
> +}

-- 
Rémi Denis-Courmont
Nokia Devices R&D, Maemo Software, Helsinki
_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to