cinterion: new +CTZU URC parser

This commit is contained in:
Aleksander Morgado
2019-07-11 23:21:00 +02:00
parent b9a3290871
commit fe11a3fa1f
3 changed files with 146 additions and 0 deletions
@@ -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;
}
@@ -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 */
@@ -792,6 +792,69 @@ test_slcc_urc_complex (void)
common_test_slcc_urc (urc, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list));
}
/*****************************************************************************/
/* 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
@@ -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 ();
}