From a339546c4547e0950d8dc8aa1d22aafc8969fac9 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 5 Mar 2012 18:11:18 +0100 Subject: iface-modem-time: setup generic unsolicited message handling Modems may get notified via unsolicited messages (either AT or QMI or some other thing), that the network time was updated. This setup allows subclasses implementing the Time interface to setup/cleanup and enable/disable the unsolicited messages, as well as notify about the network time updates. --- src/mm-iface-modem-time.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++ src/mm-iface-modem-time.h | 37 ++++++++++++ 2 files changed, 186 insertions(+) (limited to 'src') diff --git a/src/mm-iface-modem-time.c b/src/mm-iface-modem-time.c index e4578669..2502ceca 100644 --- a/src/mm-iface-modem-time.c +++ b/src/mm-iface-modem-time.c @@ -364,12 +364,32 @@ update_network_timezone (MMIfaceModemTime *self, /*****************************************************************************/ +void +mm_iface_modem_time_update_network_time (MMIfaceModemTime *self, + const gchar *network_time) +{ + MmGdbusModemTime *skeleton; + + g_object_get (self, + MM_IFACE_MODEM_TIME_DBUS_SKELETON, &skeleton, + NULL); + + /* Notify about the updated network time */ + mm_gdbus_modem_time_emit_network_time_changed (skeleton, network_time); + + g_object_unref (skeleton); +} + +/*****************************************************************************/ + typedef struct _DisablingContext DisablingContext; static void interface_disabling_step (DisablingContext *ctx); typedef enum { DISABLING_STEP_FIRST, DISABLING_STEP_CANCEL_NETWORK_TIMEZONE_UPDATE, + DISABLING_STEP_DISABLE_UNSOLICITED_EVENTS, + DISABLING_STEP_CLEANUP_UNSOLICITED_EVENTS, DISABLING_STEP_LAST } DisablingStep; @@ -423,6 +443,44 @@ mm_iface_modem_time_disable_finish (MMIfaceModemTime *self, return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } +static void +disable_unsolicited_events_ready (MMIfaceModemTime *self, + GAsyncResult *res, + DisablingContext *ctx) +{ + GError *error = NULL; + + MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->disable_unsolicited_events_finish (self, res, &error); + if (error) { + g_simple_async_result_take_error (ctx->result, error); + disabling_context_complete_and_free (ctx); + return; + } + + /* Go on to next step */ + ctx->step++; + interface_disabling_step (ctx); +} + +static void +cleanup_unsolicited_events_ready (MMIfaceModemTime *self, + GAsyncResult *res, + DisablingContext *ctx) +{ + GError *error = NULL; + + MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->cleanup_unsolicited_events_finish (self, res, &error); + if (error) { + g_simple_async_result_take_error (ctx->result, error); + disabling_context_complete_and_free (ctx); + return; + } + + /* Go on to next step */ + ctx->step++; + interface_disabling_step (ctx); +} + static void interface_disabling_step (DisablingContext *ctx) { @@ -451,6 +509,32 @@ interface_disabling_step (DisablingContext *ctx) ctx->step++; } + case DISABLING_STEP_DISABLE_UNSOLICITED_EVENTS: + /* Allow cleaning up unsolicited events */ + if (MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->disable_unsolicited_events && + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->disable_unsolicited_events_finish) { + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->disable_unsolicited_events ( + ctx->self, + (GAsyncReadyCallback)disable_unsolicited_events_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + + case DISABLING_STEP_CLEANUP_UNSOLICITED_EVENTS: + /* Allow cleaning up unsolicited events */ + if (MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events && + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events_finish) { + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events ( + ctx->self, + (GAsyncReadyCallback)cleanup_unsolicited_events_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + case DISABLING_STEP_LAST: /* We are done without errors! */ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); @@ -479,6 +563,8 @@ static void interface_enabling_step (EnablingContext *ctx); typedef enum { ENABLING_STEP_FIRST, ENABLING_STEP_SETUP_NETWORK_TIMEZONE_RETRIEVAL, + ENABLING_STEP_SETUP_UNSOLICITED_EVENTS, + ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS, ENABLING_STEP_LAST } EnablingStep; @@ -552,6 +638,43 @@ update_network_timezone_ready (MMIfaceModemTime *self, NULL); } +static void +setup_unsolicited_events_ready (MMIfaceModemTime *self, + GAsyncResult *res, + EnablingContext *ctx) +{ + GError *error = NULL; + + MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->setup_unsolicited_events_finish (self, res, &error); + if (error) { + g_simple_async_result_take_error (ctx->result, error); + enabling_context_complete_and_free (ctx); + return; + } + + /* Go on to next step */ + ctx->step++; + interface_enabling_step (ctx); +} + +static void +enable_unsolicited_events_ready (MMIfaceModemTime *self, + GAsyncResult *res, + EnablingContext *ctx) +{ + GError *error = NULL; + + /* Not critical! */ + if (!MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error)) { + mm_dbg ("Couldn't enable unsolicited events: '%s'", error->message); + g_error_free (error); + } + + /* Go on with next step */ + ctx->step++; + interface_enabling_step (ctx); +} + static void interface_enabling_step (EnablingContext *ctx) { @@ -586,6 +709,32 @@ interface_enabling_step (EnablingContext *ctx) ctx->step++; } + case ENABLING_STEP_SETUP_UNSOLICITED_EVENTS: + /* Allow setting up unsolicited events */ + if (MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->setup_unsolicited_events && + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->setup_unsolicited_events_finish) { + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->setup_unsolicited_events ( + ctx->self, + (GAsyncReadyCallback)setup_unsolicited_events_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + + case ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS: + /* Allow setting up unsolicited events */ + if (MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->enable_unsolicited_events && + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->enable_unsolicited_events_finish) { + MM_IFACE_MODEM_TIME_GET_INTERFACE (ctx->self)->enable_unsolicited_events ( + ctx->self, + (GAsyncReadyCallback)enable_unsolicited_events_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + case ENABLING_STEP_LAST: /* We are done without errors! */ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); diff --git a/src/mm-iface-modem-time.h b/src/mm-iface-modem-time.h index 5e312ef7..1d517fdc 100644 --- a/src/mm-iface-modem-time.h +++ b/src/mm-iface-modem-time.h @@ -56,6 +56,38 @@ struct _MMIfaceModemTime { MMNetworkTimezone * (* load_network_timezone_finish) (MMIfaceModemTime *self, GAsyncResult *res, GError **error); + + /* Asynchronous setting up unsolicited events */ + void (*setup_unsolicited_events) (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*setup_unsolicited_events_finish) (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error); + + /* Asynchronous cleaning up of unsolicited events */ + void (*cleanup_unsolicited_events) (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*cleanup_unsolicited_events_finish) (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error); + + /* Asynchronous enabling unsolicited events */ + void (* enable_unsolicited_events) (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* enable_unsolicited_events_finish) (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error); + + /* Asynchronous disabling unsolicited events */ + void (* disable_unsolicited_events) (MMIfaceModemTime *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* disable_unsolicited_events_finish) (MMIfaceModemTime *self, + GAsyncResult *res, + GError **error); }; GType mm_iface_modem_time_get_type (void); @@ -91,4 +123,9 @@ void mm_iface_modem_time_shutdown (MMIfaceModemTime *self); void mm_iface_modem_time_bind_simple_status (MMIfaceModemTime *self, MMSimpleStatus *status); +/* Implementations of the unsolicited events handling should call this method + * to notify about the updated time */ +void mm_iface_modem_time_update_network_time (MMIfaceModemTime *self, + const gchar *network_time); + #endif /* MM_IFACE_MODEM_TIME_H */ -- cgit v1.2.3-70-g09d2