aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-serial-port.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
index ced0f534..250e00be 100644
--- a/src/mm-serial-port.c
+++ b/src/mm-serial-port.c
@@ -79,6 +79,7 @@ typedef struct {
guint timeout_id;
guint flash_id;
+ guint connected_id;
} MMSerialPortPrivate;
#if 0
@@ -741,6 +742,35 @@ data_available (GIOChannel *source,
return TRUE;
}
+static void
+port_connected (MMSerialPort *self, GParamSpec *pspec, gpointer user_data)
+{
+ MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
+ gboolean connected;
+
+ if (priv->fd < 0)
+ return;
+
+ /* When the port is connected, drop the serial port lock so PPP can do
+ * something with the port. When the port is disconnected, grab the lock
+ * again.
+ */
+ connected = mm_port_get_connected (MM_PORT (self));
+
+ if (ioctl (priv->fd, (connected ? TIOCNXCL : TIOCEXCL)) < 0) {
+ g_warning ("%s: (%s) could not %s serial port lock: (%d) %s",
+ __func__,
+ mm_port_get_device (MM_PORT (self)),
+ connected ? "drop" : "re-acquire",
+ errno,
+ strerror (errno));
+ if (!connected) {
+ // FIXME: do something here, maybe try again in a few seconds or
+ // close the port and error out?
+ }
+ }
+}
+
gboolean
mm_serial_port_open (MMSerialPort *self, GError **error)
{
@@ -752,9 +782,10 @@ mm_serial_port_open (MMSerialPort *self, GError **error)
priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- if (priv->fd >= 0)
+ if (priv->fd >= 0) {
/* Already open */
return TRUE;
+ }
device = mm_port_get_device (MM_PORT (self));
@@ -797,6 +828,10 @@ mm_serial_port_open (MMSerialPort *self, GError **error)
G_IO_IN | G_IO_ERR | G_IO_HUP,
data_available, self);
+ g_warn_if_fail (priv->connected_id == 0);
+ priv->connected_id = g_signal_connect (self, "notify::" MM_PORT_CONNECTED,
+ G_CALLBACK (port_connected), NULL);
+
return TRUE;
}
@@ -809,6 +844,11 @@ mm_serial_port_close (MMSerialPort *self)
priv = MM_SERIAL_PORT_GET_PRIVATE (self);
+ if (priv->connected_id) {
+ g_signal_handler_disconnect (self, priv->connected_id);
+ priv->connected_id = 0;
+ }
+
if (priv->fd >= 0) {
g_message ("(%s) closing serial device...", mm_port_get_device (MM_PORT (self)));
@@ -1046,37 +1086,6 @@ mm_serial_port_flash_cancel (MMSerialPort *self)
/*****************************************************************************/
-static void
-port_connected (MMSerialPort *self, GParamSpec *pspec, gpointer user_data)
-{
- MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- gboolean connected;
-
- if (priv->fd < 0)
- return;
-
- /* When the port is connected, drop the serial port lock so PPP can do
- * something with the port. When the port is disconnected, grab the lock
- * again.
- */
- connected = mm_port_get_connected (MM_PORT (self));
-
- if (ioctl (priv->fd, (connected ? TIOCNXCL : TIOCEXCL)) < 0) {
- g_warning ("%s: (%s) could not %s serial port lock: (%d) %s",
- __func__,
- mm_port_get_device (MM_PORT (self)),
- connected ? "drop" : "re-acquire",
- errno,
- strerror (errno));
- if (!connected) {
- // FIXME: do something here, maybe try again in a few seconds or
- // close the port and error out?
- }
- }
-}
-
-/*****************************************************************************/
-
MMSerialPort *
mm_serial_port_new (const char *name, MMPortType ptype)
{
@@ -1104,8 +1113,6 @@ mm_serial_port_init (MMSerialPort *self)
priv->queue = g_queue_new ();
priv->command = g_string_new_len ("AT", SERIAL_BUF_SIZE);
priv->response = g_string_sized_new (SERIAL_BUF_SIZE);
-
- g_signal_connect (self, "notify::" MM_PORT_CONNECTED, G_CALLBACK (port_connected), NULL);
}
static void
@@ -1165,13 +1172,19 @@ get_property (GObject *object, guint prop_id,
}
static void
+dispose (GObject *object)
+{
+ mm_serial_port_close (MM_SERIAL_PORT (object));
+
+ G_OBJECT_CLASS (mm_serial_port_parent_class)->dispose (object);
+}
+
+static void
finalize (GObject *object)
{
MMSerialPort *self = MM_SERIAL_PORT (object);
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- mm_serial_port_close (self);
-
g_hash_table_destroy (priv->reply_cache);
g_queue_free (priv->queue);
g_string_free (priv->command, TRUE);
@@ -1205,6 +1218,7 @@ mm_serial_port_class_init (MMSerialPortClass *klass)
/* Virtual methods */
object_class->set_property = set_property;
object_class->get_property = get_property;
+ object_class->dispose = dispose;
object_class->finalize = finalize;
/* Properties */