diff options
Diffstat (limited to 'src/mm-generic-gsm.c')
-rw-r--r-- | src/mm-generic-gsm.c | 170 |
1 files changed, 115 insertions, 55 deletions
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index f9f87657..d351aca2 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -398,6 +398,29 @@ release_port (MMModem *modem, const char *subsys, const char *name) check_valid (MM_GENERIC_GSM (modem)); } +void +mm_generic_gsm_enable_complete (MMGenericGsm *modem, + GError *error, + MMCallbackInfo *info) +{ + g_return_if_fail (modem != NULL); + g_return_if_fail (MM_IS_GENERIC_GSM (modem)); + g_return_if_fail (info != NULL); + + if (error) { + mm_modem_set_state (MM_MODEM (modem), + MM_MODEM_STATE_DISABLED, + MM_MODEM_STATE_REASON_NONE); + + info->error = g_error_copy (error); + } else { + /* Modem is enabled; update the state */ + mm_generic_gsm_update_enabled_state (modem, FALSE, MM_MODEM_STATE_REASON_NONE); + } + + mm_callback_info_schedule (info); +} + static void enable_done (MMSerialPort *port, GString *response, @@ -415,11 +438,7 @@ enable_done (MMSerialPort *port, * errors or ignore them. */ - mm_generic_gsm_update_enabled_state (MM_GENERIC_GSM (info->modem), - FALSE, - MM_MODEM_STATE_REASON_NONE); - - mm_callback_info_schedule (info); + mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), NULL, info); } static void @@ -432,34 +451,30 @@ init_done (MMSerialPort *port, char *cmd = NULL; if (error) { - mm_modem_set_state (MM_MODEM (info->modem), - MM_MODEM_STATE_DISABLED, - MM_MODEM_STATE_REASON_NONE); + mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info); + return; + } - info->error = g_error_copy (error); - mm_callback_info_schedule (info); - } else { - /* Ensure echo is off after the init command; some modems ignore the - * E0 when it's in the same like as ATZ (Option GIO322). - */ - mm_serial_port_queue_command (port, "E0 +CMEE=1", 2, NULL, NULL); + /* Ensure echo is off after the init command; some modems ignore the + * E0 when it's in the same like as ATZ (Option GIO322). + */ + mm_serial_port_queue_command (port, "E0 +CMEE=1", 2, NULL, NULL); - g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_INIT_CMD_OPTIONAL, &cmd, NULL); - mm_serial_port_queue_command (port, cmd, 2, NULL, NULL); - g_free (cmd); + g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_INIT_CMD_OPTIONAL, &cmd, NULL); + mm_serial_port_queue_command (port, cmd, 2, NULL, NULL); + g_free (cmd); - if (MM_GENERIC_GSM_GET_PRIVATE (info->modem)->unsolicited_registration) - mm_serial_port_queue_command (port, "+CREG=1", 5, NULL, NULL); - else - mm_serial_port_queue_command (port, "+CREG=0", 5, NULL, NULL); + if (MM_GENERIC_GSM_GET_PRIVATE (info->modem)->unsolicited_registration) + mm_serial_port_queue_command (port, "+CREG=1", 5, NULL, NULL); + else + mm_serial_port_queue_command (port, "+CREG=0", 5, NULL, NULL); - g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_POWER_UP_CMD, &cmd, NULL); - if (cmd && strlen (cmd)) - mm_serial_port_queue_command (port, cmd, 5, enable_done, user_data); - else - enable_done (port, NULL, NULL, user_data); - g_free (cmd); - } + g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_POWER_UP_CMD, &cmd, NULL); + if (cmd && strlen (cmd)) + mm_serial_port_queue_command (port, cmd, 5, enable_done, user_data); + else + enable_done (port, NULL, NULL, user_data); + g_free (cmd); } static void @@ -469,12 +484,7 @@ enable_flash_done (MMSerialPort *port, GError *error, gpointer user_data) char *cmd = NULL; if (error) { - mm_modem_set_state (MM_MODEM (info->modem), - MM_MODEM_STATE_DISABLED, - MM_MODEM_STATE_REASON_NONE); - - info->error = g_error_copy (error); - mm_callback_info_schedule (info); + mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info); return; } @@ -484,29 +494,40 @@ enable_flash_done (MMSerialPort *port, GError *error, gpointer user_data) } static void +real_do_enable (MMGenericGsm *self, MMModemFn callback, gpointer user_data) +{ + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); + MMCallbackInfo *info; + + info = mm_callback_info_new (MM_MODEM (self), callback, user_data); + mm_serial_port_flash (priv->primary, 100, enable_flash_done, info); +} + +static void enable (MMModem *modem, MMModemFn callback, gpointer user_data) { MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem); - MMCallbackInfo *info; + GError *error = NULL; /* First, reset the previously used CID */ mm_generic_gsm_set_cid (MM_GENERIC_GSM (modem), 0); - info = mm_callback_info_new (modem, callback, user_data); + if (!mm_serial_port_open (priv->primary, &error)) { + MMCallbackInfo *info; - if (!mm_serial_port_open (priv->primary, &info->error)) { - g_assert (info->error); + g_assert (error); + info = mm_callback_info_new (modem, callback, user_data); + info->error = error; mm_callback_info_schedule (info); return; } - mm_modem_set_state (MM_MODEM (info->modem), - MM_MODEM_STATE_ENABLING, - MM_MODEM_STATE_REASON_NONE); + mm_modem_set_state (modem, MM_MODEM_STATE_ENABLING, MM_MODEM_STATE_REASON_NONE); - mm_serial_port_flash (priv->primary, 100, enable_flash_done, info); + g_assert (MM_GENERIC_GSM_GET_CLASS (modem)->do_enable); + MM_GENERIC_GSM_GET_CLASS (modem)->do_enable (MM_GENERIC_GSM (modem), callback, user_data); } static void @@ -1190,6 +1211,33 @@ get_registration_info (MMModemGsmNetwork *self, mm_callback_info_schedule (info); } +void +mm_generic_gsm_connect_complete (MMGenericGsm *modem, + GError *error, + MMCallbackInfo *info) +{ + MMGenericGsmPrivate *priv; + + g_return_if_fail (modem != NULL); + g_return_if_fail (MM_IS_GENERIC_GSM (modem)); + g_return_if_fail (info != NULL); + + priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + + if (error) { + mm_generic_gsm_update_enabled_state (modem, FALSE, MM_MODEM_STATE_REASON_NONE); + info->error = g_error_copy (error); + } else { + /* Modem is connected; update the state */ + mm_port_set_connected (priv->data, TRUE); + mm_modem_set_state (MM_MODEM (modem), + MM_MODEM_STATE_CONNECTED, + MM_MODEM_STATE_REASON_NONE); + } + + mm_callback_info_schedule (info); +} + static void connect_report_done (MMSerialPort *port, GString *response, @@ -1197,14 +1245,28 @@ connect_report_done (MMSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + GError *real_error; + + /* If the CEER command was successful, copy that error reason into the + * callback's error. If not, use the original error. + */ - if (!error && g_str_has_prefix (response->str, "+CEER: ")) { - g_free (info->error->message); - info->error->message = g_strdup (response->str + 7); /* skip the "+CEER: " */ + /* Have to do this little dance since mm_generic_gsm_connect_complete() + * copies the provided error into the callback info. + */ + real_error = info->error; + info->error = NULL; + + if ( !error + && g_str_has_prefix (response->str, "+CEER: ") + && (strlen (response->str) > 7)) { + /* copy the connect failure reason into the error */ + g_free (real_error->message); + real_error->message = g_strdup (response->str + 7); /* skip the "+CEER: " */ } - - mm_generic_gsm_update_enabled_state (MM_GENERIC_GSM (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE); - mm_callback_info_schedule (info); + + mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), real_error, info); + g_error_free (real_error); } static void @@ -1221,12 +1283,8 @@ connect_done (MMSerialPort *port, /* Try to get more information why it failed */ priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); mm_serial_port_queue_command (priv->primary, "+CEER", 3, connect_report_done, info); - } else { - /* Done */ - mm_port_set_connected (priv->data, TRUE); - mm_modem_set_state (info->modem, MM_MODEM_STATE_CONNECTED, MM_MODEM_STATE_REASON_NONE); - mm_callback_info_schedule (info); - } + } else + mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), NULL, info); } static void @@ -2155,6 +2213,8 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; + klass->do_enable = real_do_enable; + /* Properties */ g_object_class_override_property (object_class, MM_MODEM_PROP_DATA_DEVICE, |