diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-iface-modem-signal.c | 403 |
1 files changed, 202 insertions, 201 deletions
diff --git a/src/mm-iface-modem-signal.c b/src/mm-iface-modem-signal.c index a2339f6b..d793bba3 100644 --- a/src/mm-iface-modem-signal.c +++ b/src/mm-iface-modem-signal.c @@ -24,11 +24,49 @@ #define SUPPORT_CHECKED_TAG "signal-support-checked-tag" #define SUPPORTED_TAG "signal-supported-tag" -#define REFRESH_CONTEXT_TAG "signal-refresh-context-tag" static GQuark support_checked_quark; static GQuark supported_quark; -static GQuark refresh_context_quark; + +/*****************************************************************************/ +/* Private data context */ + +#define PRIVATE_TAG "signal-private-tag" +static GQuark private_quark; + +typedef struct { + /* polling-based reporting enabled */ + guint rate; + guint timeout_source; + /* threshold-based reporting enabled */ + guint rssi_threshold; + gboolean error_rate_threshold; +} Private; + +static void +private_free (Private *priv) +{ + if (priv->timeout_source) + g_source_remove (priv->timeout_source); + g_slice_free (Private, priv); +} + +static Private * +get_private (MMIfaceModemSignal *self) +{ + Private *priv; + + if (G_UNLIKELY (!private_quark)) + private_quark = g_quark_from_static_string (PRIVATE_TAG); + + priv = g_object_get_qdata (G_OBJECT (self), private_quark); + if (!priv) { + priv = g_slice_new0 (Private); + g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free); + } + + return priv; +} /*****************************************************************************/ @@ -40,21 +78,21 @@ mm_iface_modem_signal_bind_simple_status (MMIfaceModemSignal *self, /*****************************************************************************/ -void -mm_iface_modem_signal_update (MMIfaceModemSignal *self, - MMSignal *cdma, - MMSignal *evdo, - MMSignal *gsm, - MMSignal *umts, - MMSignal *lte, - MMSignal *nr5g) +static void +internal_signal_update (MMIfaceModemSignal *self, + MMSignal *cdma, + MMSignal *evdo, + MMSignal *gsm, + MMSignal *umts, + MMSignal *lte, + MMSignal *nr5g) { - g_autoptr(GVariant) dict_cdma = NULL; - g_autoptr(GVariant) dict_evdo = NULL; - g_autoptr(GVariant) dict_gsm = NULL; - g_autoptr(GVariant) dict_umts = NULL; - g_autoptr(GVariant) dict_lte = NULL; - g_autoptr(GVariant) dict_nr5g = NULL; + g_autoptr(GVariant) dict_cdma = NULL; + g_autoptr(GVariant) dict_evdo = NULL; + g_autoptr(GVariant) dict_gsm = NULL; + g_autoptr(GVariant) dict_umts = NULL; + g_autoptr(GVariant) dict_lte = NULL; + g_autoptr(GVariant) dict_nr5g = NULL; g_autoptr(MmGdbusModemSignalSkeleton) skeleton = NULL; g_object_get (self, @@ -65,68 +103,83 @@ mm_iface_modem_signal_update (MMIfaceModemSignal *self, return; } - if (cdma) + if (cdma) { + mm_obj_dbg (self, "cdma extended signal information updated"); dict_cdma = mm_signal_get_dictionary (cdma); + } mm_gdbus_modem_signal_set_cdma (MM_GDBUS_MODEM_SIGNAL (skeleton), dict_cdma); - if (evdo) + if (evdo) { + mm_obj_dbg (self, "evdo extended signal information updated"); dict_evdo = mm_signal_get_dictionary (evdo); + } mm_gdbus_modem_signal_set_evdo (MM_GDBUS_MODEM_SIGNAL (skeleton), dict_evdo); - if (gsm) + if (gsm) { + mm_obj_dbg (self, "gsm extended signal information updated"); dict_gsm = mm_signal_get_dictionary (gsm); + } mm_gdbus_modem_signal_set_gsm (MM_GDBUS_MODEM_SIGNAL (skeleton), dict_gsm); - if (umts) + if (umts) { + mm_obj_dbg (self, "umts extended signal information updated"); dict_umts = mm_signal_get_dictionary (umts); + } mm_gdbus_modem_signal_set_umts (MM_GDBUS_MODEM_SIGNAL (skeleton), dict_umts); - if (lte) + if (lte) { + mm_obj_dbg (self, "lte extended signal information updated"); dict_lte = mm_signal_get_dictionary (lte); + } mm_gdbus_modem_signal_set_lte (MM_GDBUS_MODEM_SIGNAL (skeleton), dict_lte); - if (nr5g) + if (nr5g) { + mm_obj_dbg (self, "5gnr extended signal information updated"); dict_nr5g = mm_signal_get_dictionary (nr5g); + } mm_gdbus_modem_signal_set_nr5g (MM_GDBUS_MODEM_SIGNAL (skeleton), dict_nr5g); /* Flush right away */ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (skeleton)); } -/*****************************************************************************/ +void +mm_iface_modem_signal_update (MMIfaceModemSignal *self, + MMSignal *cdma, + MMSignal *evdo, + MMSignal *gsm, + MMSignal *umts, + MMSignal *lte, + MMSignal *nr5g) +{ + Private *priv; -typedef struct { - guint rate; - guint timeout_source; -} RefreshContext; + priv = get_private (self); + if (!priv->rate && !priv->rssi_threshold && !priv->error_rate_threshold) { + mm_obj_dbg (self, "skipping extended signal information update..."); + return; + } -static void -refresh_context_free (RefreshContext *ctx) -{ - if (ctx->timeout_source) - g_source_remove (ctx->timeout_source); - g_slice_free (RefreshContext, ctx); + internal_signal_update (self, cdma, evdo, gsm, umts, lte, nr5g); } +/*****************************************************************************/ + static void -clear_values (MMIfaceModemSignal *self) +check_interface_reset (MMIfaceModemSignal *self) { - g_autoptr(MmGdbusModemSignalSkeleton) skeleton = NULL; + Private *priv; - g_object_get (self, - MM_IFACE_MODEM_SIGNAL_DBUS_SKELETON, &skeleton, - NULL); - if (!skeleton) - return; + priv = get_private (self); - mm_gdbus_modem_signal_set_cdma (MM_GDBUS_MODEM_SIGNAL (skeleton), NULL); - mm_gdbus_modem_signal_set_evdo (MM_GDBUS_MODEM_SIGNAL (skeleton), NULL); - mm_gdbus_modem_signal_set_gsm (MM_GDBUS_MODEM_SIGNAL (skeleton), NULL); - mm_gdbus_modem_signal_set_umts (MM_GDBUS_MODEM_SIGNAL (skeleton), NULL); - mm_gdbus_modem_signal_set_lte (MM_GDBUS_MODEM_SIGNAL (skeleton), NULL); - mm_gdbus_modem_signal_set_nr5g (MM_GDBUS_MODEM_SIGNAL (skeleton), NULL); + if (!priv->rate && !priv->rssi_threshold && !priv->error_rate_threshold) { + mm_obj_dbg (self, "reseting extended signal information..."); + mm_iface_modem_signal_update (self, NULL, NULL, NULL, NULL, NULL, NULL); + } } +/*****************************************************************************/ + static void load_values_ready (MMIfaceModemSignal *self, GAsyncResult *res) @@ -149,8 +202,7 @@ load_values_ready (MMIfaceModemSignal *self, <e, &nr5g, &error)) { - mm_obj_warn (self, "couldn't load extended signal information: %s", error->message); - clear_values (self); + mm_obj_warn (self, "couldn't reload extended signal information: %s", error->message); return; } @@ -158,7 +210,7 @@ load_values_ready (MMIfaceModemSignal *self, } static gboolean -refresh_context_cb (MMIfaceModemSignal *self) +polling_context_cb (MMIfaceModemSignal *self) { MM_IFACE_MODEM_SIGNAL_GET_INTERFACE (self)->load_values ( self, @@ -168,88 +220,50 @@ refresh_context_cb (MMIfaceModemSignal *self) return G_SOURCE_CONTINUE; } -static void -teardown_refresh_context (MMIfaceModemSignal *self) -{ - clear_values (self); - if (G_UNLIKELY (!refresh_context_quark)) - refresh_context_quark = g_quark_from_static_string (REFRESH_CONTEXT_TAG); - if (g_object_get_qdata (G_OBJECT (self), refresh_context_quark)) { - mm_obj_dbg (self, "extended signal information reporting disabled"); - g_object_set_qdata (G_OBJECT (self), refresh_context_quark, NULL); - } -} - static gboolean -setup_refresh_context (MMIfaceModemSignal *self, - gboolean update_rate, - guint new_rate, - GError **error) +polling_restart (MMIfaceModemSignal *self, + guint rate, + GError **error) { - MmGdbusModemSignal *skeleton; - RefreshContext *ctx; - MMModemState modem_state; - - if (G_UNLIKELY (!refresh_context_quark)) - refresh_context_quark = g_quark_from_static_string (REFRESH_CONTEXT_TAG); - - g_object_get (self, - MM_IFACE_MODEM_SIGNAL_DBUS_SKELETON, &skeleton, - MM_IFACE_MODEM_STATE, &modem_state, - NULL); - if (!skeleton) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't get interface skeleton"); - return FALSE; - } + Private *priv; - if (update_rate) - mm_gdbus_modem_signal_set_rate (skeleton, new_rate); - else - new_rate = mm_gdbus_modem_signal_get_rate (skeleton); - g_object_unref (skeleton); - - /* User disabling? */ - if (new_rate == 0) { - mm_obj_dbg (self, "extended signal information reporting disabled (rate: 0 seconds)"); - clear_values (self); - g_object_set_qdata (G_OBJECT (self), refresh_context_quark, NULL); - return TRUE; - } + priv = get_private (self); - if (modem_state < MM_MODEM_STATE_ENABLING) { - mm_obj_dbg (self, "extended signal information reporting disabled (modem not yet enabled)"); - return TRUE; - } + /* Update the rate in the interface if it changed */ + if (priv->rate != rate) { + g_autoptr(MmGdbusModemSignalSkeleton) skeleton = NULL; - /* Setup refresh context */ - ctx = g_object_get_qdata (G_OBJECT (self), refresh_context_quark); - if (!ctx) { - ctx = g_slice_new0 (RefreshContext); - g_object_set_qdata_full (G_OBJECT (self), - refresh_context_quark, - ctx, - (GDestroyNotify)refresh_context_free); + g_object_get (self, + MM_IFACE_MODEM_SIGNAL_DBUS_SKELETON, &skeleton, + NULL); + if (!skeleton) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't get interface skeleton"); + return FALSE; + } + mm_gdbus_modem_signal_set_rate (MM_GDBUS_MODEM_SIGNAL (skeleton), rate); + priv->rate = rate; } - /* We're enabling, compare to old rate */ - if (ctx->rate == new_rate) { - /* Already there */ + /* Polling disabled by user? */ + if (rate == 0) { + mm_obj_dbg (self, "extended signal information polling disabled (rate: 0 seconds)"); + if (priv->timeout_source) { + g_source_remove (priv->timeout_source); + priv->timeout_source = 0; + } + check_interface_reset (self); return TRUE; } - /* Update refresh context */ - mm_obj_dbg (self, "extended signal information reporting enabled (rate: %u seconds)", new_rate); - ctx->rate = new_rate; - if (ctx->timeout_source) - g_source_remove (ctx->timeout_source); - ctx->timeout_source = g_timeout_add_seconds (ctx->rate, (GSourceFunc) refresh_context_cb, self); + /* Restart polling */ + mm_obj_dbg (self, "extended signal information reporting enabled (rate: %u seconds)", rate); + if (priv->timeout_source) + g_source_remove (priv->timeout_source); + priv->timeout_source = g_timeout_add_seconds (rate, (GSourceFunc) polling_context_cb, self); /* Also launch right away */ - refresh_context_cb (self); - + polling_context_cb (self); return TRUE; } @@ -257,9 +271,9 @@ setup_refresh_context (MMIfaceModemSignal *self, typedef struct { GDBusMethodInvocation *invocation; - MmGdbusModemSignal *skeleton; - MMIfaceModemSignal *self; - guint rate; + MmGdbusModemSignal *skeleton; + MMIfaceModemSignal *self; + guint rate; } HandleSetupContext; static void @@ -278,9 +292,20 @@ handle_setup_auth_ready (MMBaseModem *self, { GError *error = NULL; - if (!mm_base_modem_authorize_finish (self, res, &error)) + if (!mm_base_modem_authorize_finish (self, res, &error)) { g_dbus_method_invocation_take_error (ctx->invocation, error); - else if (!setup_refresh_context (ctx->self, TRUE, ctx->rate, &error)) + handle_setup_context_free (ctx); + return; + } + + if (mm_iface_modem_abort_invocation_if_state_not_reached (MM_IFACE_MODEM (self), + ctx->invocation, + MM_MODEM_STATE_ENABLED)) { + handle_setup_context_free (ctx); + return; + } + + if (!polling_restart (ctx->self, ctx->rate, &error)) g_dbus_method_invocation_take_error (ctx->invocation, error); else mm_gdbus_modem_signal_complete_setup (ctx->skeleton, ctx->invocation); @@ -288,10 +313,10 @@ handle_setup_auth_ready (MMBaseModem *self, } static gboolean -handle_setup (MmGdbusModemSignal *skeleton, +handle_setup (MmGdbusModemSignal *skeleton, GDBusMethodInvocation *invocation, - guint rate, - MMIfaceModemSignal *self) + guint rate, + MMIfaceModemSignal *self) { HandleSetupContext *ctx; @@ -336,14 +361,21 @@ setup_thresholds_ready (MMIfaceModemSignal *self, GAsyncResult *res, HandleSetupThresholdsContext *ctx) { - GError *error = NULL; + GError *error = NULL; + Private *priv; + + priv = get_private (MM_IFACE_MODEM_SIGNAL (self)); if (!MM_IFACE_MODEM_SIGNAL_GET_INTERFACE (ctx->self)->setup_thresholds_finish (ctx->self, res, &error)) g_dbus_method_invocation_take_error (ctx->invocation, error); else { - /* Update the property with the latest threshold setting */ + /* Update the properties with the latest threshold setting */ mm_gdbus_modem_signal_set_rssi_threshold (ctx->skeleton, ctx->rssi_threshold); mm_gdbus_modem_signal_set_error_rate_threshold (ctx->skeleton, ctx->error_rate_threshold); + priv->rssi_threshold = ctx->rssi_threshold; + priv->error_rate_threshold = ctx->error_rate_threshold; + check_interface_reset (self); + mm_gdbus_modem_signal_complete_setup_thresholds (ctx->skeleton, ctx->invocation); } @@ -393,61 +425,15 @@ select_new_threshold_settings (HandleSetupThresholdsContext *ctx, return TRUE; } -static gboolean -check_threshold_settings (HandleSetupThresholdsContext *ctx, - GError **error) -{ - MmGdbusModemSignal *skeleton; - MMModemState modem_state; - guint32 old_rssi_threshold; - gboolean old_error_threshold; - - g_object_get (ctx->self, - MM_IFACE_MODEM_SIGNAL_DBUS_SKELETON, &skeleton, - MM_IFACE_MODEM_STATE, &modem_state, - NULL); - - if (!skeleton) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't get signal interface skeleton"); - return FALSE; - } - - if (modem_state < MM_MODEM_STATE_ENABLING) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_WRONG_STATE, - "Modem in wrong state"); - return FALSE; - } - - /* Compare to old threshold values */ - old_rssi_threshold = mm_gdbus_modem_signal_get_rssi_threshold(skeleton); - old_error_threshold = mm_gdbus_modem_signal_get_error_rate_threshold(skeleton); - - /* Set older threshold values before reading dictionary. So that if only - * one value is passed then the other threshold will be maintained as set - * previously. */ - ctx->rssi_threshold = old_rssi_threshold; - ctx->error_rate_threshold = old_error_threshold; - - if (!select_new_threshold_settings (ctx, error)) - return FALSE; - - if ((ctx->rssi_threshold == old_rssi_threshold) && (ctx->error_rate_threshold == old_error_threshold)) { - /* Already there */ - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, - "Same threshold settings already configured"); - return FALSE; - } - - return TRUE; -} - static void handle_setup_thresholds_auth_ready (MMBaseModem *self, GAsyncResult *res, HandleSetupThresholdsContext *ctx) { - GError *error = NULL; + GError *error = NULL; + Private *priv; + + priv = get_private (MM_IFACE_MODEM_SIGNAL (self)); if (!mm_base_modem_authorize_finish (self, res, &error)) { g_dbus_method_invocation_take_error (ctx->invocation, error); @@ -463,12 +449,28 @@ handle_setup_thresholds_auth_ready (MMBaseModem *self, return; } - if (!check_threshold_settings (ctx, &error)) { + if (mm_iface_modem_abort_invocation_if_state_not_reached (MM_IFACE_MODEM (self), + ctx->invocation, + MM_MODEM_STATE_ENABLED)) { + handle_setup_thresholds_context_free (ctx); + return; + } + + /* Process received settings */ + if (!select_new_threshold_settings (ctx, &error)) { g_dbus_method_invocation_take_error (ctx->invocation, error); handle_setup_thresholds_context_free (ctx); return; } + /* Same settings? */ + if ((ctx->rssi_threshold == priv->rssi_threshold) && + (ctx->error_rate_threshold == priv->error_rate_threshold)) { + mm_gdbus_modem_signal_complete_setup_thresholds (ctx->skeleton, ctx->invocation); + handle_setup_thresholds_context_free (ctx); + return; + } + MM_IFACE_MODEM_SIGNAL_GET_INTERFACE (ctx->self)->setup_thresholds ( ctx->self, ctx->rssi_threshold, @@ -502,21 +504,21 @@ handle_setup_thresholds (MmGdbusModemSignal *skeleton, /*****************************************************************************/ gboolean -mm_iface_modem_signal_disable_finish (MMIfaceModemSignal *self, - GAsyncResult *res, - GError **error) +mm_iface_modem_signal_disable_finish (MMIfaceModemSignal *self, + GAsyncResult *res, + GError **error) { return g_task_propagate_boolean (G_TASK (res), error); } void -mm_iface_modem_signal_disable (MMIfaceModemSignal *self, - GAsyncReadyCallback callback, - gpointer user_data) +mm_iface_modem_signal_disable (MMIfaceModemSignal *self, + GAsyncReadyCallback callback, + gpointer user_data) { GTask *task; - teardown_refresh_context (self); + mm_iface_modem_signal_update (self, NULL, NULL, NULL, NULL, NULL, NULL); task = g_task_new (self, NULL, callback, user_data); g_task_return_boolean (task, TRUE); @@ -526,29 +528,31 @@ mm_iface_modem_signal_disable (MMIfaceModemSignal *self, /*****************************************************************************/ gboolean -mm_iface_modem_signal_enable_finish (MMIfaceModemSignal *self, - GAsyncResult *res, - GError **error) +mm_iface_modem_signal_enable_finish (MMIfaceModemSignal *self, + GAsyncResult *res, + GError **error) { return g_task_propagate_boolean (G_TASK (res), error); } void -mm_iface_modem_signal_enable (MMIfaceModemSignal *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +mm_iface_modem_signal_enable (MMIfaceModemSignal *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - GTask *task; - GError *error = NULL; + GTask *task; + GError *error = NULL; + Private *priv; + priv = get_private (self); task = g_task_new (self, cancellable, callback, user_data); - if (!setup_refresh_context (self, FALSE, 0, &error)) + /* same rate as we had before */ + if (!polling_restart (self, priv->rate, &error)) g_task_return_error (task, error); else g_task_return_boolean (task, TRUE); - g_object_unref (task); } @@ -742,9 +746,6 @@ mm_iface_modem_signal_initialize (MMIfaceModemSignal *self, void mm_iface_modem_signal_shutdown (MMIfaceModemSignal *self) { - /* Teardown refresh context */ - teardown_refresh_context (self); - /* Unexport DBus interface and remove the skeleton */ mm_gdbus_object_skeleton_set_modem_signal (MM_GDBUS_OBJECT_SKELETON (self), NULL); g_object_set (self, |