aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-iface-modem.c157
1 files changed, 72 insertions, 85 deletions
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 4c952684..a18accdd 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -231,6 +231,33 @@ mm_iface_modem_wait_for_final_state (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Helper to return an error when the modem is in failed state and so it
+ * cannot process a given method invocation
+ */
+
+static gboolean
+abort_invocation_if_state_not_reached (MMIfaceModem *self,
+ GDBusMethodInvocation *invocation,
+ MMModemState minimum_required)
+{
+ MMModemState state = MM_MODEM_STATE_UNKNOWN;
+
+ g_object_get (self,
+ MM_IFACE_MODEM_STATE, &state,
+ NULL);
+
+ if (state >= minimum_required)
+ return FALSE;
+
+ g_dbus_method_invocation_return_error (invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_WRONG_STATE,
+ "modem in %s state",
+ mm_modem_state_get_string (state));
+ return TRUE;
+}
+
+/*****************************************************************************/
/* Helper method to load unlock required, considering retries */
#define MAX_RETRIES 6
@@ -627,6 +654,11 @@ handle_create_bearer_auth_ready (MMBaseModem *self,
return;
}
+ if (abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_LOCKED)) {
+ handle_create_bearer_context_free (ctx);
+ return;
+ }
+
properties = mm_bearer_properties_new_from_dictionary (ctx->dictionary, &error);
if (!properties) {
g_dbus_method_invocation_take_error (ctx->invocation, error);
@@ -716,6 +748,11 @@ handle_command_auth_ready (MMBaseModem *self,
return;
}
+ if (abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_LOCKED)) {
+ handle_command_context_free (ctx);
+ return;
+ }
+
/* If we are not in Debug mode, report an error */
if (!mm_context_get_debug ()) {
g_dbus_method_invocation_return_error (ctx->invocation,
@@ -828,6 +865,11 @@ handle_delete_bearer_auth_ready (MMBaseModem *self,
return;
}
+ if (abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_LOCKED)) {
+ handle_delete_bearer_context_free (ctx);
+ return;
+ }
+
if (!g_str_has_prefix (ctx->bearer_path, MM_DBUS_BEARER_PREFIX)) {
g_dbus_method_invocation_return_error (ctx->invocation,
MM_CORE_ERROR,
@@ -889,6 +931,9 @@ handle_list_bearers (MmGdbusModem *skeleton,
GStrv paths;
MMBearerList *list = NULL;
+ if (abort_invocation_if_state_not_reached (self, invocation, MM_MODEM_STATE_LOCKED))
+ return TRUE;
+
g_object_get (self,
MM_IFACE_MODEM_BEARER_LIST, &list,
NULL);
@@ -1735,6 +1780,11 @@ handle_enable_auth_ready (MMBaseModem *self,
return;
}
+ if (abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_LOCKED)) {
+ handle_enable_context_free (ctx);
+ return;
+ }
+
if (ctx->enable)
mm_base_modem_enable (self,
(GAsyncReadyCallback)enable_ready,
@@ -2055,7 +2105,12 @@ handle_factory_reset (MmGdbusModem *skeleton,
}
/*****************************************************************************/
-/* Current capabilities setting */
+/* Current capabilities setting
+ *
+ * Setting capabilities allowed also in FAILED state. Just imagine a
+ * 3GPP+3GPP2 modem in 3GPP-only mode without SIM, we should allow
+ * changing caps to 3GPP2, which doesn't require SIM
+ */
typedef struct {
MmGdbusModem *skeleton;
@@ -2521,7 +2576,6 @@ handle_set_current_bands_auth_ready (MMBaseModem *self,
HandleSetCurrentBandsContext *ctx)
{
GArray *bands_array;
- MMModemState modem_state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (self, res, &error)) {
@@ -2530,17 +2584,7 @@ handle_set_current_bands_auth_ready (MMBaseModem *self,
return;
}
- modem_state = MM_MODEM_STATE_UNKNOWN;
- g_object_get (self,
- MM_IFACE_MODEM_STATE, &modem_state,
- NULL);
-
- if (modem_state < MM_MODEM_STATE_DISABLED) {
- g_dbus_method_invocation_return_error (ctx->invocation,
- MM_CORE_ERROR,
- MM_CORE_ERROR_WRONG_STATE,
- "Cannot set current bands: "
- "not initialized/unlocked yet");
+ if (abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_DISABLED)) {
handle_set_current_bands_context_free (ctx);
return;
}
@@ -2840,7 +2884,6 @@ handle_set_current_modes_auth_ready (MMBaseModem *self,
GAsyncResult *res,
HandleSetCurrentModesContext *ctx)
{
- MMModemState modem_state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (self, res, &error)) {
@@ -2849,17 +2892,7 @@ handle_set_current_modes_auth_ready (MMBaseModem *self,
return;
}
- modem_state = MM_MODEM_STATE_UNKNOWN;
- g_object_get (self,
- MM_IFACE_MODEM_STATE, &modem_state,
- NULL);
-
- if (modem_state < MM_MODEM_STATE_DISABLED) {
- g_dbus_method_invocation_return_error (ctx->invocation,
- MM_CORE_ERROR,
- MM_CORE_ERROR_WRONG_STATE,
- "Cannot set current modes: "
- "not initialized/unlocked yet");
+ if (abort_invocation_if_state_not_reached (ctx->self, ctx->invocation, MM_MODEM_STATE_DISABLED)) {
handle_set_current_modes_context_free (ctx);
return;
}
@@ -4956,66 +4989,20 @@ interface_initialization_step (GTask *task)
}
case INITIALIZATION_STEP_LAST:
- /* Setting capabilities allowed also in FAILED state. Just imagine a
- * 3GPP+3GPP2 modem in 3GPP-only mode without SIM, we should allow
- * changing caps to 3GPP2, which doesn't require SIM */
- g_signal_connect (ctx->skeleton,
- "handle-set-current-capabilities",
- G_CALLBACK (handle_set_current_capabilities),
- self);
- /* Allow setting the power state to OFF even when the modem is in the
- * FAILED state as this operation does not necessarily depend on the
- * presence of a SIM. handle_set_power_state_auth_ready already ensures
- * that the power state can only be set to OFF when the modem is in the
- * FAILED state. */
- g_signal_connect (ctx->skeleton,
- "handle-set-power-state",
- G_CALLBACK (handle_set_power_state),
- self);
- /* Allow the reset and factory reset operation in FAILED state to rescue the modem.
- * Also, for a modem that doesn't support SIM hot swapping, a reset is needed to
- * force the modem to detect the newly inserted SIM. */
- g_signal_connect (ctx->skeleton,
- "handle-reset",
- G_CALLBACK (handle_reset),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-factory-reset",
- G_CALLBACK (handle_factory_reset),
- self);
-
- if (!ctx->fatal_error) {
- /* We are done without errors!
- * Handle method invocations */
- g_signal_connect (ctx->skeleton,
- "handle-create-bearer",
- G_CALLBACK (handle_create_bearer),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-command",
- G_CALLBACK (handle_command),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-delete-bearer",
- G_CALLBACK (handle_delete_bearer),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-list-bearers",
- G_CALLBACK (handle_list_bearers),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-enable",
- G_CALLBACK (handle_enable),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-set-current-bands",
- G_CALLBACK (handle_set_current_bands),
- self);
- g_signal_connect (ctx->skeleton,
- "handle-set-current-modes",
- G_CALLBACK (handle_set_current_modes),
- self);
- }
+ /* Setup all method handlers */
+ g_object_connect (ctx->skeleton,
+ "signal::handle-set-current-capabilities", G_CALLBACK (handle_set_current_capabilities), self,
+ "signal::handle-set-power-state", G_CALLBACK (handle_set_power_state), self,
+ "signal::handle-reset", G_CALLBACK (handle_reset), self,
+ "signal::handle-factory-reset", G_CALLBACK (handle_factory_reset), self,
+ "signal::handle-create-bearer", G_CALLBACK (handle_create_bearer), self,
+ "signal::handle-command", G_CALLBACK (handle_command), self,
+ "signal::handle-delete-bearer", G_CALLBACK (handle_delete_bearer), self,
+ "signal::handle-list-bearers", G_CALLBACK (handle_list_bearers), self,
+ "signal::handle-enable", G_CALLBACK (handle_enable), self,
+ "signal::handle-set-current-bands", G_CALLBACK (handle_set_current_bands), self,
+ "signal::handle-set-current-modes", G_CALLBACK (handle_set_current_modes), self,
+ NULL);
/* Finally, export the new interface, even if we got errors, but only if not
* done already */