aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-callback-info.c5
-rw-r--r--src/mm-errors.c3
-rw-r--r--src/mm-errors.h3
-rw-r--r--src/mm-generic-cdma.c196
-rw-r--r--src/mm-generic-gsm.c69
-rw-r--r--src/mm-modem.c46
-rw-r--r--src/mm-modem.h2
7 files changed, 194 insertions, 130 deletions
diff --git a/src/mm-callback-info.c b/src/mm-callback-info.c
index b554f79b..1882898a 100644
--- a/src/mm-callback-info.c
+++ b/src/mm-callback-info.c
@@ -11,6 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include "mm-callback-info.h"
@@ -55,8 +56,8 @@ modem_destroyed_cb (gpointer data, GObject *destroyed)
info->modem = NULL;
if (!info->pending_id) {
info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "The modem was removed or disabled.");
+ MM_MODEM_ERROR_REMOVED,
+ "The modem was removed.");
mm_callback_info_schedule (info);
}
}
diff --git a/src/mm-errors.c b/src/mm-errors.c
index 6448b807..34f56c19 100644
--- a/src/mm-errors.c
+++ b/src/mm-errors.c
@@ -11,7 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include "mm-errors.h"
@@ -72,6 +72,7 @@ mm_modem_error_get_type (void)
ENUM_ENTRY (MM_MODEM_ERROR_CONNECTED, "Connected"),
ENUM_ENTRY (MM_MODEM_ERROR_DISCONNECTED, "Disconnected"),
ENUM_ENTRY (MM_MODEM_ERROR_OPERATION_IN_PROGRESS, "OperationInProgress"),
+ ENUM_ENTRY (MM_MODEM_ERROR_REMOVED, "Removed"),
{ 0, 0, 0 }
};
diff --git a/src/mm-errors.h b/src/mm-errors.h
index 4bf8ecad..c02a351b 100644
--- a/src/mm-errors.h
+++ b/src/mm-errors.h
@@ -38,7 +38,8 @@ enum {
MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED = 1,
MM_MODEM_ERROR_CONNECTED = 2,
MM_MODEM_ERROR_DISCONNECTED = 3,
- MM_MODEM_ERROR_OPERATION_IN_PROGRESS = 4
+ MM_MODEM_ERROR_OPERATION_IN_PROGRESS = 4,
+ MM_MODEM_ERROR_REMOVED = 5
};
#define MM_MODEM_ERROR (mm_modem_error_quark ())
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c
index 1d20760a..e3c6004f 100644
--- a/src/mm-generic-cdma.c
+++ b/src/mm-generic-cdma.c
@@ -11,7 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include <string.h>
@@ -478,13 +478,15 @@ static void
disable_all_done (MMModem *modem, GError *error, gpointer user_data)
{
MMCallbackInfo *info = user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- if (error) {
- disable_set_previous_state (MM_MODEM (modem), info);
- info->error = g_error_copy (error);
+ info->error = mm_modem_check_removed (modem, error);
+ if (info->error) {
+ if (modem)
+ disable_set_previous_state (modem, info);
} else {
+ MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
+ MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
+
mm_serial_port_close (priv->primary);
mm_modem_set_state (modem, MM_MODEM_STATE_DISABLED, MM_MODEM_STATE_REASON_NONE);
@@ -501,18 +503,22 @@ disable_flash_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
+ MMGenericCdma *self;
- if (error) {
- disable_set_previous_state (info->modem, info);
- info->error = g_error_copy (error);
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem)
+ disable_set_previous_state (info->modem, info);
mm_callback_info_schedule (info);
- } else {
- if (MM_GENERIC_CDMA_GET_CLASS (self)->post_disable)
- MM_GENERIC_CDMA_GET_CLASS (self)->post_disable (self, disable_all_done, info);
- else
- disable_all_done (MM_MODEM (self), NULL, info);
+ return;
}
+
+ self = MM_GENERIC_CDMA (info->modem);
+
+ if (MM_GENERIC_CDMA_GET_CLASS (self)->post_disable)
+ MM_GENERIC_CDMA_GET_CLASS (self)->post_disable (self, disable_all_done, info);
+ else
+ disable_all_done (MM_MODEM (self), NULL, info);
}
static void
@@ -557,13 +563,15 @@ dial_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);;
- if (error) {
- info->error = g_error_copy (error);
- update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem)
+ update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
} else {
+ MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
+ MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
+
/* Clear reg tries; we're obviously registered by this point */
registration_cleanup (self, 0, 0);
@@ -598,25 +606,22 @@ disconnect_flash_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
-
- if (error) {
- MMModemState prev_state;
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_CDMA_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
+ MMModemState prev_state;
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem) {
+ /* Reset old state since the operation failed */
+ prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_CDMA_PREV_STATE_TAG));
+ mm_modem_set_state (MM_MODEM (info->modem),
+ prev_state,
+ MM_MODEM_STATE_REASON_NONE);
+ }
+ } else {
+ mm_port_set_connected (MM_GENERIC_CDMA_GET_PRIVATE (info->modem)->data, FALSE);
+ update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
}
- mm_port_set_connected (priv->data, FALSE);
- update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
-
mm_callback_info_schedule (info);
}
@@ -727,21 +732,28 @@ get_card_info (MMModem *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
+ MMSerialPort *port = priv->primary;
info = mm_callback_info_new_full (MM_MODEM (modem),
card_info_invoke,
G_CALLBACK (callback),
user_data);
- mm_serial_port_queue_command_cached (priv->secondary ? priv->secondary : priv->primary,
- "+GMI", 3,
- get_manufacturer_done, info);
- mm_serial_port_queue_command_cached (priv->secondary ? priv->secondary : priv->primary,
- "+GMM", 3,
- get_model_done, info);
- mm_serial_port_queue_command_cached (priv->secondary ? priv->secondary : priv->primary,
- "+GMR", 3,
- get_version_done, info);
+ if (mm_port_get_connected (MM_PORT (priv->primary))) {
+ if (!priv->secondary) {
+ info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
+ "Cannot modem info while connected");
+ mm_callback_info_schedule (info);
+ return;
+ }
+
+ /* Use secondary port if primary is connected */
+ port = priv->secondary;
+ }
+
+ mm_serial_port_queue_command_cached (port, "+GMI", 3, get_manufacturer_done, info);
+ mm_serial_port_queue_command_cached (port, "+GMM", 3, get_model_done, info);
+ mm_serial_port_queue_command_cached (port, "+GMR", 3, get_version_done, info);
}
/*****************************************************************************/
@@ -839,20 +851,21 @@ get_signal_quality (MMModemCdma *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- gboolean connected;
+ MMSerialPort *port = priv->primary;
- connected = mm_port_get_connected (MM_PORT (priv->primary));
- if (connected && !priv->secondary) {
- g_message ("Returning saved signal quality %d", priv->cdma1x_quality);
- callback (MM_MODEM (modem), priv->cdma1x_quality, NULL, user_data);
- return;
+ if (mm_port_get_connected (MM_PORT (priv->primary))) {
+ if (!priv->secondary) {
+ g_message ("Returning saved signal quality %d", priv->cdma1x_quality);
+ callback (MM_MODEM (modem), priv->cdma1x_quality, NULL, user_data);
+ return;
+ }
+
+ /* Use secondary port if primary is connected */
+ port = priv->secondary;
}
info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
- /* Prefer secondary port for signal strength */
- mm_serial_port_queue_command (priv->secondary ? priv->secondary : priv->primary,
- "+CSQ", 3,
- get_signal_quality_done, info);
+ mm_serial_port_queue_command (port, "+CSQ", 3, get_signal_quality_done, info);
}
static void
@@ -881,22 +894,24 @@ get_esn (MMModemCdma *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- gboolean connected;
GError *error;
+ MMSerialPort *port = priv->primary;
- connected = mm_port_get_connected (MM_PORT (priv->primary));
- if (connected && !priv->secondary) {
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
- "Cannot get ESN while connected");
- callback (MM_MODEM (modem), NULL, error, user_data);
- g_error_free (error);
- return;
+ if (mm_port_get_connected (MM_PORT (priv->primary))) {
+ if (!priv->secondary) {
+ error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
+ "Cannot get ESN while connected");
+ callback (MM_MODEM (modem), NULL, error, user_data);
+ g_error_free (error);
+ return;
+ }
+
+ /* Use secondary port if primary is connected */
+ port = priv->secondary;
}
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command_cached (priv->secondary ? priv->secondary : priv->primary,
- "+GSN", 3,
- get_string_done, info);
+ mm_serial_port_queue_command_cached (port, "+GSN", 3, get_string_done, info);
}
static void
@@ -1098,16 +1113,20 @@ get_serving_system (MMModemCdma *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- gboolean connected;
GError *error;
+ MMSerialPort *port = priv->primary;
- connected = mm_port_get_connected (MM_PORT (priv->primary));
- if (connected && !priv->secondary) {
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
- "Cannot get serving system while connected");
- callback (modem, 0, 0, 0, error, user_data);
- g_error_free (error);
- return;
+ if (mm_port_get_connected (MM_PORT (priv->primary))) {
+ if (!priv->secondary) {
+ error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
+ "Cannot get serving system while connected");
+ callback (modem, 0, 0, 0, error, user_data);
+ g_error_free (error);
+ return;
+ }
+
+ /* Use secondary port if primary is connected */
+ port = priv->secondary;
}
info = mm_callback_info_new_full (MM_MODEM (modem),
@@ -1115,9 +1134,7 @@ get_serving_system (MMModemCdma *modem,
G_CALLBACK (callback),
user_data);
- mm_serial_port_queue_command (priv->secondary ? priv->secondary : priv->primary,
- "+CSS?", 3,
- serving_system_done, info);
+ mm_serial_port_queue_command (port, "+CSS?", 3, serving_system_done, info);
}
#define CDMA_1X_STATE_TAG "cdma-1x-reg-state"
@@ -1323,23 +1340,22 @@ get_registration_state (MMModemCdma *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- gboolean connected;
+ MMSerialPort *port = priv->primary;
- connected = mm_port_get_connected (MM_PORT (priv->primary));
- if (connected && !priv->secondary) {
- g_message ("Returning saved registration states: 1x: %d EVDO: %d",
- priv->cdma_1x_reg_state, priv->evdo_reg_state);
- callback (MM_MODEM_CDMA (modem), priv->cdma_1x_reg_state, priv->evdo_reg_state, NULL, user_data);
- return;
+ if (mm_port_get_connected (MM_PORT (priv->primary))) {
+ if (!priv->secondary) {
+ g_message ("Returning saved registration states: 1x: %d EVDO: %d",
+ priv->cdma_1x_reg_state, priv->evdo_reg_state);
+ callback (MM_MODEM_CDMA (modem), priv->cdma_1x_reg_state, priv->evdo_reg_state, NULL, user_data);
+ return;
+ }
+
+ /* Use secondary port if primary is connected */
+ port = priv->secondary;
}
info = mm_generic_cdma_query_reg_state_callback_info_new (MM_GENERIC_CDMA (modem), callback, user_data);
-
- /* Prefer secondary port for registration state */
- mm_serial_port_queue_command (priv->secondary ? priv->secondary : priv->primary,
- "+CAD?",
- 3,
- get_analog_digital_done, info);
+ mm_serial_port_queue_command (port, "+CAD?", 3, get_analog_digital_done, info);
}
/*****************************************************************************/
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 25c6c1ee..4954ca1b 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -11,7 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
* Copyright (C) 2009 Ericsson
*/
@@ -538,13 +538,17 @@ disable_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = user_data;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- mm_serial_port_close (port);
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
- priv->reg_status = MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN;
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (!info->error) {
+ MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
+
+ mm_serial_port_close (port);
+ mm_modem_set_state (MM_MODEM (info->modem),
+ MM_MODEM_STATE_DISABLED,
+ MM_MODEM_STATE_REASON_NONE);
+ priv->reg_status = MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN;
+ }
mm_callback_info_schedule (info);
}
@@ -554,18 +558,19 @@ disable_flash_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = user_data;
+ MMModemState prev_state;
char *cmd = NULL;
- if (error) {
- MMModemState prev_state;
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem) {
+ /* Reset old state since the operation failed */
+ prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
+ mm_modem_set_state (MM_MODEM (info->modem),
+ prev_state,
+ MM_MODEM_STATE_REASON_NONE);
+ }
- info->error = g_error_copy (error);
mm_callback_info_schedule (info);
return;
}
@@ -1374,25 +1379,25 @@ disconnect_flash_done (MMSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (error) {
- MMModemState prev_state;
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
+ MMModemState prev_state;
+
+ info->error = mm_modem_check_removed (info->modem, error);
+ if (info->error) {
+ if (info->modem) {
+ /* Reset old state since the operation failed */
+ prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
+ mm_modem_set_state (MM_MODEM (info->modem),
+ prev_state,
+ MM_MODEM_STATE_REASON_NONE);
+ }
+ } else {
+ MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
+ MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
+ mm_port_set_connected (priv->data, FALSE);
+ mm_generic_gsm_update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE);
}
- mm_port_set_connected (priv->data, FALSE);
- mm_generic_gsm_update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE);
mm_callback_info_schedule (info);
}
diff --git a/src/mm-modem.c b/src/mm-modem.c
index 5f0f5fac..27b77954 100644
--- a/src/mm-modem.c
+++ b/src/mm-modem.c
@@ -11,7 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include <string.h>
@@ -29,6 +29,28 @@ static void impl_modem_get_info (MMModem *modem, DBusGMethodInvocation *context)
#include "mm-modem-glue.h"
+/* Should be used from callbacks to check whether the modem was removed after
+ * the callback's operation was started, but before the callback itself was
+ * called, in which case the MMModem passed to the callback is NULL.
+ */
+GError *
+mm_modem_check_removed (MMModem *self, const GError *error)
+{
+ if (g_error_matches (error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED))
+ return g_error_copy (error);
+
+ if (!self) {
+ /* If the modem was NULL, the error *should* have been
+ * MM_MODEM_ERROR_REMOVED. If it wasn't, make it that.
+ */
+ return g_error_new_literal (MM_MODEM_ERROR,
+ MM_MODEM_ERROR_REMOVED,
+ "The modem was removed.");
+ }
+
+ return NULL;
+}
+
static void
async_op_not_supported (MMModem *self,
MMModemFn callback,
@@ -92,7 +114,6 @@ finish_disable (MMModem *self,
MMModemFn callback,
gpointer user_data)
{
-
if (MM_MODEM_GET_INTERFACE (self)->disable)
MM_MODEM_GET_INTERFACE (self)->disable (self, callback, user_data);
else
@@ -110,9 +131,27 @@ disable_disconnect_done (MMModem *self,
gpointer user_data)
{
DisableDisconnectInfo *cb_data = user_data;
+ GError *tmp_error = NULL;
+
+ /* Check for modem removal */
+ if (g_error_matches (error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED))
+ tmp_error = g_error_copy (error);
+ else if (!self) {
+ tmp_error = g_error_new_literal (MM_MODEM_ERROR,
+ MM_MODEM_ERROR_REMOVED,
+ "The modem was removed.");
+ }
+
+ /* And send an immediate error reply if the modem was removed */
+ if (tmp_error) {
+ cb_data->callback (NULL, tmp_error, cb_data->user_data);
+ g_free (cb_data);
+ g_error_free (tmp_error);
+ return;
+ }
- /* ignore errors */
if (error) {
+ /* Don't really care what the error was; log it and proceed to disable */
g_warning ("%s: (%s): error disconnecting the modem while disabling: (%d) %s",
__func__,
mm_modem_get_device (self),
@@ -337,7 +376,6 @@ mm_modem_disconnect (MMModem *self,
return;
}
-
if (MM_MODEM_GET_INTERFACE (self)->disconnect)
MM_MODEM_GET_INTERFACE (self)->disconnect (self, callback, user_data);
else
diff --git a/src/mm-modem.h b/src/mm-modem.h
index b59525e2..e8dd7ea2 100644
--- a/src/mm-modem.h
+++ b/src/mm-modem.h
@@ -213,5 +213,7 @@ void mm_modem_set_state (MMModem *self,
MMModemState new_state,
MMModemStateReason reason);
+GError *mm_modem_check_removed (MMModem *self, const GError *error);
+
#endif /* MM_MODEM_H */