diff options
-rw-r--r-- | plugins/mm-modem-anydata-cdma.c | 10 | ||||
-rw-r--r-- | plugins/mm-modem-gobi-gsm.c | 5 | ||||
-rw-r--r-- | plugins/mm-modem-hso.c | 66 | ||||
-rw-r--r-- | plugins/mm-modem-huawei-cdma.c | 5 | ||||
-rw-r--r-- | plugins/mm-modem-huawei-gsm.c | 45 | ||||
-rw-r--r-- | plugins/mm-modem-icera.c | 59 | ||||
-rw-r--r-- | plugins/mm-modem-linktop.c | 12 | ||||
-rw-r--r-- | plugins/mm-modem-longcheer-gsm.c | 20 | ||||
-rw-r--r-- | plugins/mm-modem-mbm.c | 70 | ||||
-rw-r--r-- | plugins/mm-modem-novatel-cdma.c | 19 | ||||
-rw-r--r-- | plugins/mm-modem-novatel-gsm.c | 20 | ||||
-rw-r--r-- | plugins/mm-modem-option-utils.c | 28 | ||||
-rwxr-xr-x | plugins/mm-modem-samsung-gsm.c | 42 | ||||
-rw-r--r-- | plugins/mm-modem-sierra-cdma.c | 24 | ||||
-rw-r--r-- | plugins/mm-modem-sierra-gsm.c | 48 | ||||
-rw-r--r-- | plugins/mm-modem-simtech-gsm.c | 43 | ||||
-rw-r--r-- | plugins/mm-modem-wavecom-gsm.c | 89 | ||||
-rw-r--r-- | plugins/mm-modem-x22x-gsm.c | 19 | ||||
-rw-r--r-- | plugins/mm-modem-zte.c | 46 | ||||
-rw-r--r-- | src/mm-callback-info.c | 8 | ||||
-rw-r--r-- | src/mm-callback-info.h | 2 | ||||
-rw-r--r-- | src/mm-generic-cdma.c | 117 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 490 | ||||
-rw-r--r-- | src/mm-modem-base.c | 20 | ||||
-rw-r--r-- | src/mm-modem.c | 19 | ||||
-rw-r--r-- | src/mm-modem.h | 2 |
26 files changed, 1029 insertions, 299 deletions
diff --git a/plugins/mm-modem-anydata-cdma.c b/plugins/mm-modem-anydata-cdma.c index 0e7e65c5..7b6b37a2 100644 --- a/plugins/mm-modem-anydata-cdma.c +++ b/plugins/mm-modem-anydata-cdma.c @@ -128,6 +128,11 @@ evdo_state_done (MMAtSerialPort *port, GRegex *r; GMatchInfo *match_info; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { /* Leave superclass' reg state alone if AT*HSTATE isn't supported */ mm_callback_info_schedule (info); @@ -195,6 +200,11 @@ state_done (MMAtSerialPort *port, GRegex *r; GMatchInfo *match_info; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { /* Leave superclass' reg state alone if AT*STATE isn't supported */ mm_callback_info_schedule (info); diff --git a/plugins/mm-modem-gobi-gsm.c b/plugins/mm-modem-gobi-gsm.c index 7e2fa4ca..ab19642b 100644 --- a/plugins/mm-modem-gobi-gsm.c +++ b/plugins/mm-modem-gobi-gsm.c @@ -63,6 +63,11 @@ get_string_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error && response && !strcmp (response->str, "ERROR")) { info->error = g_error_new_literal (MM_MOBILE_ERROR, MM_MOBILE_ERROR_SIM_NOT_INSERTED, diff --git a/plugins/mm-modem-hso.c b/plugins/mm-modem-hso.c index 70816665..e3d4dce7 100644 --- a/plugins/mm-modem-hso.c +++ b/plugins/mm-modem-hso.c @@ -117,8 +117,16 @@ auth_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemHso *self = MM_MODEM_HSO (info->modem); - MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (self); + MMModemHso *self; + MMModemHsoPrivate *priv; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_HSO (info->modem); + priv = MM_MODEM_HSO_GET_PRIVATE (self); if (error) { priv->auth_idx++; @@ -257,6 +265,11 @@ hso_call_control_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error && !mm_callback_info_get_data (info, IGNORE_ERRORS_TAG)) info->error = g_error_copy (error); @@ -318,12 +331,13 @@ hso_enabled (MMModem *modem, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - GError *tmp_error; - tmp_error = mm_modem_check_removed (modem, error); - if (tmp_error) { - mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), tmp_error, info); - g_clear_error (&tmp_error); + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), error, info); } else { MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (modem); @@ -338,13 +352,14 @@ old_context_clear_done (MMModem *modem, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - GError *tmp_error; - tmp_error = mm_modem_check_removed (modem, error); - if (tmp_error) { - mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), tmp_error, info); - g_clear_error (&tmp_error); - } else { + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) + mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), error, info); + else { /* Success, activate the PDP context and start the data session */ hso_call_control (MM_MODEM_HSO (modem), TRUE, FALSE, hso_enabled, info); } @@ -356,12 +371,13 @@ connect_auth_done (MMModem *modem, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - GError *tmp_error; - tmp_error = mm_modem_check_removed (modem, error); - if (tmp_error) { - mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), tmp_error, info); - g_clear_error (&tmp_error); + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), error, info); } else { /* Now connect; kill any existing connections first */ hso_call_control (MM_MODEM_HSO (modem), FALSE, TRUE, old_context_clear_done, info); @@ -491,6 +507,11 @@ get_ip4_config_done (MMAtSerialPort *port, guint32 tmp; gint cid; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto out; @@ -560,7 +581,14 @@ disconnect_owancall_done (MMAtSerialPort *port, GError *error, gpointer user_data) { - mm_callback_info_schedule ((MMCallbackInfo *) user_data); + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + mm_callback_info_schedule (info); } static void diff --git a/plugins/mm-modem-huawei-cdma.c b/plugins/mm-modem-huawei-cdma.c index 3aec470b..b24ec64b 100644 --- a/plugins/mm-modem-huawei-cdma.c +++ b/plugins/mm-modem-huawei-cdma.c @@ -167,6 +167,11 @@ sysinfo_done (MMAtSerialPort *port, GMatchInfo *match_info; const char *reply; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { /* Leave superclass' reg state alone if AT^SYSINFO isn't supported */ goto done; diff --git a/plugins/mm-modem-huawei-gsm.c b/plugins/mm-modem-huawei-gsm.c index df58d535..93cb4cca 100644 --- a/plugins/mm-modem-huawei-gsm.c +++ b/plugins/mm-modem-huawei-gsm.c @@ -171,6 +171,11 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -232,11 +237,18 @@ get_allowed_mode_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemHuaweiGsm *self = MM_MODEM_HUAWEI_GSM (info->modem); + MMModemHuaweiGsm *self; int mode_a, mode_b, u1, u2; guint32 band; MMModemGsmAllowedMode mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_HUAWEI_GSM (info->modem); + if (error) info->error = g_error_copy (error); else if (parse_syscfg (self, response->str, &mode_a, &mode_b, &band, &u1, &u2, &mode)) @@ -271,8 +283,16 @@ set_band_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemHuaweiGsm *self = MM_MODEM_HUAWEI_GSM (info->modem); - MMModemHuaweiGsmPrivate *priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (self); + MMModemHuaweiGsm *self; + MMModemHuaweiGsmPrivate *priv; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_HUAWEI_GSM (info->modem); + priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (self); if (error) info->error = g_error_copy (error); @@ -321,10 +341,17 @@ get_band_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemHuaweiGsm *self = MM_MODEM_HUAWEI_GSM (info->modem); + MMModemHuaweiGsm *self; int mode_a, mode_b, u1, u2; guint32 band; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_HUAWEI_GSM (info->modem); + if (error) info->error = g_error_copy (error); else if (parse_syscfg (self, response->str, &mode_a, &mode_b, &band, &u1, &u2, NULL)) { @@ -410,6 +437,11 @@ get_act_request_done (MMAtSerialPort *port, char *str; int srv_stat = 0; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; @@ -504,6 +536,11 @@ send_huawei_cpin_done (MMAtSerialPort *port, char *str = NULL; guint32 num = 0; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; diff --git a/plugins/mm-modem-icera.c b/plugins/mm-modem-icera.c index d34e71ee..b093b344 100644 --- a/plugins/mm-modem-icera.c +++ b/plugins/mm-modem-icera.c @@ -56,6 +56,11 @@ get_allowed_mode_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean parsed = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (!g_str_has_prefix (response->str, "%IPSYS: ")) { @@ -119,6 +124,11 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -235,8 +245,14 @@ get_nwstate_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { MMModemIcera *self = MM_MODEM_ICERA (info->modem); MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self); @@ -277,7 +293,14 @@ disconnect_ipdpact_done (MMAtSerialPort *port, GError *error, gpointer user_data) { - mm_callback_info_schedule ((MMCallbackInfo *) user_data); + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + mm_callback_info_schedule (info); } void @@ -458,6 +481,11 @@ icera_connected (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info); } else { @@ -481,6 +509,11 @@ old_context_clear_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + /* Activate the PDP context and start the data session */ icera_call_control (MM_MODEM_ICERA (info->modem), TRUE, icera_connected, info); } @@ -493,6 +526,11 @@ auth_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info); else { @@ -574,6 +612,11 @@ get_ip4_config_done (MMAtSerialPort *port, guint32 tmp; gint cid; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto out; @@ -710,8 +753,14 @@ is_icera_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else mm_callback_info_set_result (info, GUINT_TO_POINTER (TRUE), NULL); mm_callback_info_schedule (info); } diff --git a/plugins/mm-modem-linktop.c b/plugins/mm-modem-linktop.c index 923c2191..cfe0c0de 100644 --- a/plugins/mm-modem-linktop.c +++ b/plugins/mm-modem-linktop.c @@ -104,6 +104,11 @@ linktop_set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -127,7 +132,7 @@ set_allowed_mode (MMGenericGsm *gsm, mm_callback_info_schedule (info); return; } - + command = g_strdup_printf ("+CFUN=%d", linktop_parse_allowed_mode (mode)); mm_at_serial_port_queue_command (port, command, 3, linktop_set_allowed_mode_done, info); g_free (command); @@ -142,6 +147,11 @@ get_allowed_mode_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean parsed = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (!g_str_has_prefix (response->str, "CFUN: ")) { diff --git a/plugins/mm-modem-longcheer-gsm.c b/plugins/mm-modem-longcheer-gsm.c index 33763e27..610ec777 100644 --- a/plugins/mm-modem-longcheer-gsm.c +++ b/plugins/mm-modem-longcheer-gsm.c @@ -60,9 +60,15 @@ get_allowed_mode_done (MMAtSerialPort *port, MMModemGsmAllowedMode mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; gint mododr = -1; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto done; + } p = mm_strip_tag (response->str, "+MODODR:"); if (!p) { @@ -120,6 +126,11 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -175,6 +186,11 @@ get_act_request_done (MMAtSerialPort *port, MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c index 93034537..1a9fbf37 100644 --- a/plugins/mm-modem-mbm.c +++ b/plugins/mm-modem-mbm.c @@ -177,6 +177,11 @@ mbm_set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -257,6 +262,11 @@ get_allowed_mode_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean parsed = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (!g_str_has_prefix (response->str, "CFUN: ")) { @@ -351,6 +361,11 @@ mbm_enable_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + /* Start unsolicited signal strength and access technology responses */ mm_at_serial_port_queue_command (port, "*ERINFO=1", 3, NULL, NULL); @@ -359,14 +374,21 @@ mbm_enable_done (MMAtSerialPort *port, static void mbm_enap0_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) + GString *response, + GError *error, + gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); + MMModemMbmPrivate *priv; char *command; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); + if (!priv->network_mode) priv->network_mode = MBM_NETWORK_MODE_ANY; @@ -382,7 +404,14 @@ mbm_init_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); + MMModemMbmPrivate *priv; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); if (error) { mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info); @@ -408,12 +437,19 @@ mbm_emrdy_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) mm_warn ("timed out waiting for EMRDY response."); - else + else { + MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); + priv->have_emrdy = TRUE; + } do_init (port, info); } @@ -536,6 +572,11 @@ factory_reset_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + mm_serial_port_close (MM_SERIAL_PORT (port)); mm_callback_info_schedule (info); } @@ -659,6 +700,11 @@ enap_poll_response (MMAtSerialPort *port, g_assert (info); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + count = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "mbm-enap-poll-count")); if (sscanf (response->str, "*ENAP: %d", &state) == 1 && state == 1) { @@ -702,6 +748,11 @@ enap_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; guint tid; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info); return; @@ -796,6 +847,11 @@ send_epin_done (MMAtSerialPort *port, const char *pin_type; int attempts_left = 0; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; diff --git a/plugins/mm-modem-novatel-cdma.c b/plugins/mm-modem-novatel-cdma.c index 6b8c4aa9..c1f4151a 100644 --- a/plugins/mm-modem-novatel-cdma.c +++ b/plugins/mm-modem-novatel-cdma.c @@ -122,16 +122,15 @@ get_rssi_done (MMAtSerialPort *port, MMModemCdma *parent_iface; int qual; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { - if (info->modem) { - /* Fallback to parent's method */ - g_clear_error (&info->error); - parent_iface = g_type_interface_peek_parent (MM_MODEM_CDMA_GET_INTERFACE (info->modem)); - parent_iface->get_signal_quality (MM_MODEM_CDMA (info->modem), parent_csq_done, info); - } else - mm_callback_info_schedule (info); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { + /* Fallback to parent's method */ + parent_iface = g_type_interface_peek_parent (MM_MODEM_CDMA_GET_INTERFACE (info->modem)); + parent_iface->get_signal_quality (MM_MODEM_CDMA (info->modem), parent_csq_done, info); return; } @@ -149,7 +148,7 @@ get_rssi_done (MMAtSerialPort *port, info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Could not parse signal quality results"); } - + mm_callback_info_schedule (info); } diff --git a/plugins/mm-modem-novatel-gsm.c b/plugins/mm-modem-novatel-gsm.c index 64a81bd5..5d78db73 100644 --- a/plugins/mm-modem-novatel-gsm.c +++ b/plugins/mm-modem-novatel-gsm.c @@ -118,6 +118,11 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -227,8 +232,14 @@ get_allowed_mode_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemGsmAllowedMode mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { parse_nwrat_response (response, &mode, &info->error); mm_callback_info_set_result (info, GUINT_TO_POINTER (mode), NULL); } @@ -265,6 +276,11 @@ get_act_request_done (MMAtSerialPort *port, MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { diff --git a/plugins/mm-modem-option-utils.c b/plugins/mm-modem-option-utils.c index 35dd1acd..61ca5d15 100644 --- a/plugins/mm-modem-option-utils.c +++ b/plugins/mm-modem-option-utils.c @@ -32,6 +32,11 @@ option_get_allowed_mode_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean parsed = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (!g_str_has_prefix (response->str, "_OPSYS: ")) { @@ -95,6 +100,11 @@ option_set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -357,8 +367,14 @@ unsolicited_msg_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - if (info) + if (info) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + mm_callback_info_chain_complete_one (info); + } } static void @@ -394,6 +410,11 @@ get_act_octi_request_done (MMAtSerialPort *port, MMModemGsmAccessTech octi = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; MMModemGsmAccessTech owcti; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (!error) { if (parse_octi_response (response, &octi)) { /* If no 3G tech yet or current tech isn't 3G, then 2G tech is the best */ @@ -416,6 +437,11 @@ get_act_owcti_request_done (MMAtSerialPort *port, MMModemGsmAccessTech owcti = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (!error) { p = mm_strip_tag (response->str, "_OWCTI:"); if (owcti_to_mm (*p, &owcti)) { diff --git a/plugins/mm-modem-samsung-gsm.c b/plugins/mm-modem-samsung-gsm.c index 0f63e03f..b7df067d 100755 --- a/plugins/mm-modem-samsung-gsm.c +++ b/plugins/mm-modem-samsung-gsm.c @@ -144,6 +144,11 @@ set_band_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -232,6 +237,11 @@ get_band_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemGsmBand mm_band = MM_MODEM_GSM_BAND_UNKNOWN; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (parse_ipbm (response->str, &mm_band)) @@ -290,6 +300,11 @@ send_samsung_pinnum_done (MMAtSerialPort *port, char *str = NULL; guint32 num = 0; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; @@ -461,7 +476,14 @@ init_all_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); + MMModemSamsungGsm *self; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_SAMSUNG_GSM (info->modem); if (!error) mm_modem_icera_change_unsolicited_messages (MM_MODEM_ICERA (self), TRUE); @@ -476,7 +498,14 @@ init2_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); + MMModemSamsungGsm *self; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_SAMSUNG_GSM (info->modem); if (error) mm_generic_gsm_enable_complete (MM_GENERIC_GSM (self), error, info); @@ -493,7 +522,14 @@ init_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); + MMModemSamsungGsm *self; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_SAMSUNG_GSM (info->modem); if (error) mm_generic_gsm_enable_complete (MM_GENERIC_GSM (self), error, info); diff --git a/plugins/mm-modem-sierra-cdma.c b/plugins/mm-modem-sierra-cdma.c index 1168c834..faf36757 100644 --- a/plugins/mm-modem-sierra-cdma.c +++ b/plugins/mm-modem-sierra-cdma.c @@ -148,7 +148,7 @@ status_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemSierraCdmaPrivate *priv = MM_MODEM_SIERRA_CDMA_GET_PRIVATE (info->modem); + MMModemSierraCdmaPrivate *priv; char **lines, **iter; gboolean registered = FALSE; gboolean have_sid = FALSE; @@ -156,6 +156,13 @@ status_done (MMAtSerialPort *port, SysMode sys_mode = SYS_MODE_UNKNOWN; gboolean evdo_roam = FALSE, cdma1x_roam = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_MODEM_SIERRA_CDMA_GET_PRIVATE (info->modem); + if (error) { /* Leave superclass' reg state alone if AT!STATUS isn't supported */ goto done; @@ -167,11 +174,11 @@ status_done (MMAtSerialPort *port, goto done; } - /* Sierra CDMA parts have two general formats depending on whether they + /* Sierra CDMA parts have two general formats depending on whether they * support EVDO or not. EVDO parts report both 1x and EVDO roaming status * while of course 1x parts only report 1x status. Some modems also do not * report the Roaming information (MP 555 GPS). - * + * * AT!STATUS responses: * * Unregistered MC5725: @@ -182,7 +189,7 @@ status_done (MMAtSerialPort *port, * Temp: 33 State: 100 Sys Mode: NO SRV * Pilot NOT acquired * Modem has NOT registered - * + * * Registered MC5725: * ----------------------- * Current band: Cellular Sleep @@ -340,10 +347,17 @@ pcstate_done (MMAtSerialPort *port, GError *error, gpointer user_data) { + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + /* Ignore errors for now; we're not sure if all Sierra CDMA devices support * at!pcstate. */ - mm_callback_info_schedule ((MMCallbackInfo *) user_data); + mm_callback_info_schedule (info); } static void diff --git a/plugins/mm-modem-sierra-gsm.c b/plugins/mm-modem-sierra-gsm.c index d4636d73..6d4e4d5a 100644 --- a/plugins/mm-modem-sierra-gsm.c +++ b/plugins/mm-modem-sierra-gsm.c @@ -74,9 +74,15 @@ get_allowed_mode_done (MMAtSerialPort *port, GRegex *r = NULL; GMatchInfo *match_info; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto done; + } /* Example response: !SELRAT: 03, UMTS 3G Preferred */ r = g_regex_new ("!SELRAT:\\s*(\\d+).*$", 0, 0, NULL); @@ -156,6 +162,11 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -217,6 +228,11 @@ get_act_request_done (MMAtSerialPort *port, MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { @@ -260,6 +276,11 @@ get_sim_iccid_done (MMAtSerialPort *port, char buf[21]; int i; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; @@ -415,7 +436,13 @@ ppp_connect_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (modem, error); + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + mm_callback_info_schedule (info); } @@ -427,6 +454,11 @@ net_activate_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info); } @@ -441,6 +473,11 @@ auth_done (MMAtSerialPort *port, gint cid; char *command; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); mm_callback_info_schedule (info); @@ -467,6 +504,11 @@ ps_attach_done (MMAtSerialPort *port, MMModem *parent_modem_iface; const char *number; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); mm_callback_info_schedule (info); diff --git a/plugins/mm-modem-simtech-gsm.c b/plugins/mm-modem-simtech-gsm.c index 4a626947..5d420335 100644 --- a/plugins/mm-modem-simtech-gsm.c +++ b/plugins/mm-modem-simtech-gsm.c @@ -67,9 +67,15 @@ get_mode_pref_done (MMAtSerialPort *port, guint32 acqord; MMModemGsmAllowedMode allowed = MM_MODEM_GSM_ALLOWED_MODE_ANY; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto done; + } p = mm_strip_tag (response->str, "+CNMP:"); if (!p) { @@ -125,9 +131,15 @@ get_acq_order_done (MMAtSerialPort *port, const char *p; gint acqord = -1; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto done; + } p = mm_strip_tag (response->str, "+CNAOP:"); if (!p) { @@ -182,6 +194,11 @@ set_acq_order_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -198,8 +215,13 @@ set_mode_pref_done (MMAtSerialPort *port, guint32 naop; char *command; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } @@ -286,8 +308,13 @@ get_act_tech_done (MMAtSerialPort *port, MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } diff --git a/plugins/mm-modem-wavecom-gsm.c b/plugins/mm-modem-wavecom-gsm.c index 3c8a49b0..c66637cf 100644 --- a/plugins/mm-modem-wavecom-gsm.c +++ b/plugins/mm-modem-wavecom-gsm.c @@ -239,12 +239,19 @@ set_band_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; if (error) info->error = g_error_copy (error); - else + else { + MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + priv->current_bands = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "new-band")); + } mm_callback_info_schedule (info); } @@ -389,11 +396,16 @@ get_2g_band_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; if (error) info->error = g_error_copy (error); else { + MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); const gchar *p; guint32 mm_band = MM_MODEM_GSM_BAND_UNKNOWN; @@ -430,11 +442,16 @@ get_3g_band_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; if (error) info->error = g_error_copy (error); else { + MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); const gchar *p; guint mm_band = MM_MODEM_GSM_BAND_UNKNOWN; guint32 wavecom_band; @@ -516,6 +533,11 @@ get_access_technology_cb (MMAtSerialPort *port, MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const gchar *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { @@ -583,19 +605,26 @@ get_allowed_mode_cb (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + MMModemWavecomGsmPrivate *priv; gint read_mode = -1; gchar *mode_str = NULL; gchar *prefer_str = NULL; GRegex *r = NULL; GMatchInfo *match_info = NULL; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } + priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + /* Possible responses: * +WWSM: 0 (2G only) * +WWSM: 1 (3G only) @@ -706,12 +735,19 @@ set_allowed_mode_cb (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; if (error) info->error = g_error_copy (error); - else + else { + MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + priv->allowed_mode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "new-mode")); + } mm_callback_info_schedule (info); } @@ -813,17 +849,24 @@ set_highest_ms_class_cb (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); guint new_class; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { enable_complete (MM_GENERIC_GSM (info->modem), error, info); return; } new_class = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "new-class")); - if (new_class) + if (new_class) { + MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + priv->current_ms_class = new_class; + } /* All done without errors! */ mm_dbg ("[5/5] All done"); @@ -882,14 +925,21 @@ get_current_ms_class_cb (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + MMModemWavecomGsmPrivate *priv; const gchar *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { enable_complete (MM_GENERIC_GSM (info->modem), error, info); return; } + priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + p = mm_strip_tag (response->str, "+CGCLASS:"); if (strncmp (p, @@ -936,14 +986,21 @@ get_supported_ms_classes_cb (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemWavecomGsmPrivate *priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + MMModemWavecomGsmPrivate *priv; const gchar *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { enable_complete (MM_GENERIC_GSM (info->modem), error, info); return; } + priv = MM_MODEM_WAVECOM_GSM_GET_PRIVATE (info->modem); + /* Reset currently supported MS classes */ priv->supported_ms_classes = 0; @@ -996,6 +1053,11 @@ get_current_functionality_status_cb (MMAtSerialPort *port, const gchar *p; GError *inner_error; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { enable_complete (MM_GENERIC_GSM (info->modem), error, info); return; @@ -1027,6 +1089,11 @@ do_enable_power_up_done (MMGenericGsm *gsm, MMAtSerialPort *port; GError *inner_error = NULL; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { enable_complete (gsm, error, info); return; diff --git a/plugins/mm-modem-x22x-gsm.c b/plugins/mm-modem-x22x-gsm.c index ff232971..c5d65c0f 100644 --- a/plugins/mm-modem-x22x-gsm.c +++ b/plugins/mm-modem-x22x-gsm.c @@ -115,8 +115,14 @@ get_allowed_mode_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemGsmAllowedMode mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { parse_syssel_response (response, &mode, &info->error); mm_callback_info_set_result (info, GUINT_TO_POINTER (mode), NULL); } @@ -151,7 +157,14 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - info->error = mm_modem_check_removed (info->modem, error); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + mm_callback_info_schedule (info); } diff --git a/plugins/mm-modem-zte.c b/plugins/mm-modem-zte.c index e7387a05..4b7abafa 100644 --- a/plugins/mm-modem-zte.c +++ b/plugins/mm-modem-zte.c @@ -103,9 +103,15 @@ get_allowed_mode_done (MMAtSerialPort *port, GRegex *r = NULL; GMatchInfo *match_info; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto done; + } r = g_regex_new ("+ZSNT:\\s*(\\d),(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL); if (!r) { @@ -192,6 +198,11 @@ set_allowed_mode_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -260,6 +271,11 @@ get_act_request_done (MMAtSerialPort *port, MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { @@ -346,7 +362,14 @@ cpms_try_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMModemZtePrivate *priv = MM_MODEM_ZTE_GET_PRIVATE (info->modem); + MMModemZtePrivate *priv; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_MODEM_ZTE_GET_PRIVATE (info->modem); if (error && g_error_matches (error, MM_MOBILE_ERROR, MM_MOBILE_ERROR_SIM_BUSY)) { if (priv->cpms_tries++ < 4) { @@ -377,6 +400,11 @@ init_modem_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + mm_at_serial_port_queue_command (port, "E0", 5, NULL, NULL); /* Attempt to disable floods of "+ZUSIMR:2" unsolicited responses that @@ -417,8 +445,16 @@ pre_init_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemZte *self = MM_MODEM_ZTE (info->modem); - MMModemZtePrivate *priv = MM_MODEM_ZTE_GET_PRIVATE (self); + MMModemZte *self; + MMModemZtePrivate *priv; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_MODEM_ZTE (info->modem); + priv = MM_MODEM_ZTE_GET_PRIVATE (self); if (error) { /* Retry the init string one more time; the modem sometimes throws it away */ diff --git a/src/mm-callback-info.c b/src/mm-callback-info.c index 1986bb55..aa1f13ab 100644 --- a/src/mm-callback-info.c +++ b/src/mm-callback-info.c @@ -182,6 +182,14 @@ mm_callback_info_get_data (MMCallbackInfo *info, const char *key) return quark ? g_datalist_id_get_data (&info->qdata, quark) : NULL; } +gboolean +mm_callback_info_check_modem_removed (MMCallbackInfo *info) +{ + g_return_val_if_fail (info != NULL, TRUE); + + return (info->modem ? FALSE : TRUE); +} + MMCallbackInfo * mm_callback_info_ref (MMCallbackInfo *info) { diff --git a/src/mm-callback-info.h b/src/mm-callback-info.h index ef4d65fc..42d9908e 100644 --- a/src/mm-callback-info.h +++ b/src/mm-callback-info.h @@ -70,6 +70,8 @@ void mm_callback_info_set_data (MMCallbackInfo *info, gpointer mm_callback_info_get_data (MMCallbackInfo *info, const char *key); +gboolean mm_callback_info_check_modem_removed (MMCallbackInfo *info); + MMCallbackInfo *mm_callback_info_ref (MMCallbackInfo *info); void mm_callback_info_unref (MMCallbackInfo *info); diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index 0a95e7b1..378555b7 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -619,6 +619,11 @@ init_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { mm_modem_set_state (MM_MODEM (info->modem), MM_MODEM_STATE_DISABLED, @@ -699,10 +704,14 @@ disable_all_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (modem, error); - if (info->error) { - if (modem) - disable_set_previous_state (modem, info); + /* If the modem has already been removed, return without + * scheduling callback */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + disable_set_previous_state (modem, info); } else { MMGenericCdma *self = MM_GENERIC_CDMA (info->modem); MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); @@ -725,10 +734,15 @@ disable_flash_done (MMSerialPort *port, MMCallbackInfo *info = user_data; MMGenericCdma *self; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { - if (info->modem) - disable_set_previous_state (info->modem, info); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + + disable_set_previous_state (info->modem, info); mm_callback_info_schedule (info); return; } @@ -787,10 +801,14 @@ dial_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - 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); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + 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); @@ -831,15 +849,19 @@ disconnect_flash_done (MMSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; 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_CDMA_PREV_STATE_TAG)); - mm_modem_set_state (MM_MODEM (info->modem), - prev_state, - MM_MODEM_STATE_REASON_NONE); - } + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + + /* 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); @@ -929,6 +951,11 @@ get_signal_quality_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; char *reply = response->str; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { if (mm_callback_info_get_data (info, CSQ2_TRIED)) info->error = g_error_copy (error); @@ -1077,6 +1104,11 @@ get_string_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { @@ -1207,6 +1239,11 @@ serving_system_done (MMAtSerialPort *port, unsigned char band = 'Z'; gboolean success = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto out; @@ -1500,8 +1537,14 @@ subclass_reg_query_done (MMModemCdma *cdma, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { /* Set final registration state */ set_callback_1x_state_helper (info, cdma_reg_state); set_callback_evdo_state_helper (info, evdo_reg_state); @@ -1520,6 +1563,11 @@ reg_query_speri_done (MMAtSerialPort *port, gboolean roam = FALSE; const char *p; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) goto done; @@ -1559,6 +1607,11 @@ reg_query_spservice_done (MMAtSerialPort *port, MMModemCdmaRegistrationState cdma_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN; MMModemCdmaRegistrationState evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (mm_cdma_parse_spservice_response (response->str, &cdma_state, &evdo_state)) { @@ -1661,6 +1714,11 @@ get_analog_digital_done (MMAtSerialPort *port, const char *reply; long int int_cad; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto error; @@ -1994,7 +2052,7 @@ reg_state_changed (MMModemCdma *self, MMModemCdmaRegistrationState evdo_new_state, gpointer user_data) { -/* Disabled for now... changing the registration state from the +/* Disabled for now... changing the registration state from the * subclass' query_registration_state handler also emits the registration * state changed signal, which will call this function, and execute * simple_state_machine() to advance to the next state. Then however @@ -2030,9 +2088,14 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) const char *str; guint id; - info->error = mm_modem_check_removed (modem, error); - if (info->error) + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto out; + } switch (state) { case SIMPLE_STATE_BEGIN: @@ -2095,7 +2158,7 @@ simple_connect (MMModemSimple *simple, info = mm_callback_info_new (MM_MODEM (simple), callback, user_data); priv->simple_connect_info = info; - mm_callback_info_set_data (info, "simple-connect-properties", + mm_callback_info_set_data (info, "simple-connect-properties", g_hash_table_ref (properties), (GDestroyNotify) g_hash_table_unref); diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index b67cecff..bcc158e6 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -275,6 +275,11 @@ pin_check_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean parsed = FALSE; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (response && strstr (response->str, "+CPIN: ")) { @@ -513,6 +518,11 @@ real_get_iccid_done (MMAtSerialPort *port, gboolean success = FALSE; char buf[21], swapped[21]; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; @@ -1064,21 +1074,21 @@ cgreg1_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (info->modem) { - if (info->error) { - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; - g_clear_error (&info->error); + if (error) { + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); - /* The modem doesn't like unsolicited CGREG, so we'll need to poll */ - priv->cgreg_poll = TRUE; - } else - mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (1), NULL); + /* The modem doesn't like unsolicited CGREG, so we'll need to poll */ + priv->cgreg_poll = TRUE; + } else + mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (1), NULL); - /* Success; get initial state */ - mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem); - } + /* Success; get initial state */ + mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem); initial_unsolicited_reg_check_done (info); } @@ -1091,27 +1101,25 @@ cgreg2_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - /* Ignore errors except modem removal errors */ - info->error = mm_modem_check_removed (info->modem, error); - if (info->modem) { - if (info->error) { - g_clear_error (&info->error); - /* Try CGREG=1 instead */ - mm_at_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info); - } else { - add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; - mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (2), NULL); + /* Ignore errors */ + if (error) { + /* Try CGREG=1 instead */ + mm_at_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info); + } else { + add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI); - /* Success; get initial state */ - mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem); + mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (2), NULL); - /* All done */ - initial_unsolicited_reg_check_done (info); - } - } else { - /* Modem got removed */ - mm_callback_info_schedule (info); + /* Success; get initial state */ + mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem); + + /* All done */ + initial_unsolicited_reg_check_done (info); } } @@ -1122,28 +1130,26 @@ creg1_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; + MMGenericGsmPrivate *priv; - info->error = mm_modem_check_removed (info->modem, error); - if (info->modem) { - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; - if (info->error) { - g_clear_error (&info->error); + priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); - /* The modem doesn't like unsolicited CREG, so we'll need to poll */ - priv->creg_poll = TRUE; - } else - mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (1), NULL); + if (error) { + /* The modem doesn't like unsolicited CREG, so we'll need to poll */ + priv->creg_poll = TRUE; + } else + mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (1), NULL); - /* Success; get initial state */ - mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem); + /* Success; get initial state */ + mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem); - /* Now try to set up CGREG messages */ - mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info); - } else { - /* Modem got removed */ - mm_callback_info_schedule (info); - } + /* Now try to set up CGREG messages */ + mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info); } static void @@ -1154,26 +1160,24 @@ creg2_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - /* Ignore errors except modem removal errors */ - info->error = mm_modem_check_removed (info->modem, error); - if (info->modem) { - if (info->error) { - g_clear_error (&info->error); - mm_at_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info); - } else { - add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; - mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (2), NULL); + /* Ignore errors */ + if (error) + mm_at_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info); + else { + add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI); - /* Success; get initial state */ - mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem); + mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (2), NULL); - /* Now try to set up CGREG messages */ - mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info); - } - } else { - /* Modem got removed */ - mm_callback_info_schedule (info); + /* Success; get initial state */ + mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem); + + /* Now try to set up CGREG messages */ + mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info); } } @@ -1182,20 +1186,23 @@ enable_failed (MMModem *modem, GError *error, MMCallbackInfo *info) { MMGenericGsmPrivate *priv; - info->error = mm_modem_check_removed (modem, error); + /* If modem already removed, do nothing */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; - if (modem) { - mm_modem_set_state (modem, - MM_MODEM_STATE_DISABLED, - MM_MODEM_STATE_REASON_NONE); + if (error) + info->error = g_error_copy (error); - priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + mm_modem_set_state (modem, + MM_MODEM_STATE_DISABLED, + MM_MODEM_STATE_REASON_NONE); - if (priv->primary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary))) - mm_serial_port_close_force (MM_SERIAL_PORT (priv->primary)); - if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) - mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary)); - } + priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + + if (priv->primary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary))) + mm_serial_port_close_force (MM_SERIAL_PORT (priv->primary)); + if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) + mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary)); mm_callback_info_schedule (info); } @@ -1468,6 +1475,11 @@ enable_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + /* Let subclasses handle the power up command response/error; many devices * don't support +CFUN, but for those that do let them handle the error * correctly. @@ -1488,6 +1500,11 @@ init_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; char *cmd = NULL; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info); return; @@ -1590,8 +1607,14 @@ disable_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { MMGenericGsm *self = MM_GENERIC_GSM (info->modem); mm_serial_port_close_force (MM_SERIAL_PORT (port)); @@ -1623,15 +1646,19 @@ disable_flash_done (MMSerialPort *port, MMModemState prev_state; char *cmd = NULL; - 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); - } + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + + /* 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); mm_callback_info_schedule (info); return; @@ -1739,6 +1766,11 @@ get_string_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else @@ -1760,6 +1792,11 @@ get_mnc_length_done (MMAtSerialPort *port, char hex[51]; char *bin; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; @@ -2016,35 +2053,33 @@ static void pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + MMGenericGsmPrivate *priv; MMSerialPort *port; GError *saved_error; + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + /* Clear the pin check timeout to ensure that it won't ever get a * stale MMCallbackInfo if the modem got removed. We'll reschedule it here * anyway if needed. */ - if (info->modem) { - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); - - if (priv->pin_check_timeout) - g_source_remove (priv->pin_check_timeout); - priv->pin_check_timeout = 0; - } + if (priv->pin_check_timeout) + g_source_remove (priv->pin_check_timeout); + priv->pin_check_timeout = 0; - /* modem could have been removed before we get here, in which case - * 'modem' will be NULL. - */ - info->error = mm_modem_check_removed (modem, error); + /* Propagate the error to the info */ + if (error) + info->error = g_error_copy (error); /* If the modem wasn't removed, and the modem isn't ready yet, ask it for * the current PIN status a few times since some devices take a bit to fully * enable themselves after a SIM PIN/PUK unlock. */ - if ( info->modem - && info->error - && !g_error_matches (info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED)) { - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); - + if (info->error && !g_error_matches (info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED)) { if (priv->pin_check_tries < 4) { g_clear_error (&info->error); priv->pin_check_tries++; @@ -2055,13 +2090,13 @@ pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data) /* Otherwise, clean up and return the PIN check result */ port = mm_callback_info_get_data (info, PIN_PORT_TAG); - if (modem && port) + if (port) mm_serial_port_close (port); /* If we have a saved error from sending PIN/PUK, return that to callers */ saved_error = mm_callback_info_get_data (info, SAVED_ERROR_TAG); if (saved_error) { - if (info->modem && !mm_modem_base_get_unlock_required (MM_MODEM_BASE (info->modem))) { + if (!mm_modem_base_get_unlock_required (MM_MODEM_BASE (info->modem))) { /* Original unlock failed but the modem is actually unlocked, so * return success. Sometimes happens if the modem doesn't allow * CPIN="xxxx" when it's already unlocked and returns an error. @@ -2085,6 +2120,11 @@ send_puk_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { if (error->domain != MM_MOBILE_ERROR) { info->error = g_error_copy (error); @@ -2149,6 +2189,11 @@ send_pin_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { if (error->domain != MM_MOBILE_ERROR) { info->error = g_error_copy (error); @@ -2212,6 +2257,11 @@ enable_pin_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); mm_callback_info_schedule (info); @@ -2242,6 +2292,11 @@ change_pin_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); mm_callback_info_schedule (info); @@ -2734,11 +2789,19 @@ get_reg_status_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMGenericGsm *self = MM_GENERIC_GSM (info->modem); - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); + MMGenericGsm *self; + MMGenericGsmPrivate *priv; guint id; MMModemGsmNetworkRegStatus status; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + self = MM_GENERIC_GSM (info->modem); + priv = MM_GENERIC_GSM_GET_PRIVATE (self); + /* This function should only get called during the connect sequence when * polling for registration state, since explicit registration requests * from D-Bus clients are filled from the cached registration state. @@ -2806,10 +2869,17 @@ register_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + MMGenericGsmPrivate *priv; mm_callback_info_unref (info); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + /* If the registration timed out (and thus pending_reg_info will be NULL) * and the modem eventually got around to sending the response for the * registration request then just ignore the response since the callback is @@ -2986,6 +3056,11 @@ connect_report_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; GError *real_error; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + /* If the CEER command was successful, copy that error reason into the * callback's error. If not, use the original error. */ @@ -3015,7 +3090,14 @@ connect_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + MMGenericGsmPrivate *priv; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); if (error) { info->error = g_error_copy (error); @@ -3067,15 +3149,17 @@ disconnect_done (MMModem *modem, MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemState prev_state; - info->error = mm_modem_check_removed (modem, error); - if (info->error) { - if (info->modem && 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); - } + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + /* 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 (modem); MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); @@ -3094,7 +3178,14 @@ disconnect_all_done (MMAtSerialPort *port, GError *error, gpointer user_data) { - mm_callback_info_schedule ((MMCallbackInfo *) user_data); + MMCallbackInfo *info = (MMCallbackInfo *)user_data; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + mm_callback_info_schedule (info); } static void @@ -3126,17 +3217,21 @@ disconnect_flash_done (MMSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMGenericGsmPrivate *priv; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { /* Ignore "NO CARRIER" response when modem disconnects and any flash * failures we might encounter. Other errors are hard errors. */ - if ( !g_error_matches (info->error, MM_MODEM_CONNECT_ERROR, MM_MODEM_CONNECT_ERROR_NO_CARRIER) - && !g_error_matches (info->error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) { + if ( !g_error_matches (error, MM_MODEM_CONNECT_ERROR, MM_MODEM_CONNECT_ERROR_NO_CARRIER) + && !g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) { + info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } - g_clear_error (&info->error); } priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); @@ -3163,11 +3258,10 @@ disconnect_secondary_cgact_done (MMAtSerialPort *port, MMGenericGsm *self; MMGenericGsmPrivate *priv; - if (!info->modem) { - info->error = mm_modem_check_removed (info->modem, error); - mm_callback_info_schedule (info); + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) return; - } self = MM_GENERIC_GSM (info->modem); priv = MM_GENERIC_GSM_GET_PRIVATE (self); @@ -3257,6 +3351,11 @@ scan_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; GPtrArray *results; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { @@ -3296,8 +3395,14 @@ set_apn_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); priv->cid = GPOINTER_TO_INT (mm_callback_info_get_data (info, APN_CID_TAG)); @@ -3315,6 +3420,11 @@ cid_range_read (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; guint32 cid = 0; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else if (g_str_has_prefix (response->str, "+CGDCONT:")) { @@ -3381,10 +3491,14 @@ existing_apns_read (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean found = FALSE; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) - goto done; - else if (g_str_has_prefix (response->str, "+CGDCONT:")) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); + } else if (g_str_has_prefix (response->str, "+CGDCONT:")) { GRegex *r; GMatchInfo *match_info; @@ -3435,7 +3549,6 @@ existing_apns_read (MMAtSerialPort *port, MM_MODEM_ERROR_GENERAL, "Could not parse the response"); -done: if (found || info->error) mm_callback_info_schedule (info); else { @@ -3542,8 +3655,14 @@ get_cind_signal_done (MMAtSerialPort *port, GByteArray *indicators; guint quality; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); indicators = mm_parse_cind_query_response (response->str, &info->error); @@ -3571,9 +3690,15 @@ get_csq_done (MMAtSerialPort *port, char *reply = response->str; gboolean parsed = FALSE; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto done; + } if (!strncmp (reply, "+CSQ: ", 6)) { /* Got valid reply */ @@ -3721,8 +3846,13 @@ set_allowed_mode_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { MMModemGsmAllowedMode mode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "mode")); mm_generic_gsm_update_allowed_mode (MM_GENERIC_GSM (info->modem), mode); @@ -3777,8 +3907,13 @@ get_charsets_done (MMAtSerialPort *port, MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMGenericGsmPrivate *priv; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } @@ -3836,8 +3971,13 @@ set_get_charset_done (MMAtSerialPort *port, MMModemCharset tried_charset; const char *p; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } @@ -3873,13 +4013,18 @@ set_charset_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - info->error = mm_modem_check_removed (info->modem, error); - if (info->error) { + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) { gboolean tried_no_quotes = !!mm_callback_info_get_data (info, TRIED_NO_QUOTES_TAG); MMModemCharset charset = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "charset")); char *command; - if (!info->modem || tried_no_quotes) { + if (tried_no_quotes) { + info->error = g_error_copy (error); mm_callback_info_schedule (info); return; } @@ -3992,6 +4137,11 @@ sms_send_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -4253,6 +4403,11 @@ sms_get_done (MMAtSerialPort *port, int rv, status, tpdu_len, offset; char pdu[SMS_MAX_PDU_LEN + 1]; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto out; @@ -4327,6 +4482,11 @@ sms_delete_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); @@ -4368,6 +4528,11 @@ sms_list_done (MMAtSerialPort *port, int rv, status, tpdu_len, offset; char *rstr; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); else { @@ -4506,6 +4671,11 @@ ussd_send_done (MMAtSerialPort *port, const char *str, *start = NULL, *end = NULL; char *reply = NULL, *converted; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) { info->error = g_error_copy (error); goto done; @@ -4664,13 +4834,17 @@ ussd_cancel_done (MMAtSerialPort *port, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + if (error) info->error = g_error_copy (error); mm_callback_info_schedule (info); - if (info->modem) - ussd_update_state (MM_GENERIC_GSM (info->modem), MM_MODEM_GSM_USSD_STATE_IDLE); + ussd_update_state (MM_GENERIC_GSM (info->modem), MM_MODEM_GSM_USSD_STATE_IDLE); } static void @@ -4828,9 +5002,14 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) gboolean home_only = FALSE; char *data_device; - info->error = mm_modem_check_removed (modem, error); - if (info->error) + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) { + info->error = g_error_copy (error); goto out; + } priv = MM_GENERIC_GSM_GET_PRIVATE (modem); @@ -5047,8 +5226,13 @@ simple_status_got_reg_info (MMModemGsmNetwork *modem, MMCallbackInfo *info = (MMCallbackInfo *) user_data; GHashTable *properties; - info->error = mm_modem_check_removed ((MMModem *) modem, error); - if (!info->error) { + /* Do nothing if modem removed */ + if (!modem || mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { properties = (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG); g_hash_table_insert (properties, "registration_status", simple_uint_value (status)); diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c index 9afc1bf9..451e2ebe 100644 --- a/src/mm-modem-base.c +++ b/src/mm-modem-base.c @@ -493,15 +493,17 @@ info_item_done (MMCallbackInfo *info, mm_callback_info_chain_complete_one (info); } -#define GET_INFO_RESP_FN(func_name, tag, tag2, desc) \ -static void \ -func_name (MMAtSerialPort *port, \ - GString *response, \ - GError *error, \ - gpointer user_data) \ -{ \ - info_item_done ((MMCallbackInfo *) user_data, response, error, tag, tag2, desc ); \ -} +#define GET_INFO_RESP_FN(func_name, tag, tag2, desc) \ + static void \ + func_name (MMAtSerialPort *port, \ + GString *response, \ + GError *error, \ + gpointer user_data) \ + { \ + if (mm_callback_info_check_modem_removed ((MMCallbackInfo *) user_data)) \ + return; \ + info_item_done ((MMCallbackInfo *) user_data, response, error, tag, tag2, desc ); \ + } GET_INFO_RESP_FN(get_revision_done, "+GMR:", "AT+GMR", "card-info-revision") GET_INFO_RESP_FN(get_model_done, "+GMM:", "AT+GMM", "card-info-model") diff --git a/src/mm-modem.c b/src/mm-modem.c index d5351660..b3c1677d 100644 --- a/src/mm-modem.c +++ b/src/mm-modem.c @@ -33,25 +33,6 @@ static void impl_modem_factory_reset (MMModem *modem, const char *code, DBusGMet #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 (!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 error ? g_error_copy (error) : NULL; -} - static void async_op_not_supported (MMModem *self, MMModemFn callback, diff --git a/src/mm-modem.h b/src/mm-modem.h index c478f701..45f81103 100644 --- a/src/mm-modem.h +++ b/src/mm-modem.h @@ -282,8 +282,6 @@ void mm_modem_set_state (MMModem *self, MMModemState new_state, MMModemStateReason reason); -GError *mm_modem_check_removed (MMModem *self, const GError *error); - /* Request authorization to perform an action. Used by D-Bus method * handlers to ensure that the incoming request is authorized to perform * the action it's requesting. |