aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2011-06-20 11:43:41 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-02-17 13:25:03 +0100
commit8b1016f4e1de4f058ce93c4dec1438cf8138317e (patch)
treea3cc8e5130b882061126f4992d6a77129526d60e /plugins
parentd52b38b1f2ecdac84620d62c3fc0c8a5aa2ed496 (diff)
iridium: close and open the port during disconnection
The Iridium modem doesn't seem to like only the port flashing during the disconnection, so we fully close and open again the port.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mm-modem-iridium-gsm.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/plugins/mm-modem-iridium-gsm.c b/plugins/mm-modem-iridium-gsm.c
index 03637d0a..a5c2b0d0 100644
--- a/plugins/mm-modem-iridium-gsm.c
+++ b/plugins/mm-modem-iridium-gsm.c
@@ -184,6 +184,78 @@ do_enable (MMGenericGsm *modem, MMModemFn callback, gpointer user_data)
}
static void
+disconnect_flash_done (MMSerialPort *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;
+
+ 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 (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;
+ }
+ }
+
+ /* Send ATE0 after reopening, and continue */
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "E0", 3, NULL, NULL);
+ mm_callback_info_schedule (info);
+}
+
+static gboolean
+after_disconnect_sleep_cb (gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *)user_data;
+ MMAtSerialPort *primary;
+ GError *error = NULL;
+
+ /* If the modem has already been removed, return without
+ * scheduling callback */
+ if (mm_callback_info_check_modem_removed (info))
+ return FALSE;
+
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (info->modem), MM_PORT_TYPE_PRIMARY);
+ g_assert (primary);
+
+ /* Propagate errors when reopening the port */
+ if (!mm_serial_port_open (MM_SERIAL_PORT (primary), &error)) {
+ info->error = g_error_copy (error);
+ mm_callback_info_schedule (info);
+ }
+
+ mm_serial_port_flash (MM_SERIAL_PORT (primary), 1000, TRUE, disconnect_flash_done, info);
+ return FALSE;
+}
+
+static void
+do_disconnect (MMGenericGsm *gsm,
+ gint cid,
+ MMModemFn callback,
+ gpointer user_data)
+{
+ MMCallbackInfo *info;
+ MMAtSerialPort *primary;
+
+ info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data);
+
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
+ g_assert (primary);
+
+ /* Close the serial port and wait some seconds before reopening it */
+ mm_serial_port_close (MM_SERIAL_PORT (primary));
+ mm_dbg ("Waiting some seconds before reopening the port...");
+ g_timeout_add_seconds (5, after_disconnect_sleep_cb, info);
+}
+
+static void
set_allowed_mode (MMGenericGsm *gsm,
MMModemGsmAllowedMode mode,
MMModemFn callback,
@@ -450,6 +522,7 @@ mm_modem_iridium_gsm_class_init (MMModemIridiumGsmClass *klass)
MM_GENERIC_GSM_PS_NETWORK_SUPPORTED);
gsm_class->do_enable = do_enable;
+ gsm_class->do_disconnect = do_disconnect;
gsm_class->get_access_technology = get_access_technology;
gsm_class->set_allowed_mode = set_allowed_mode;
gsm_class->get_allowed_mode = get_allowed_mode;