[moserial] detect detached serial device, bug 791872



commit 35e5942c008f127d771bddbe61ccc714ca53fab6
Author: Michael J. Chudobiak <mjc avtechpulse com>
Date:   Mon Jan 18 15:23:35 2021 -0500

     detect detached serial device, bug 791872

 src/MainWindow.vala       | 19 +++++++++++++++++++
 src/SerialConnection.vala | 24 +++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 1 deletion(-)
---
diff --git a/src/MainWindow.vala b/src/MainWindow.vala
index 1a67d32..a05eaf7 100644
--- a/src/MainWindow.vala
+++ b/src/MainWindow.vala
@@ -866,6 +866,7 @@ font-weight:
         statusbar.pop (statusbarContext);
         statusbar.push (statusbarContext, currentSettings.getStatusbarString (true));
         serialConnection.newData.connect (this.updateIncoming);
+        serialConnection.onError.connect(this.connectionError);
         connectButton.set_label_widget (disconnectLabel);
         return true;
     }
@@ -878,6 +879,7 @@ font-weight:
             settingsButton.set_sensitive (true);
             serialConnection.doDisconnect ();
             serialConnection.newData.disconnect (this.updateIncoming);
+            serialConnection.onError.disconnect(this.connectionError);
             bytecountbar.pop (bytecountbarContext);
             bytecountbar.push (bytecountbarContext, serialConnection.getBytecountbarString ());
             statusbar.pop (statusbarContext);
@@ -907,6 +909,23 @@ font-weight:
         return true;
     }
 
+    private void connectionError()
+    {
+        settingsButton.set_sensitive(true);
+        serialConnection.doDisconnect();
+        serialConnection.newData.disconnect(this.updateIncoming);
+        serialConnection.onError.disconnect(this.connectionError);
+        bytecountbar.pop(bytecountbarContext);
+        bytecountbar.push(bytecountbarContext, serialConnection.getBytecountbarString());
+        statusbar.pop(statusbarContext);
+        statusbar.push(statusbarContext, currentSettings.getStatusbarString(false));
+        connectButton.set_label_widget(connectLabel);
+        connectButton.set_active(false);
+
+        if (recordButton.get_active())
+            recordButton.set_active(false);
+    }
+
     private void updateIncoming (SerialConnection sc, uchar[] data, int size)
     {
         if (rz.running) {
diff --git a/src/SerialConnection.vala b/src/SerialConnection.vala
index 0fa662f..7011c04 100644
--- a/src/SerialConnection.vala
+++ b/src/SerialConnection.vala
@@ -36,6 +36,7 @@ public class moserial.SerialConnection : GLib.Object
     private int m_fd = -1;
     private GLib.IOChannel IOChannelFd;
     public signal void newData (uchar[] data, int size);
+    public signal void onError();
 
     private int flags = 0;
 
@@ -52,6 +53,9 @@ public class moserial.SerialConnection : GLib.Object
 
 
     uint ? sourceId;
+    uint? sourceIdErr;
+    uint? sourceIdHup;
+    uint? sourceIdNval;
     bool localEcho;
     public bool doConnect (Settings settings)
     {
@@ -78,6 +82,12 @@ public class moserial.SerialConnection : GLib.Object
 
         IOChannelFd = new GLib.IOChannel.unix_new (m_fd);
         sourceId = IOChannelFd.add_watch (GLib.IOCondition.IN, this.readBytes);
+        // G_IO_ERR is sometimes faster than G_IO_HUP when device is unplugged
+        sourceIdErr = IOChannelFd.add_watch(GLib.IOCondition.ERR, this.onUnplugged);
+        // G_IO_HUP is received when the serial port vanishes (unplugged USB)
+        sourceIdHup = IOChannelFd.add_watch(GLib.IOCondition.HUP, this.onUnplugged);
+        // G_IO_NVAL is the last resort when device is unplugged and you want to write
+        sourceIdNval = IOChannelFd.add_watch(GLib.IOCondition.NVAL, this.onUnplugged);
         localEcho = settings.localEcho;
         return true;
     }
@@ -106,8 +116,14 @@ public class moserial.SerialConnection : GLib.Object
     public void doDisconnect ()
     {
         if (connected) {
-            GLib.Source.remove (sourceId);
+            GLib.Source.remove(sourceId);
+            GLib.Source.remove(sourceIdHup);
+            GLib.Source.remove(sourceIdErr);
+            GLib.Source.remove(sourceIdNval);
             sourceId = null;
+            sourceIdHup = null;
+            sourceIdErr = null;
+            sourceIdNval = null;
             try {
                 IOChannelFd.shutdown (true);
             } catch (GLib.IOChannelError e) {
@@ -130,6 +146,12 @@ public class moserial.SerialConnection : GLib.Object
         return connected;
     }
 
+    private bool onUnplugged(GLib.IOChannel source, GLib.IOCondition condition)
+    {
+        onError();
+        return false;
+    }
+
     private bool readBytes (GLib.IOChannel source, GLib.IOCondition condition)
     {
         uchar[] m_buf = new uchar[max_buf_size];


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]