[PATCH] telit: implement the network time interface for Telit modems
Dan Williams
dcbw at redhat.com
Thu Mar 12 14:43:26 PDT 2015
On Thu, 2015-03-12 at 14:33 -0700, Jason Simmons wrote:
> Moved this into the base broadband modem object. Please take another look.
>
>
> Add support for querying the real-time clock to the Telit plugin.
> Tested with a Telit HE910 modem.
> ---
> src/mm-broadband-modem.c | 96
> ++++++++++++++++++++++++++++++++++++++++++
Looks like your mailer line-wrapped :(
Dan
> src/mm-modem-helpers.c | 75 +++++++++++++++++++++++++++++++++
> src/mm-modem-helpers.h | 9 ++++
> src/tests/test-modem-helpers.c | 73 ++++++++++++++++++++++++++++++++
> 4 files changed, 253 insertions(+)
>
> diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
> index 17c128c..feebbc6 100644
> --- a/src/mm-broadband-modem.c
> +++ b/src/mm-broadband-modem.c
> @@ -7511,6 +7511,96 @@ enable_location_gathering (MMIfaceModemLocation
> *self,
> }
>
> /*****************************************************************************/
> +/* Load network time (Time interface) */
> +
> +static gchar *
> +modem_time_load_network_time_finish (MMIfaceModemTime *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + const gchar *response;
> + gchar *result = NULL;
> +
> + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res,
> error);
> + if (response)
> + mm_parse_cclk_response (response, &result, NULL, error);
> + return result;
> +}
> +
> +static void
> +modem_time_load_network_time (MMIfaceModemTime *self,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + mm_base_modem_at_command (MM_BASE_MODEM (self),
> + "+CCLK?",
> + 3,
> + FALSE,
> + callback,
> + user_data);
> +}
> +
> +/*****************************************************************************/
> +/* Load network timezone (Time interface) */
> +
> +static MMNetworkTimezone *
> +modem_time_load_network_timezone_finish (MMIfaceModemTime *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + const gchar *response;
> + MMNetworkTimezone *tz = NULL;
> +
> + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res,
> NULL);
> + if (response)
> + mm_parse_cclk_response (response, NULL, &tz, error);
> + return tz;
> +}
> +
> +static void
> +modem_time_load_network_timezone (MMIfaceModemTime *self,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + mm_base_modem_at_command (MM_BASE_MODEM (self),
> + "+CCLK?",
> + 3,
> + FALSE,
> + callback,
> + user_data);
> +}
> +
> +/*****************************************************************************/
> +/* Check support (Time interface) */
> +
> +static const MMBaseModemAtCommand time_check_sequence[] = {
> + { "+CTZU=1", 3, TRUE,
> mm_base_modem_response_processor_no_result_continue },
> + { "+CCLK?", 3, TRUE, mm_base_modem_response_processor_string },
> + { NULL }
> +};
> +
> +static gboolean
> +modem_time_check_support_finish (MMIfaceModemTime *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + return !!mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res,
> NULL, error);
> +}
> +
> +static void
> +modem_time_check_support (MMIfaceModemTime *self,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + mm_base_modem_at_sequence (MM_BASE_MODEM (self),
> + time_check_sequence,
> + NULL, /* response_processor_context */
> + NULL, /* response_processor_context_free */
> + callback,
> + user_data);
> +}
> +
> +/*****************************************************************************/
>
> static const gchar *primary_init_sequence[] = {
> /* Ensure echo is off */
> @@ -9824,6 +9914,12 @@ iface_modem_messaging_init (MMIfaceModemMessaging
> *iface)
> static void
> iface_modem_time_init (MMIfaceModemTime *iface)
> {
> + iface->check_support = modem_time_check_support;
> + iface->check_support_finish = modem_time_check_support_finish;
> + iface->load_network_time = modem_time_load_network_time;
> + iface->load_network_time_finish = modem_time_load_network_time_finish;
> + iface->load_network_timezone = modem_time_load_network_timezone;
> + iface->load_network_timezone_finish =
> modem_time_load_network_timezone_finish;
> }
>
> static void
> diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
> index d40082d..9f0feea 100644
> --- a/src/mm-modem-helpers.c
> +++ b/src/mm-modem-helpers.c
> @@ -2621,3 +2621,78 @@ mm_parse_gsn (const char *gsn,
>
> return success;
> }
> +
> +/*****************************************************************************/
> +/* +CCLK response parser */
> +
> +gboolean
> +mm_parse_cclk_response (const char *response,
> + gchar **iso8601p,
> + MMNetworkTimezone **tzp,
> + GError **error)
> +{
> + GRegex *r;
> + GMatchInfo *match_info = NULL;
> + GError *match_error = NULL;
> + guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
> + gint tz = 0;
> + gboolean ret = FALSE;
> +
> + g_assert (iso8601p || tzp); /* at least one */
> +
> + /* Sample reply: +CCLK: "15/03/05,14:14:26-32" */
> + r = g_regex_new ("[+]CCLK:
> \"(\\d+)/(\\d+)/(\\d+),(\\d+):(\\d+):(\\d+)([-+]\\d+)\"", 0, 0, NULL);
> + g_assert (r != NULL);
> +
> + if (!g_regex_match_full (r, response, -1, 0, 0, &match_info,
> &match_error)) {
> + if (match_error) {
> + g_propagate_error (error, match_error);
> + g_prefix_error (error, "Could not parse +CCLK results: ");
> + } else {
> + g_set_error_literal (error,
> + MM_CORE_ERROR,
> + MM_CORE_ERROR_FAILED,
> + "Couldn't match +CCLK reply");
> + }
> + } else {
> + /* Remember that g_match_info_get_match_count() includes match #0
> */
> + g_assert (g_match_info_get_match_count (match_info) >= 8);
> +
> + if (mm_get_uint_from_match_info (match_info, 1, &year) &&
> + mm_get_uint_from_match_info (match_info, 2, &month) &&
> + mm_get_uint_from_match_info (match_info, 3, &day) &&
> + mm_get_uint_from_match_info (match_info, 4, &hour) &&
> + mm_get_uint_from_match_info (match_info, 5, &minute) &&
> + mm_get_uint_from_match_info (match_info, 6, &second) &&
> + mm_get_int_from_match_info (match_info, 7, &tz)) {
> + /* adjust year */
> + year += 2000;
> + /*
> + * tz = timezone offset in 15 minute intervals
> + */
> + if (iso8601p) {
> + /* Return ISO-8601 format date/time string */
> + *iso8601p = mm_new_iso8601_time (year, month, day, hour,
> + minute, second,
> + TRUE, (tz * 15));
> + }
> + if (tzp) {
> + *tzp = mm_network_timezone_new ();
> + mm_network_timezone_set_offset (*tzp, tz * 15);
> + }
> +
> + ret = TRUE;
> + } else {
> + g_set_error_literal (error,
> + MM_CORE_ERROR,
> + MM_CORE_ERROR_FAILED,
> + "Failed to parse +CCLK reply");
> + }
> + }
> +
> + if (match_info)
> + g_match_info_free (match_info);
> + g_regex_unref (r);
> +
> + return ret;
> +}
> diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
> index 0ec59af..2e5d8e4 100644
> --- a/src/mm-modem-helpers.h
> +++ b/src/mm-modem-helpers.h
> @@ -20,6 +20,9 @@
>
> #include <ModemManager.h>
>
> +#define _LIBMM_INSIDE_MM
> +#include <libmm-glib.h>
> +
> #include "glib-object.h"
> #include "mm-charsets.h"
>
> @@ -246,4 +249,10 @@ gboolean mm_parse_gsn (const char *gsn,
> gchar **out_meid,
> gchar **out_esn);
>
> +/* +CCLK response parser */
> +gboolean mm_parse_cclk_response (const gchar *response,
> + gchar **iso8601p,
> + MMNetworkTimezone **tzp,
> + GError **error);
> +
> #endif /* MM_MODEM_HELPERS_H */
> diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
> index b493e6b..9fd2501 100644
> --- a/src/tests/test-modem-helpers.c
> +++ b/src/tests/test-modem-helpers.c
> @@ -2341,6 +2341,77 @@ test_supported_capability_filter (void *f, gpointer
> d)
> }
>
> /*****************************************************************************/
> +/* Test +CCLK responses */
> +
> +typedef struct {
> + const gchar *str;
> + gboolean ret;
> + gboolean test_iso8601;
> + gboolean test_tz;
> + gchar *iso8601;
> + gint32 offset;
> +} CclkTest;
> +
> +static const CclkTest cclk_tests[] = {
> + { "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, TRUE, FALSE,
> + "2014-08-05T04:00:21+10:00", 600 },
> + { "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, FALSE, TRUE,
> + "2014-08-05T04:00:21+10:00", 600 },
> + { "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, TRUE, TRUE,
> + "2014-08-05T04:00:21+10:00", 600 },
> +
> + { "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, FALSE,
> + "2015-02-28T20:30:40-08:00", -480 },
> + { "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, FALSE, TRUE,
> + "2015-02-28T20:30:40-08:00", -480 },
> + { "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, TRUE,
> + "2015-02-28T20:30:40-08:00", -480 },
> +
> + { "+CCLK: \"XX/XX/XX,XX:XX:XX+XX\"", FALSE, TRUE, FALSE,
> + NULL, MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN },
> +
> + { NULL, FALSE, FALSE, FALSE, NULL, MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN }
> +};
> +
> +static void
> +test_cclk_response (void)
> +{
> + guint i;
> +
> + for (i = 0; cclk_tests[i].str; i++) {
> + GError *error = NULL;
> + gchar *iso8601 = NULL;
> + MMNetworkTimezone *tz = NULL;
> + gboolean ret;
> +
> + ret = mm_parse_cclk_response (cclk_tests[i].str,
> + cclk_tests[i].test_iso8601 ?
> &iso8601 : NULL,
> + cclk_tests[i].test_tz ? &tz : NULL,
> + &error);
> +
> + g_assert (ret == cclk_tests[i].ret);
> + g_assert (ret == (error ? FALSE : TRUE));
> +
> + g_clear_error (&error);
> +
> + if (cclk_tests[i].test_iso8601)
> + g_assert_cmpstr (cclk_tests[i].iso8601, ==, iso8601);
> +
> + if (cclk_tests[i].test_tz) {
> + g_assert (mm_network_timezone_get_offset (tz) ==
> cclk_tests[i].offset);
> + g_assert (mm_network_timezone_get_dst_offset (tz) ==
> MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN);
> + g_assert (mm_network_timezone_get_leap_seconds (tz) ==
> MM_NETWORK_TIMEZONE_LEAP_SECONDS_UNKNOWN);
> + }
> +
> + if (iso8601)
> + g_free (iso8601);
> +
> + if (tz)
> + g_object_unref (tz);
> + }
> +}
> +
> +/*****************************************************************************/
>
> void
> _mm_log (const char *loc,
> @@ -2501,6 +2572,8 @@ int main (int argc, char **argv)
>
> g_test_suite_add (suite, TESTCASE (test_supported_capability_filter,
> NULL));
>
> + g_test_suite_add (suite, TESTCASE (test_cclk_response, NULL));
> +
> result = g_test_run ();
>
> reg_test_data_free (reg_data);
> _______________________________________________
> ModemManager-devel mailing list
> ModemManager-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
More information about the ModemManager-devel
mailing list