diff options
-rw-r--r-- | plugins/cinterion/mm-modem-helpers-cinterion.c | 70 | ||||
-rw-r--r-- | plugins/cinterion/mm-modem-helpers-cinterion.h | 11 | ||||
-rw-r--r-- | plugins/cinterion/tests/test-modem-helpers-cinterion.c | 65 |
3 files changed, 146 insertions, 0 deletions
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c index 7d583c81..b45b9af0 100644 --- a/plugins/cinterion/mm-modem-helpers-cinterion.c +++ b/plugins/cinterion/mm-modem-helpers-cinterion.c @@ -795,3 +795,73 @@ mm_cinterion_call_info_list_free (GList *call_info_list) { g_list_free_full (call_info_list, (GDestroyNotify) cinterion_call_info_free); } + +/*****************************************************************************/ +/* +CTZU URC helpers */ + +GRegex * +mm_cinterion_get_ctzu_regex (void) +{ + /* + * From PLS-8 AT command spec: + * +CTZU:<nitzUT>, <nitzTZ>[, <nitzDST>] + * E.g.: + * +CTZU: "19/07/09,10:19:15",+08,1 + */ + + return g_regex_new ("\\r\\n\\+CTZU:\\s*\"(\\d+)\\/(\\d+)\\/(\\d+),(\\d+):(\\d+):(\\d+)\",([\\-\\+\\d]+)(?:,(\\d+))?(?:\\r\\n)?", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +} + +gboolean +mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info, + gchar **iso8601p, + MMNetworkTimezone **tzp, + GError **error) +{ + guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, dst = 0; + gint tz = 0; + + 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)) { + g_set_error_literal (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse +CTZU URC"); + return FALSE; + } + + /* adjust year */ + if (year < 100) + 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); + } + + /* dst flag is optional in the URC + * + * tz = timezone offset in 15 minute intervals + * dst = daylight adjustment, 0 = none, 1 = 1 hour, 2 = 2 hours + */ + if (tzp && mm_get_uint_from_match_info (match_info, 8, &dst)) + mm_network_timezone_set_dst_offset (*tzp, dst * 60); + + return TRUE; +} diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.h b/plugins/cinterion/mm-modem-helpers-cinterion.h index 43a39d18..6b972048 100644 --- a/plugins/cinterion/mm-modem-helpers-cinterion.h +++ b/plugins/cinterion/mm-modem-helpers-cinterion.h @@ -22,6 +22,8 @@ #include <ModemManager.h> #include <mm-base-bearer.h> +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> /*****************************************************************************/ /* ^SCFG test parser */ @@ -98,4 +100,13 @@ gboolean mm_cinterion_parse_slcc_list (const gchar *str, GError **error); void mm_cinterion_call_info_list_free (GList *call_info_list); +/*****************************************************************************/ +/* +CTZU URC helpers */ + +GRegex *mm_cinterion_get_ctzu_regex (void); +gboolean mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info, + gchar **iso8601p, + MMNetworkTimezone **tzp, + GError **error); + #endif /* MM_MODEM_HELPERS_CINTERION_H */ diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c index fd05019e..9b12f199 100644 --- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c +++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c @@ -793,6 +793,69 @@ test_slcc_urc_complex (void) } /*****************************************************************************/ +/* Test +CTZU URCs */ + +static void +common_test_ctzu_urc (const gchar *urc, + const gchar *expected_iso8601, + gint expected_offset, + gint expected_dst_offset) +{ + GError *error = NULL; + GRegex *ctzu_regex = NULL; + gboolean result; + GMatchInfo *match_info = NULL; + gchar *iso8601; + MMNetworkTimezone *tz = NULL; + + ctzu_regex = mm_cinterion_get_ctzu_regex (); + + /* Same matching logic as done in MMSerialPortAt when processing URCs! */ + result = g_regex_match_full (ctzu_regex, urc, -1, 0, 0, &match_info, &error); + g_assert_no_error (error); + g_assert (result); + + result = mm_cinterion_parse_ctzu_urc (match_info, &iso8601, &tz, &error); + g_assert_no_error (error); + g_assert (result); + + g_assert (iso8601); + g_assert_cmpstr (expected_iso8601, ==, iso8601); + g_free (iso8601); + + g_assert (tz); + g_assert_cmpint (expected_offset, ==, mm_network_timezone_get_offset (tz)); + + if (expected_dst_offset >= 0) + g_assert_cmpuint ((guint)expected_dst_offset, ==, mm_network_timezone_get_dst_offset (tz)); + + g_object_unref (tz); + g_regex_unref (ctzu_regex); +} + +static void +test_ctzu_urc_simple (void) +{ + const gchar *urc = "\r\n+CTZU: \"19/07/09,11:15:40\",+08\r\n"; + const gchar *expected_iso8601 = "2019-07-09T11:15:40+02:00"; + gint expected_offset = 120; + gint expected_dst_offset = -1; /* not given */ + + common_test_ctzu_urc (urc, expected_iso8601, expected_offset, expected_dst_offset); +} + +static void +test_ctzu_urc_full (void) +{ + const gchar *urc = "\r\n+CTZU: \"19/07/09,11:15:40\",+08,1\r\n"; + const gchar *expected_iso8601 = "2019-07-09T11:15:40+02:00"; + gint expected_offset = 120; + gint expected_dst_offset = 60; + + common_test_ctzu_urc (urc, expected_iso8601, expected_offset, expected_dst_offset); +} + +/*****************************************************************************/ void _mm_log (const char *loc, @@ -835,6 +898,8 @@ int main (int argc, char **argv) g_test_add_func ("/MM/cinterion/slcc/urc/single", test_slcc_urc_single); g_test_add_func ("/MM/cinterion/slcc/urc/multiple", test_slcc_urc_multiple); g_test_add_func ("/MM/cinterion/slcc/urc/complex", test_slcc_urc_complex); + g_test_add_func ("/MM/cinterion/ctzu/urc/simple", test_ctzu_urc_simple); + g_test_add_func ("/MM/cinterion/ctzu/urc/full", test_ctzu_urc_full); return g_test_run (); } |