diff options
-rw-r--r-- | plugins/cinterion/mm-broadband-modem-cinterion.c | 21 | ||||
-rw-r--r-- | plugins/cinterion/mm-broadband-modem-qmi-cinterion.c | 23 | ||||
-rw-r--r-- | plugins/cinterion/mm-shared-cinterion.c | 195 | ||||
-rw-r--r-- | plugins/cinterion/mm-shared-cinterion.h | 26 |
4 files changed, 262 insertions, 3 deletions
diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c index ef799ebc..a99db326 100644 --- a/plugins/cinterion/mm-broadband-modem-cinterion.c +++ b/plugins/cinterion/mm-broadband-modem-cinterion.c @@ -46,12 +46,14 @@ static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); static void iface_modem_messaging_init (MMIfaceModemMessaging *iface); static void iface_modem_location_init (MMIfaceModemLocation *iface); static void iface_modem_voice_init (MMIfaceModemVoice *iface); +static void iface_modem_time_init (MMIfaceModemTime *iface); static void shared_cinterion_init (MMSharedCinterion *iface); static MMIfaceModem *iface_modem_parent; static MMIfaceModem3gpp *iface_modem_3gpp_parent; static MMIfaceModemLocation *iface_modem_location_parent; static MMIfaceModemVoice *iface_modem_voice_parent; +static MMIfaceModemTime *iface_modem_time_parent; G_DEFINE_TYPE_EXTENDED (MMBroadbandModemCinterion, mm_broadband_modem_cinterion, MM_TYPE_BROADBAND_MODEM, 0, G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) @@ -59,6 +61,7 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemCinterion, mm_broadband_modem_cinterion, G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init) + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init) G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_CINTERION, shared_cinterion_init)) typedef enum { @@ -1986,10 +1989,28 @@ peek_parent_voice_interface (MMSharedCinterion *self) } static void +iface_modem_time_init (MMIfaceModemTime *iface) +{ + iface_modem_time_parent = g_type_interface_peek_parent (iface); + + iface->setup_unsolicited_events = mm_shared_cinterion_time_setup_unsolicited_events; + iface->setup_unsolicited_events_finish = mm_shared_cinterion_time_setup_unsolicited_events_finish; + iface->cleanup_unsolicited_events = mm_shared_cinterion_time_cleanup_unsolicited_events; + iface->cleanup_unsolicited_events_finish = mm_shared_cinterion_time_cleanup_unsolicited_events_finish; +} + +static MMIfaceModemTime * +peek_parent_time_interface (MMSharedCinterion *self) +{ + return iface_modem_time_parent; +} + +static void shared_cinterion_init (MMSharedCinterion *iface) { iface->peek_parent_location_interface = peek_parent_location_interface; iface->peek_parent_voice_interface = peek_parent_voice_interface; + iface->peek_parent_time_interface = peek_parent_time_interface; } static void diff --git a/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c b/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c index de2eff7f..c14fb23c 100644 --- a/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c +++ b/plugins/cinterion/mm-broadband-modem-qmi-cinterion.c @@ -31,15 +31,18 @@ #include "mm-shared-cinterion.h" static void iface_modem_location_init (MMIfaceModemLocation *iface); -static void iface_modem_voice_init (MMIfaceModemVoice *iface); +static void iface_modem_voice_init (MMIfaceModemVoice *iface); +static void iface_modem_time_init (MMIfaceModemTime *iface); static void shared_cinterion_init (MMSharedCinterion *iface); static MMIfaceModemLocation *iface_modem_location_parent; static MMIfaceModemVoice *iface_modem_voice_parent; +static MMIfaceModemTime *iface_modem_time_parent; G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmiCinterion, mm_broadband_modem_qmi_cinterion, MM_TYPE_BROADBAND_MODEM_QMI, 0, G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init) + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init) G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_CINTERION, shared_cinterion_init)) /*****************************************************************************/ @@ -110,10 +113,28 @@ peek_parent_voice_interface (MMSharedCinterion *self) } static void +iface_modem_time_init (MMIfaceModemTime *iface) +{ + iface_modem_time_parent = g_type_interface_peek_parent (iface); + + iface->setup_unsolicited_events = mm_shared_cinterion_time_setup_unsolicited_events; + iface->setup_unsolicited_events_finish = mm_shared_cinterion_time_setup_unsolicited_events_finish; + iface->cleanup_unsolicited_events = mm_shared_cinterion_time_cleanup_unsolicited_events; + iface->cleanup_unsolicited_events_finish = mm_shared_cinterion_time_cleanup_unsolicited_events_finish; +} + +static MMIfaceModemTime * +peek_parent_time_interface (MMSharedCinterion *self) +{ + return iface_modem_time_parent; +} + +static void shared_cinterion_init (MMSharedCinterion *iface) { iface->peek_parent_location_interface = peek_parent_location_interface; iface->peek_parent_voice_interface = peek_parent_voice_interface; + iface->peek_parent_time_interface = peek_parent_time_interface; } static void diff --git a/plugins/cinterion/mm-shared-cinterion.c b/plugins/cinterion/mm-shared-cinterion.c index d736903c..3bc15e94 100644 --- a/plugins/cinterion/mm-shared-cinterion.c +++ b/plugins/cinterion/mm-shared-cinterion.c @@ -53,11 +53,15 @@ typedef struct { MMIfaceModemVoice *iface_modem_voice_parent; FeatureSupport slcc_support; GRegex *slcc_regex; + /* time */ + MMIfaceModemTime *iface_modem_time_parent; + GRegex *ctzu_regex; } Private; static void private_free (Private *ctx) { + g_regex_unref (ctx->ctzu_regex); g_regex_unref (ctx->slcc_regex); g_slice_free (Private, ctx); } @@ -80,8 +84,9 @@ get_private (MMSharedCinterion *self) priv->sgpsc_support = FEATURE_SUPPORT_UNKNOWN; priv->slcc_support = FEATURE_SUPPORT_UNKNOWN; priv->slcc_regex = mm_cinterion_get_slcc_regex (); + priv->ctzu_regex = mm_cinterion_get_ctzu_regex (); - /* Setup parent class' MMIfaceModemLocation and MMIfaceModemVoice */ + /* Setup parent class' MMIfaceModemLocation, MMIfaceModemVoice and MMIfaceModemTime */ g_assert (MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_location_interface); priv->iface_modem_location_parent = MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_location_interface (self); @@ -89,6 +94,9 @@ get_private (MMSharedCinterion *self) g_assert (MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_voice_interface); priv->iface_modem_voice_parent = MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_voice_interface (self); + g_assert (MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_time_interface); + priv->iface_modem_time_parent = MM_SHARED_CINTERION_GET_INTERFACE (self)->peek_parent_time_interface (self); + g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free); } @@ -1334,6 +1342,191 @@ mm_shared_cinterion_voice_check_support (MMIfaceModemVoice *self, } /*****************************************************************************/ +/* Common setup/cleanup time unsolicited events */ + +static void +ctzu_received (MMPortSerialAt *port, + GMatchInfo *match_info, + MMSharedCinterion *self) +{ + gchar *iso8601 = NULL; + MMNetworkTimezone *tz = NULL; + GError *error = NULL; + + if (!mm_cinterion_parse_ctzu_urc (match_info, &iso8601, &tz, &error)) { + mm_dbg ("Couldn't process +CTZU URC: %s", error->message); + g_error_free (error); + return; + } + + g_assert (iso8601); + mm_dbg ("+CTZU URC received: %s", iso8601); + mm_iface_modem_time_update_network_time (MM_IFACE_MODEM_TIME (self), iso8601); + g_free (iso8601); + + g_assert (tz); + mm_iface_modem_time_update_network_timezone (MM_IFACE_MODEM_TIME (self), tz); + g_object_unref (tz); +} + +static void +common_time_setup_cleanup_unsolicited_events (MMSharedCinterion *self, + gboolean enable) +{ + Private *priv; + MMPortSerialAt *ports[2]; + guint i; + + priv = get_private (MM_SHARED_CINTERION (self)); + + ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); + ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); + + mm_dbg ("%s up time unsolicited events...", + enable ? "Setting" : "Cleaning"); + + for (i = 0; i < G_N_ELEMENTS (ports); i++) { + if (!ports[i]) + continue; + + mm_port_serial_at_add_unsolicited_msg_handler (ports[i], + priv->ctzu_regex, + enable ? (MMPortSerialAtUnsolicitedMsgFn)ctzu_received : NULL, + enable ? self : NULL, + NULL); + } +} + +/*****************************************************************************/ +/* Cleanup unsolicited events (Time interface) */ + +gboolean +mm_shared_cinterion_time_cleanup_unsolicited_events_finish (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +parent_time_cleanup_unsolicited_events_ready (MMIfaceModemTime *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + Private *priv; + + priv = get_private (MM_SHARED_CINTERION (self)); + + if (!priv->iface_modem_time_parent->cleanup_unsolicited_events_finish (self, res, &error)) { + mm_warn ("Couldn't cleanup parent time unsolicited events: %s", error->message); + g_error_free (error); + } + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +void +mm_shared_cinterion_time_cleanup_unsolicited_events (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + Private *priv; + GTask *task; + + task = g_task_new (self, NULL, callback, user_data); + + priv = get_private (MM_SHARED_CINTERION (self)); + g_assert (priv->iface_modem_time_parent); + + /* our own cleanup first */ + common_time_setup_cleanup_unsolicited_events (MM_SHARED_CINTERION (self), FALSE); + + if (priv->iface_modem_time_parent->cleanup_unsolicited_events && + priv->iface_modem_time_parent->cleanup_unsolicited_events_finish) { + /* Chain up parent's cleanup */ + priv->iface_modem_time_parent->cleanup_unsolicited_events ( + self, + (GAsyncReadyCallback)parent_time_cleanup_unsolicited_events_ready, + task); + return; + } + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +/*****************************************************************************/ +/* Setup unsolicited events (Time interface) */ + +gboolean +mm_shared_cinterion_time_setup_unsolicited_events_finish (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +own_time_setup_unsolicited_events (GTask *task) +{ + MMSharedCinterion *self; + + self = g_task_get_source_object (task); + + /* our own setup next */ + common_time_setup_cleanup_unsolicited_events (MM_SHARED_CINTERION (self), TRUE); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +parent_time_setup_unsolicited_events_ready (MMIfaceModemTime *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + Private *priv; + + priv = get_private (MM_SHARED_CINTERION (self)); + + if (!priv->iface_modem_time_parent->cleanup_unsolicited_events_finish (self, res, &error)) { + mm_warn ("Couldn't cleanup parent time unsolicited events: %s", error->message); + g_error_free (error); + } + + own_time_setup_unsolicited_events (task); +} + +void +mm_shared_cinterion_time_setup_unsolicited_events (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + Private *priv; + GTask *task; + + task = g_task_new (self, NULL, callback, user_data); + + priv = get_private (MM_SHARED_CINTERION (self)); + g_assert (priv->iface_modem_time_parent); + + if (priv->iface_modem_time_parent->setup_unsolicited_events && + priv->iface_modem_time_parent->setup_unsolicited_events_finish) { + /* chain up parent's setup first */ + priv->iface_modem_time_parent->setup_unsolicited_events ( + self, + (GAsyncReadyCallback)parent_time_setup_unsolicited_events_ready, + task); + return; + } + + own_time_setup_unsolicited_events (task); +} + +/*****************************************************************************/ static void shared_cinterion_init (gpointer g_iface) diff --git a/plugins/cinterion/mm-shared-cinterion.h b/plugins/cinterion/mm-shared-cinterion.h index 52c154f3..c849b826 100644 --- a/plugins/cinterion/mm-shared-cinterion.h +++ b/plugins/cinterion/mm-shared-cinterion.h @@ -27,6 +27,7 @@ #include "mm-iface-modem.h" #include "mm-iface-modem-location.h" #include "mm-iface-modem-voice.h" +#include "mm-iface-modem-time.h" #define MM_TYPE_SHARED_CINTERION (mm_shared_cinterion_get_type ()) #define MM_SHARED_CINTERION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SHARED_CINTERION, MMSharedCinterion)) @@ -43,10 +44,16 @@ struct _MMSharedCinterion { /* Peek voice interface of the parent class of the object */ MMIfaceModemVoice * (* peek_parent_voice_interface) (MMSharedCinterion *self); + + /* Peek time interface of the parent class of the object */ + MMIfaceModemTime * (* peek_parent_time_interface) (MMSharedCinterion *self); }; GType mm_shared_cinterion_get_type (void); +/*****************************************************************************/ +/* Location interface */ + void mm_shared_cinterion_location_load_capabilities (MMIfaceModemLocation *self, GAsyncReadyCallback callback, gpointer user_data); @@ -71,7 +78,7 @@ gboolean mm_shared_cinterion_disable_location_gathering_finish (MMI GError **error); /*****************************************************************************/ -/* Create call (Voice interface) */ +/* Voice interface */ MMBaseCall *mm_shared_cinterion_create_call (MMIfaceModemVoice *self, MMCallDirection direction, @@ -112,4 +119,21 @@ gboolean mm_shared_cinterion_voice_disable_unsolicited_events_finish (MMIfaceMod GAsyncResult *res, GError **error); +/*****************************************************************************/ +/* Time interface */ + +void mm_shared_cinterion_time_setup_unsolicited_events (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_shared_cinterion_time_setup_unsolicited_events_finish (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error); + +void mm_shared_cinterion_time_cleanup_unsolicited_events (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_shared_cinterion_time_cleanup_unsolicited_events_finish (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error); + #endif /* MM_SHARED_CINTERION_H */ |