summaryrefslogtreecommitdiff
authorAleksander Morgado <aleksander@lanedo.com>2012-11-30 13:03:31 (GMT)
committer Aleksander Morgado <aleksander@lanedo.com>2012-12-12 11:56:47 (GMT)
commitdc9bbefbc083a328fad0b770d1e716e704c72c65 (patch) (side-by-side diff)
tree1a4dc17a08e8add583225cddc30856071f822a19
parentf20922ba9d766bfbb198a3c2e41981b4d9473cfa (diff)
downloadModemManager-dc9bbefbc083a328fad0b770d1e716e704c72c65.zip
ModemManager-dc9bbefbc083a328fad0b770d1e716e704c72c65.tar.gz
icera,hso: don't wait to get connected if the primary port is removed
If the primary port is gone (e.g. when going to sleep) and we are just in the middle of a connection attempt, we won't be able to receive any unsolicited message regarding the status of the attempt. So, if we detect that the port is forced to get closed, we'll just treat it as a connection failure. http://code.google.com/p/chromium-os/issues/detail?id=35391
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--plugins/icera/mm-broadband-bearer-icera.c30
-rw-r--r--plugins/option/mm-broadband-bearer-hso.c28
-rw-r--r--src/mm-serial-port.c13
-rw-r--r--src/mm-serial-port.h1
4 files changed, 71 insertions, 1 deletions
diff --git a/plugins/icera/mm-broadband-bearer-icera.c b/plugins/icera/mm-broadband-bearer-icera.c
index 7dce685..589bdc4 100644
--- a/plugins/icera/mm-broadband-bearer-icera.c
+++ b/plugins/icera/mm-broadband-bearer-icera.c
@@ -50,6 +50,7 @@ struct _MMBroadbandBearerIceraPrivate {
gpointer connect_pending;
guint connect_pending_id;
gulong connect_cancellable_id;
+ gulong connect_port_closed_id;
/* Disconnection related */
gpointer disconnect_pending;
@@ -624,6 +625,12 @@ connect_timed_out_cb (MMBroadbandBearerIcera *self)
self->priv->connect_cancellable_id = 0;
}
+ /* Remove closed port watch, if found */
+ if (ctx && self->priv->connect_port_closed_id) {
+ g_signal_handler_disconnect (ctx->primary, self->priv->connect_port_closed_id);
+ self->priv->connect_port_closed_id = 0;
+ }
+
/* Cleanup timeout ID */
self->priv->connect_pending_id = 0;
@@ -665,6 +672,16 @@ connect_cancelled_cb (GCancellable *cancellable,
}
static void
+forced_close_cb (MMSerialPort *port,
+ MMBroadbandBearerIcera *self)
+{
+ /* Just treat the forced close event as any other unsolicited message */
+ mm_broadband_bearer_icera_report_connection_status (
+ self,
+ MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED);
+}
+
+static void
ier_query_ready (MMBaseModem *modem,
GAsyncResult *res,
Dial3gppContext *ctx)
@@ -708,7 +725,7 @@ report_connect_status (MMBroadbandBearerIcera *self,
ctx = self->priv->connect_pending;
self->priv->connect_pending = NULL;
- /* Cleanup cancellable and timeout, if any */
+ /* Cleanup cancellable, timeout and port closed watch, if any */
if (self->priv->connect_pending_id) {
g_source_remove (self->priv->connect_pending_id);
self->priv->connect_pending_id = 0;
@@ -720,6 +737,11 @@ report_connect_status (MMBroadbandBearerIcera *self,
self->priv->connect_cancellable_id = 0;
}
+ if (ctx && self->priv->connect_port_closed_id) {
+ g_signal_handler_disconnect (ctx->primary, self->priv->connect_port_closed_id);
+ self->priv->connect_port_closed_id = 0;
+ }
+
switch (status) {
case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN:
break;
@@ -845,6 +867,12 @@ activate_ready (MMBaseModem *modem,
G_CALLBACK (connect_cancelled_cb),
self,
NULL);
+
+ /* If we get the port closed, we treat as a connect error */
+ self->priv->connect_port_closed_id = g_signal_connect (ctx->primary,
+ "forced-close",
+ G_CALLBACK (forced_close_cb),
+ self);
}
static void
diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c
index 0db9dac..0685881 100644
--- a/plugins/option/mm-broadband-bearer-hso.c
+++ b/plugins/option/mm-broadband-bearer-hso.c
@@ -40,6 +40,7 @@ struct _MMBroadbandBearerHsoPrivate {
gpointer connect_pending;
guint connect_pending_id;
gulong connect_cancellable_id;
+ gulong connect_port_closed_id;
};
/*****************************************************************************/
@@ -372,6 +373,11 @@ mm_broadband_bearer_hso_report_connection_status (MMBroadbandBearerHso *self,
self->priv->connect_cancellable_id = 0;
}
+ if (ctx && self->priv->connect_port_closed_id) {
+ g_signal_handler_disconnect (ctx->primary, self->priv->connect_port_closed_id);
+ self->priv->connect_port_closed_id = 0;
+ }
+
switch (status) {
case MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_UNKNOWN:
break;
@@ -461,6 +467,12 @@ connect_timed_out_cb (MMBroadbandBearerHso *self)
self->priv->connect_cancellable_id = 0;
}
+ /* Remove closed port watch, if found */
+ if (ctx && self->priv->connect_port_closed_id) {
+ g_signal_handler_disconnect (ctx->primary, self->priv->connect_port_closed_id);
+ self->priv->connect_port_closed_id = 0;
+ }
+
/* Cleanup timeout ID */
self->priv->connect_pending_id = 0;
@@ -505,6 +517,16 @@ connect_cancelled_cb (GCancellable *cancellable,
}
static void
+forced_close_cb (MMSerialPort *port,
+ MMBroadbandBearerHso *self)
+{
+ /* Just treat the forced close event as any other unsolicited message */
+ mm_broadband_bearer_hso_report_connection_status (
+ self,
+ MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTION_FAILED);
+}
+
+static void
activate_ready (MMBaseModem *modem,
GAsyncResult *res,
MMBroadbandBearerHso *self)
@@ -546,6 +568,12 @@ activate_ready (MMBaseModem *modem,
G_CALLBACK (connect_cancelled_cb),
self,
NULL);
+
+ /* If we get the port closed, we treat as a connect error */
+ self->priv->connect_port_closed_id = g_signal_connect (ctx->primary,
+ "forced-close",
+ G_CALLBACK (forced_close_cb),
+ self);
}
static void authenticate (Dial3gppContext *ctx);
diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
index 04cac88..87f06e2 100644
--- a/src/mm-serial-port.c
+++ b/src/mm-serial-port.c
@@ -57,6 +57,7 @@ enum {
enum {
BUFFER_FULL,
TIMED_OUT,
+ FORCED_CLOSE,
LAST_SIGNAL
};
@@ -1093,6 +1094,9 @@ mm_serial_port_close_force (MMSerialPort *self)
/* Mark as having forced the close, so that we don't warn about incorrect
* open counts */
priv->forced_close = TRUE;
+
+ /* Notify about the forced close status */
+ g_signal_emit (self, signals[FORCED_CLOSE], 0);
}
static void
@@ -1670,4 +1674,13 @@ mm_serial_port_class_init (MMSerialPortClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ signals[FORCED_CLOSE] =
+ g_signal_new ("forced-close",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (MMSerialPortClass, forced_close),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
diff --git a/src/mm-serial-port.h b/src/mm-serial-port.h
index 77db321..31cd5a7 100644
--- a/src/mm-serial-port.h
+++ b/src/mm-serial-port.h
@@ -100,6 +100,7 @@ struct _MMSerialPortClass {
/* Signals */
void (*buffer_full) (MMSerialPort *port, const GByteArray *buffer);
void (*timed_out) (MMSerialPort *port, guint n_consecutive_replies);
+ void (*forced_close) (MMSerialPort *port);
};
GType mm_serial_port_get_type (void);