<div dir="ltr"><div>This is a new revision of the patch incorporating your feedback.</div><div><br></div><div><br></div><div>Add support for querying the real-time clock to the Telit plugin.</div><div>Tested with a Telit HE910 modem.</div><div>---</div><div> .gitignore | 1 +</div><div> plugins/Makefile.am | 15 +++</div><div> plugins/telit/mm-broadband-modem-telit.c | 101 +++++++++++++++++++-</div><div> plugins/telit/mm-modem-helpers-telit.c | 97 +++++++++++++++++++</div><div> plugins/telit/mm-modem-helpers-telit.h | 29 ++++++</div><div> plugins/telit/tests/test-modem-helpers-telit.c | 126 +++++++++++++++++++++++++</div><div> 6 files changed, 368 insertions(+), 1 deletion(-)</div><div> create mode 100644 plugins/telit/mm-modem-helpers-telit.c</div><div> create mode 100644 plugins/telit/mm-modem-helpers-telit.h</div><div> create mode 100644 plugins/telit/tests/test-modem-helpers-telit.c</div><div><br></div><div>diff --git a/.gitignore b/.gitignore</div><div>index 08366fd..3c020e6 100644</div><div>--- a/.gitignore</div><div>+++ b/.gitignore</div><div>@@ -160,6 +160,7 @@ Makefile.in</div><div> /plugins/test-modem-helpers-cinterion*</div><div> /plugins/test-modem-helpers-icera*</div><div> /plugins/test-modem-helpers-mbm*</div><div>+/plugins/test-modem-helpers-telit*</div><div> /plugins/test-service-*</div><div> </div><div> /test/lsudev</div><div>diff --git a/plugins/Makefile.am b/plugins/Makefile.am</div><div>index 1e30b1a..7759e7f 100644</div><div>--- a/plugins/Makefile.am</div><div>+++ b/plugins/Makefile.am</div><div>@@ -540,12 +540,27 @@ libmm_plugin_via_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)</div><div> libmm_plugin_telit_la_SOURCES = \</div><div> <span class="" style="white-space:pre"> </span>telit/mm-plugin-telit.c \</div><div> <span class="" style="white-space:pre"> </span>telit/mm-plugin-telit.h \</div><div>+<span class="" style="white-space:pre"> </span>telit/mm-modem-helpers-telit.c \</div><div>+<span class="" style="white-space:pre"> </span>telit/mm-modem-helpers-telit.h \</div><div> <span class="" style="white-space:pre"> </span>telit/mm-broadband-modem-telit.c \</div><div> <span class="" style="white-space:pre"> </span>telit/mm-broadband-modem-telit.h</div><div> libmm_plugin_telit_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)</div><div> libmm_plugin_telit_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)</div><div> udevrules_DATA += telit/77-mm-telit-port-types.rules</div><div> </div><div>+noinst_PROGRAMS += test-modem-helpers-telit</div><div>+test_modem_helpers_telit_SOURCES = \</div><div>+<span class="" style="white-space:pre"> </span>telit/mm-modem-helpers-telit.c \</div><div>+<span class="" style="white-space:pre"> </span>telit/mm-modem-helpers-telit.h \</div><div>+<span class="" style="white-space:pre"> </span>telit/tests/test-modem-helpers-telit.c</div><div>+test_modem_helpers_telit_CPPFLAGS = \</div><div>+<span class="" style="white-space:pre"> </span>-I$(top_srcdir)/plugins/telit \</div><div>+<span class="" style="white-space:pre"> </span>$(PLUGIN_COMMON_COMPILER_FLAGS)</div><div>+test_modem_helpers_telit_LDADD = \</div><div>+ $(top_builddir)/libmm-glib/<a href="http://libmm-glib.la">libmm-glib.la</a> \</div><div>+ $(top_builddir)/src/<a href="http://libmodem-helpers.la">libmodem-helpers.la</a></div><div>+test_modem_helpers_telit_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)</div><div>+</div><div> # MTK</div><div> libmm_plugin_mtk_la_SOURCES = \</div><div> <span class="" style="white-space:pre"> </span>mtk/mm-plugin-mtk.c \</div><div>diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c</div><div>index 5e1dbff..f102549 100644</div><div>--- a/plugins/telit/mm-broadband-modem-telit.c</div><div>+++ b/plugins/telit/mm-broadband-modem-telit.c</div><div>@@ -27,14 +27,18 @@</div><div> #include "mm-log.h"</div><div> #include "mm-errors-types.h"</div><div> #include "mm-modem-helpers.h"</div><div>+#include "mm-modem-helpers-telit.h"</div><div> #include "mm-base-modem-at.h"</div><div> #include "mm-iface-modem.h"</div><div>+#include "mm-iface-modem-time.h"</div><div> #include "mm-broadband-modem-telit.h"</div><div> </div><div> static void iface_modem_init (MMIfaceModem *iface);</div><div>+static void iface_modem_time_init (MMIfaceModemTime *iface);</div><div> </div><div> G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE_BROADBAND_MODEM, 0,</div><div>- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));</div><div>+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)</div><div>+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init));</div><div> </div><div> /*****************************************************************************/</div><div> /* Load access technologies (Modem interface) */</div><div>@@ -175,6 +179,90 @@ load_access_technologies (MMIfaceModem *self,</div><div> }</div><div> </div><div> /*****************************************************************************/</div><div>+/* Load network time (Time interface) */</div><div>+</div><div>+static gchar *</div><div>+modem_time_load_network_time_finish (MMIfaceModemTime *self,</div><div>+ GAsyncResult *res,</div><div>+ GError **error)</div><div>+{</div><div>+ const gchar *response;</div><div>+ gchar *result = NULL;</div><div>+</div><div>+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);</div><div>+ if (response)</div><div>+ mm_telit_parse_cclk_response (response, &result, NULL, error);</div><div>+ return result;</div><div>+}</div><div>+</div><div>+static void</div><div>+modem_time_load_network_time (MMIfaceModemTime *self,</div><div>+ GAsyncReadyCallback callback,</div><div>+ gpointer user_data)</div><div>+{</div><div>+ mm_base_modem_at_command (MM_BASE_MODEM (self),</div><div>+ "+CCLK?",</div><div>+ 3,</div><div>+ FALSE,</div><div>+ callback,</div><div>+ user_data);</div><div>+}</div><div>+</div><div>+/*****************************************************************************/</div><div>+/* Load network timezone (Time interface) */</div><div>+</div><div>+static MMNetworkTimezone *</div><div>+modem_time_load_network_timezone_finish (MMIfaceModemTime *self,</div><div>+ GAsyncResult *res,</div><div>+ GError **error)</div><div>+{</div><div>+ const gchar *response;</div><div>+ MMNetworkTimezone *tz = NULL;</div><div>+</div><div>+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, NULL);</div><div>+ if (response)</div><div>+ mm_telit_parse_cclk_response (response, NULL, &tz, error);</div><div>+ return tz;</div><div>+}</div><div>+</div><div>+static void</div><div>+modem_time_load_network_timezone (MMIfaceModemTime *self,</div><div>+ GAsyncReadyCallback callback,</div><div>+ gpointer user_data)</div><div>+{</div><div>+ mm_base_modem_at_command (MM_BASE_MODEM (self),</div><div>+ "+CCLK?",</div><div>+ 3,</div><div>+ FALSE,</div><div>+ callback,</div><div>+ user_data);</div><div>+}</div><div>+</div><div>+/*****************************************************************************/</div><div>+/* Check support (Time interface) */</div><div>+</div><div>+static gboolean</div><div>+modem_time_check_support_finish (MMIfaceModemTime *self,</div><div>+ GAsyncResult *res,</div><div>+ GError **error)</div><div>+{</div><div>+ return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);</div><div>+}</div><div>+</div><div>+static void</div><div>+modem_time_check_support (MMIfaceModemTime *self,</div><div>+ GAsyncReadyCallback callback,</div><div>+ gpointer user_data)</div><div>+{</div><div>+ mm_base_modem_at_command (MM_BASE_MODEM (self),</div><div>+ "+CCLK?",</div><div>+ 3,</div><div>+ TRUE,</div><div>+ callback,</div><div>+ user_data);</div><div>+}</div><div>+</div><div>+/*****************************************************************************/</div><div> </div><div> MMBroadbandModemTelit *</div><div> mm_broadband_modem_telit_new (const gchar *device,</div><div>@@ -205,6 +293,17 @@ iface_modem_init (MMIfaceModem *iface)</div><div> }</div><div> </div><div> static void</div><div>+iface_modem_time_init (MMIfaceModemTime *iface)</div><div>+{</div><div>+ iface->check_support = modem_time_check_support;</div><div>+ iface->check_support_finish = modem_time_check_support_finish;</div><div>+ iface->load_network_time = modem_time_load_network_time;</div><div>+ iface->load_network_time_finish = modem_time_load_network_time_finish;</div><div>+ iface->load_network_timezone = modem_time_load_network_timezone;</div><div>+ iface->load_network_timezone_finish = modem_time_load_network_timezone_finish;</div><div>+}</div><div>+</div><div>+static void</div><div> mm_broadband_modem_telit_class_init (MMBroadbandModemTelitClass *klass)</div><div> {</div><div> }</div><div>diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c</div><div>new file mode 100644</div><div>index 0000000..19f6625</div><div>--- /dev/null</div><div>+++ b/plugins/telit/mm-modem-helpers-telit.c</div><div>@@ -0,0 +1,97 @@</div><div>+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */</div><div>+/*</div><div>+ * This program is free software; you can redistribute it and/or modify</div><div>+ * it under the terms of the GNU General Public License as published by</div><div>+ * the Free Software Foundation; either version 2 of the License, or</div><div>+ * (at your option) any later version.</div><div>+ *</div><div>+ * This program is distributed in the hope that it will be useful,</div><div>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</div><div>+ * GNU General Public License for more details:</div><div>+ *</div><div>+ * Copyright (C) 2015 Google Inc.</div><div>+ *</div><div>+ */</div><div>+</div><div>+#include <ModemManager.h></div><div>+#define _LIBMM_INSIDE_MM</div><div>+#include <libmm-glib.h></div><div>+</div><div>+#include "mm-modem-helpers.h"</div><div>+#include "mm-modem-helpers-telit.h"</div><div>+</div><div>+/*****************************************************************************/</div><div>+/* +CCLK response parser */</div><div>+</div><div>+gboolean</div><div>+mm_telit_parse_cclk_response (const char *response,</div><div>+ gchar **iso8601p,</div><div>+ MMNetworkTimezone **tzp,</div><div>+ GError **error)</div><div>+{</div><div>+ GRegex *r;</div><div>+ GMatchInfo *match_info = NULL;</div><div>+ GError *match_error = NULL;</div><div>+ guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;</div><div>+ gint tz = 0;</div><div>+ gboolean ret = FALSE;</div><div>+</div><div>+ g_assert (iso8601p || tzp); /* at least one */</div><div>+</div><div>+ /* Sample reply: +CCLK: "15/03/05,14:14:26-32" */</div><div>+ r = g_regex_new ("[+]CCLK: \"(\\d+)/(\\d+)/(\\d+),(\\d+):(\\d+):(\\d+)([-+]\\d+)\"", 0, 0, NULL);</div><div>+ g_assert (r != NULL);</div><div>+</div><div>+ if (!g_regex_match_full (r, response, -1, 0, 0, &match_info, &match_error)) {</div><div>+ if (match_error) {</div><div>+ g_propagate_error (error, match_error);</div><div>+ g_prefix_error (error, "Could not parse +CCLK results: ");</div><div>+ } else {</div><div>+ g_set_error_literal (error,</div><div>+ MM_CORE_ERROR,</div><div>+ MM_CORE_ERROR_FAILED,</div><div>+ "Couldn't match +CCLK reply");</div><div>+ }</div><div>+ } else {</div><div>+ /* Remember that g_match_info_get_match_count() includes match #0 */</div><div>+ g_assert (g_match_info_get_match_count (match_info) >= 8);</div><div>+</div><div>+ if (mm_get_uint_from_match_info (match_info, 1, &year) &&</div><div>+ mm_get_uint_from_match_info (match_info, 2, &month) &&</div><div>+ mm_get_uint_from_match_info (match_info, 3, &day) &&</div><div>+ mm_get_uint_from_match_info (match_info, 4, &hour) &&</div><div>+ mm_get_uint_from_match_info (match_info, 5, &minute) &&</div><div>+ mm_get_uint_from_match_info (match_info, 6, &second) &&</div><div>+ mm_get_int_from_match_info (match_info, 7, &tz)) {</div><div>+ /* adjust year */</div><div>+ year += 2000;</div><div>+ /*</div><div>+ * tz = timezone offset in 15 minute intervals</div><div>+ */</div><div>+ if (iso8601p) {</div><div>+ /* Return ISO-8601 format date/time string */</div><div>+ *iso8601p = mm_new_iso8601_time (year, month, day, hour,</div><div>+ minute, second,</div><div>+ TRUE, (tz * 15));</div><div>+ }</div><div>+ if (tzp) {</div><div>+ *tzp = mm_network_timezone_new ();</div><div>+ mm_network_timezone_set_offset (*tzp, tz * 15);</div><div>+ }</div><div>+</div><div>+ ret = TRUE;</div><div>+ } else {</div><div>+ g_set_error_literal (error,</div><div>+ MM_CORE_ERROR,</div><div>+ MM_CORE_ERROR_FAILED,</div><div>+ "Failed to parse +CCLK reply");</div><div>+ }</div><div>+ }</div><div>+</div><div>+ if (match_info)</div><div>+ g_match_info_free (match_info);</div><div>+ g_regex_unref (r);</div><div>+</div><div>+ return ret;</div><div>+}</div><div>diff --git a/plugins/telit/mm-modem-helpers-telit.h b/plugins/telit/mm-modem-helpers-telit.h</div><div>new file mode 100644</div><div>index 0000000..7b45242</div><div>--- /dev/null</div><div>+++ b/plugins/telit/mm-modem-helpers-telit.h</div><div>@@ -0,0 +1,29 @@</div><div>+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */</div><div>+/*</div><div>+ * This program is free software; you can redistribute it and/or modify</div><div>+ * it under the terms of the GNU General Public License as published by</div><div>+ * the Free Software Foundation; either version 2 of the License, or</div><div>+ * (at your option) any later version.</div><div>+ *</div><div>+ * This program is distributed in the hope that it will be useful,</div><div>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</div><div>+ * GNU General Public License for more details:</div><div>+ *</div><div>+ * Copyright (C) 2015 Google Inc.</div><div>+ */</div><div>+</div><div>+#ifndef MM_MODEM_HELPERS_TELIT_H</div><div>+#define MM_MODEM_HELPERS_TELIT_H</div><div>+</div><div>+#include <libmm-glib.h></div><div>+</div><div>+/*****************************************************************************/</div><div>+/* +CCLK response parser */</div><div>+</div><div>+gboolean mm_telit_parse_cclk_response (const gchar *response,</div><div>+ gchar **iso8601p,</div><div>+ MMNetworkTimezone **tzp,</div><div>+ GError **error);</div><div>+</div><div>+#endif /* MM_MODEM_HELPERS_TELIT_H */</div><div>diff --git a/plugins/telit/tests/test-modem-helpers-telit.c b/plugins/telit/tests/test-modem-helpers-telit.c</div><div>new file mode 100644</div><div>index 0000000..162a1c9</div><div>--- /dev/null</div><div>+++ b/plugins/telit/tests/test-modem-helpers-telit.c</div><div>@@ -0,0 +1,126 @@</div><div>+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */</div><div>+/*</div><div>+ * This program is free software; you can redistribute it and/or modify</div><div>+ * it under the terms of the GNU General Public License as published by</div><div>+ * the Free Software Foundation; either version 2 of the License, or</div><div>+ * (at your option) any later version.</div><div>+ *</div><div>+ * This program is distributed in the hope that it will be useful,</div><div>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</div><div>+ * GNU General Public License for more details:</div><div>+ *</div><div>+ * Copyright (C) 2015 Google Inc.</div><div>+ */</div><div>+</div><div>+#include <glib.h></div><div>+#include <glib-object.h></div><div>+#include <locale.h></div><div>+</div><div>+#include "mm-log.h"</div><div>+#include "mm-modem-helpers-telit.h"</div><div>+</div><div>+/*****************************************************************************/</div><div>+/* Test +CCLK responses */</div><div>+</div><div>+typedef struct {</div><div>+ const gchar *str;</div><div>+ gboolean ret;</div><div>+ gboolean test_iso8601;</div><div>+ gboolean test_tz;</div><div>+ gchar *iso8601;</div><div>+ gint32 offset;</div><div>+} CclkTest;</div><div>+</div><div>+static const CclkTest cclk_tests[] = {</div><div>+ { "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, TRUE, FALSE,</div><div>+ "2014-08-05T04:00:21+10:00", 600 },</div><div>+ { "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, FALSE, TRUE,</div><div>+ "2014-08-05T04:00:21+10:00", 600 },</div><div>+ { "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, TRUE, TRUE,</div><div>+ "2014-08-05T04:00:21+10:00", 600 },</div><div>+</div><div>+ { "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, FALSE,</div><div>+ "2015-02-28T20:30:40-08:00", -480 },</div><div>+ { "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, FALSE, TRUE,</div><div>+ "2015-02-28T20:30:40-08:00", -480 },</div><div>+ { "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, TRUE,</div><div>+ "2015-02-28T20:30:40-08:00", -480 },</div><div>+</div><div>+ { "+CCLK: \"XX/XX/XX,XX:XX:XX+XX\"", FALSE, TRUE, FALSE,</div><div>+ NULL, MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN },</div><div>+</div><div>+ { NULL, FALSE, FALSE, FALSE, NULL, MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN }</div><div>+};</div><div>+</div><div>+static void</div><div>+test_cclk (void)</div><div>+{</div><div>+ guint i;</div><div>+</div><div>+ for (i = 0; cclk_tests[i].str; i++) {</div><div>+ GError *error = NULL;</div><div>+ gchar *iso8601 = NULL;</div><div>+ MMNetworkTimezone *tz = NULL;</div><div>+ gboolean ret;</div><div>+</div><div>+ ret = mm_telit_parse_cclk_response (cclk_tests[i].str,</div><div>+ cclk_tests[i].test_iso8601 ? &iso8601 : NULL,</div><div>+ cclk_tests[i].test_tz ? &tz : NULL,</div><div>+ &error);</div><div>+</div><div>+ g_assert (ret == cclk_tests[i].ret);</div><div>+ g_assert (ret == (error ? FALSE : TRUE));</div><div>+</div><div>+ g_clear_error (&error);</div><div>+</div><div>+ if (cclk_tests[i].test_iso8601)</div><div>+ g_assert_cmpstr (cclk_tests[i].iso8601, ==, iso8601);</div><div>+</div><div>+ if (cclk_tests[i].test_tz) {</div><div>+ g_assert (mm_network_timezone_get_offset (tz) == cclk_tests[i].offset);</div><div>+ g_assert (mm_network_timezone_get_dst_offset (tz) == MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN);</div><div>+ g_assert (mm_network_timezone_get_leap_seconds (tz) == MM_NETWORK_TIMEZONE_LEAP_SECONDS_UNKNOWN);</div><div>+ }</div><div>+</div><div>+ if (iso8601)</div><div>+ g_free (iso8601);</div><div>+</div><div>+ if (tz)</div><div>+ g_object_unref (tz);</div><div>+ }</div><div>+}</div><div>+</div><div>+/*****************************************************************************/</div><div>+</div><div>+void</div><div>+_mm_log (const char *loc,</div><div>+ const char *func,</div><div>+ guint32 level,</div><div>+ const char *fmt,</div><div>+ ...)</div><div>+{</div><div>+#if defined ENABLE_TEST_MESSAGE_TRACES</div><div>+ /* Dummy log function */</div><div>+ va_list args;</div><div>+ gchar *msg;</div><div>+</div><div>+ va_start (args, fmt);</div><div>+ msg = g_strdup_vprintf (fmt, args);</div><div>+ va_end (args);</div><div>+ g_print ("%s\n", msg);</div><div>+ g_free (msg);</div><div>+#endif</div><div>+}</div><div>+</div><div>+int main (int argc, char **argv)</div><div>+{</div><div>+ setlocale (LC_ALL, "");</div><div>+</div><div>+ g_type_init ();</div><div>+ g_test_init (&argc, &argv, NULL);</div><div>+</div><div>+ g_test_add_func ("/MM/telit/cclk", test_cclk);</div><div>+</div><div>+ return g_test_run ();</div><div>+}</div><div>-- </div><div>2.2.0.rc0.207.ga3a616c</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 11, 2015 at 11:41 AM, Aleksander Morgado <span dir="ltr"><<a href="mailto:aleksander@aleksander.es" target="_blank">aleksander@aleksander.es</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hey,<br>
<div><div class="h5"><br>
On Wed, Mar 11, 2015 at 6:49 PM, Jason Simmons <<a href="mailto:jsimmons@chromium.org">jsimmons@chromium.org</a>> wrote:<br>
> Add support for querying the real-time clock to the Telit plugin.<br>
> Tested with a Telit HE910 modem.<br>
> ---<br>
> plugins/telit/mm-broadband-modem-telit.c | 174<br>
> ++++++++++++++++++++++++++++++-<br>
> 1 file changed, 173 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/plugins/telit/mm-broadband-modem-telit.c<br>
> b/plugins/telit/mm-broadband-modem-telit.c<br>
> index 5e1dbff..429a735 100644<br>
> --- a/plugins/telit/mm-broadband-modem-telit.c<br>
> +++ b/plugins/telit/mm-broadband-modem-telit.c<br>
> @@ -29,12 +29,15 @@<br>
> #include "mm-modem-helpers.h"<br>
> #include "mm-base-modem-at.h"<br>
> #include "mm-iface-modem.h"<br>
> +#include "mm-iface-modem-time.h"<br>
> #include "mm-broadband-modem-telit.h"<br>
><br>
> static void iface_modem_init (MMIfaceModem *iface);<br>
> +static void iface_modem_time_init (MMIfaceModemTime *iface);<br>
><br>
> G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit,<br>
> MM_TYPE_BROADBAND_MODEM, 0,<br>
> - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM,<br>
> iface_modem_init));<br>
> + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM,<br>
> iface_modem_init)<br>
> + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME,<br>
> iface_modem_time_init));<br>
><br>
><br>
> /*****************************************************************************/<br>
> /* Load access technologies (Modem interface) */<br>
> @@ -175,6 +178,164 @@ load_access_technologies (MMIfaceModem *self,<br>
> }<br>
><br>
><br>
> /*****************************************************************************/<br>
> +/* Load network time (Time interface) */<br>
> +<br>
> +static gboolean<br>
> +parse_cclk_reply (const char *response,<br>
> + gchar **iso8601p,<br>
> + MMNetworkTimezone **tzp,<br>
> + GError **error)<br>
<br>
</div></div>Could you put this in a mm-modem-helpers-telit.c|h set of files in the<br>
telit plugin, and add unit tests? You can check e.g. how that is done<br>
in the Huawei plugin for the ^TIME response parsers.<br>
<div><div class="h5"><br>
> +{<br>
> + GRegex *r;<br>
> + GMatchInfo *match_info = NULL;<br>
> + GError *match_error = NULL;<br>
> + guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;<br>
> + gint tz = 0;<br>
> + gboolean ret = FALSE;<br>
> +<br>
> + g_assert (iso8601p || tzp); /* at least one */<br>
> +<br>
> + /* Sample reply: +CCLK: "15/03/05,14:14:26-32" */<br>
> + r = g_regex_new ("[+]CCLK:<br>
> \"(\\d+)/(\\d+)/(\\d+),(\\d+):(\\d+):(\\d+)([-+]\\d+)\"", 0, 0, NULL);<br>
> + g_assert (r != NULL);<br>
> +<br>
> + if (!g_regex_match_full (r, response, -1, 0, 0, &match_info,<br>
> &match_error)) {<br>
> + if (match_error) {<br>
> + g_propagate_error (error, match_error);<br>
> + g_prefix_error (error, "Could not parse +CCLK results: ");<br>
> + } else {<br>
> + g_set_error_literal (error,<br>
> + MM_CORE_ERROR,<br>
> + MM_CORE_ERROR_FAILED,<br>
> + "Couldn't match +CCLK reply");<br>
> + }<br>
> + } else {<br>
> + /* Remember that g_match_info_get_match_count() includes match #0<br>
> */<br>
> + g_assert (g_match_info_get_match_count (match_info) >= 8);<br>
> +<br>
> + if (mm_get_uint_from_match_info (match_info, 1, &year) &&<br>
> + mm_get_uint_from_match_info (match_info, 2, &month) &&<br>
> + mm_get_uint_from_match_info (match_info, 3, &day) &&<br>
> + mm_get_uint_from_match_info (match_info, 4, &hour) &&<br>
> + mm_get_uint_from_match_info (match_info, 5, &minute) &&<br>
> + mm_get_uint_from_match_info (match_info, 6, &second) &&<br>
> + mm_get_int_from_match_info (match_info, 7, &tz)) {<br>
> + /* adjust year */<br>
> + year += 2000;<br>
> + /*<br>
> + * tz = timezone offset in 15 minute intervals<br>
> + */<br>
> + if (iso8601p) {<br>
> + /* Return ISO-8601 format date/time string */<br>
> + *iso8601p = mm_new_iso8601_time (year, month, day, hour,<br>
> + minute, second,<br>
> + TRUE, (tz * 15));<br>
> + }<br>
> + if (tzp) {<br>
> + *tzp = mm_network_timezone_new ();<br>
> + mm_network_timezone_set_offset (*tzp, tz * 15);<br>
> + }<br>
> +<br>
> + ret = TRUE;<br>
> + } else {<br>
> + g_set_error_literal (error,<br>
> + MM_CORE_ERROR,<br>
> + MM_CORE_ERROR_FAILED,<br>
> + "Failed to parse +CCLK reply");<br>
> + }<br>
> + }<br>
> +<br>
> + if (match_info)<br>
> + g_match_info_free (match_info);<br>
> + g_regex_unref (r);<br>
> +<br>
> + return ret;<br>
> +}<br>
> +<br>
> +static gchar *<br>
> +modem_time_load_network_time_finish (MMIfaceModemTime *self,<br>
> + GAsyncResult *res,<br>
> + GError **error)<br>
> +{<br>
> + const gchar *response;<br>
> + gchar *result = NULL;<br>
> +<br>
> + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res,<br>
> error);<br>
> + if (response)<br>
> + parse_cclk_reply (response, &result, NULL, error);<br>
> + return result;<br>
> +}<br>
> +<br>
> +static void<br>
> +modem_time_load_network_time (MMIfaceModemTime *self,<br>
> + GAsyncReadyCallback callback,<br>
> + gpointer user_data)<br>
> +{<br>
> + mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> + "+CCLK?",<br>
> + 3,<br>
> + FALSE,<br>
> + callback,<br>
> + user_data);<br>
> +}<br>
> +<br>
> +/*****************************************************************************/<br>
> +/* Load network timezone (Time interface) */<br>
> +<br>
> +static MMNetworkTimezone *<br>
> +modem_time_load_network_timezone_finish (MMIfaceModemTime *self,<br>
> + GAsyncResult *res,<br>
> + GError **error)<br>
> +{<br>
> + const gchar *response;<br>
> + MMNetworkTimezone *tz = NULL;<br>
> +<br>
> + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res,<br>
> NULL);<br>
> + if (response)<br>
> + parse_cclk_reply (response, NULL, &tz, error);<br>
> + return tz;<br>
> +}<br>
> +<br>
> +static void<br>
> +modem_time_load_network_timezone (MMIfaceModemTime *self,<br>
> + GAsyncReadyCallback callback,<br>
> + gpointer user_data)<br>
> +{<br>
> + mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> + "+CCLK?",<br>
> + 3,<br>
> + FALSE,<br>
> + callback,<br>
> + user_data);<br>
> +}<br>
> +<br>
> +/*****************************************************************************/<br>
> +/* Check support (Time interface) */<br>
> +<br>
> +static gboolean<br>
> +modem_time_check_support_finish (MMIfaceModemTime *self,<br>
> + GAsyncResult *res,<br>
> + GError **error)<br>
> +{<br>
> + g_debug("modem_time_check_support_finish");<br>
<br>
</div></div>That previous log message is not useful, please remove it.<br>
<span class=""><br>
> + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT<br>
> (res), error);<br>
<br>
</span>This is wrong. I see that it's also wrong in the novatel plugin, which<br>
does basically the same check.<br>
The correct way to finish() an at_command() operation is to call<br>
at_command_finish(). So, the proper code should be:<br>
<br>
return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);<br>
<br>
This is, return TRUE if mm_base_modem_at_command_finish() returned a<br>
valid non-error string.<br>
<br>
Fixed that for Novatel:<br>
<a href="http://cgit.freedesktop.org/ModemManager/ModemManager/commit/?id=46b2aeae531ea47d3cf3d455305c40694d4f60b7" target="_blank">http://cgit.freedesktop.org/ModemManager/ModemManager/commit/?id=46b2aeae531ea47d3cf3d455305c40694d4f60b7</a><br>
<br>
With this change, we don't assume how<br>
mm_base_modem_at_command_finish() treats the GAsyncResult.<br>
<span class=""><br>
> +}<br>
> +<br>
> +static void<br>
> +modem_time_check_support (MMIfaceModemTime *self,<br>
> + GAsyncReadyCallback callback,<br>
> + gpointer user_data)<br>
> +{<br>
> + g_debug("modem_time_check_support");<br>
<br>
</span>That previous log message is not useful, please remove it.<br>
<div><div class="h5"><br>
> + mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> + "+CCLK?",<br>
> + 3,<br>
> + TRUE,<br>
> + callback,<br>
> + user_data);<br>
> +}<br>
> +<br>
> +/*****************************************************************************/<br>
><br>
> MMBroadbandModemTelit *<br>
> mm_broadband_modem_telit_new (const gchar *device,<br>
> @@ -205,6 +366,17 @@ iface_modem_init (MMIfaceModem *iface)<br>
> }<br>
><br>
> static void<br>
> +iface_modem_time_init (MMIfaceModemTime *iface)<br>
> +{<br>
> + iface->check_support = modem_time_check_support;<br>
> + iface->check_support_finish = modem_time_check_support_finish;<br>
> + iface->load_network_time = modem_time_load_network_time;<br>
> + iface->load_network_time_finish = modem_time_load_network_time_finish;<br>
> + iface->load_network_timezone = modem_time_load_network_timezone;<br>
> + iface->load_network_timezone_finish =<br>
> modem_time_load_network_timezone_finish;<br>
> +}<br>
> +<br>
> +static void<br>
> mm_broadband_modem_telit_class_init (MMBroadbandModemTelitClass *klass)<br>
> {<br>
> }<br>
> --<br>
> 2.2.0.rc0.207.ga3a616c<br>
><br>
><br>
</div></div>> _______________________________________________<br>
> ModemManager-devel mailing list<br>
> <a href="mailto:ModemManager-devel@lists.freedesktop.org">ModemManager-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel</a><br>
><br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
--<br>
Aleksander<br>
<a href="https://aleksander.es" target="_blank">https://aleksander.es</a><br>
</font></span></blockquote></div><br></div>