]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Improve ECM HDLC frame decoder to recover more quickly from data corruption and...
authorAidan Van Dyk <aidan@ifax.com>
Wed, 14 Mar 2007 18:26:27 +0000 (18:26 +0000)
committerAidan Van Dyk <aidan@ifax.com>
Wed, 14 Mar 2007 18:26:27 +0000 (18:26 +0000)
This is based on  of 2 of Lee's patches:
|  commit 6edca4c323ac8a499ce6a2b832e2bc2c8ee6a38a
|  Author: Lee Howard <faxguy@howardsilvan.com>
|  Date:   Tue Nov 7 00:51:20 2006 +0000
|
|    The ECM HDLC frame decoder would read the bitstream and would pull out ECM
|    frames from there.
|
|    Most of this change is directed towards removing the requirement that the
|    HDLC frame be immediately followed by an HDLC sync flag.  That way if the
|    data corruption occurs on the flag and not in the frame itself then the
|    data is still useable.
|
|    The way in which I've coded this, however, in merely counting the frame
|    size as it builds allows the decoder to recover from data corruption more
|    quickly than before.  So that's an added bonus, I guess. :-)

and

|  commit 94c3c2732b60f4aad41852f2a4fd17d03c43bda5
|  Author: Lee Howard <faxguy@howardsilvan.com>
|  Date:   Tue Nov 7 16:58:37 2006 +0000
|
|    ECM frames are, unfortunately, not always full-sized

CHANGES
faxd/Class1.c++

diff --git a/CHANGES b/CHANGES
index 62c034a7c3c65d7c91b4a545cfafdfe5fa6a568c..ee6ca8d25feef84cd1519b21437bc7c013413c13 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,8 @@
 
 Changelog since HylaFAX 4.3.3
 
+* Improve ECM HDLC frame decoder to recover more quickly from data corruption
+  and possibly find frames where it couldn't before (12 Mar 2007)
 * Extend "awaiting ECM synchronization" timeout (12 Mar 2007)
 * Add Class1PageWidthSupport modem config option (12 Mar 2007)
 * Add Class1PageLengthSupport config option (12 Mar 2007)
index 299da193fe70777f95d3d92de472eb038ccc0c2f..efd5337abe4cc046b1548a89f1d7bfba629c398f 100644 (file)
@@ -1048,13 +1048,6 @@ Class1Modem::recvECMFrame(HDLCFrame& frame)
                frame.put(byte);
                bitpos = 8;
                byte = 0;
-               /*
-                * Ensure that a corrupt frame doesn't overflow the frame buffer.
-                */
-               if (frame.getLength() > ((frameSize+6)*4)) {    //  4 times valid size
-                   protoTrace("HDLC frame length invalid.");
-                   return (false);
-               }
            }
        }
        if (bit == 0) ones = 0;
@@ -1070,11 +1063,22 @@ Class1Modem::recvECMFrame(HDLCFrame& frame)
            frame.put(0xff); frame.put(0xc0); frame.put(0x61); frame.put(0x96); frame.put(0xd3);
            rcpframe = true;
        }
-    } while (ones != 6 && bit != EOF && !rcpframe);
-    bit = getModemBit(60000);                  // trailing bit on flag
-    if (!rcpframe) {
-       if (frame.getLength() > 0)
-           traceHDLCFrame("-->", frame, true);
+    } while (ones != 6 && bit != EOF && !rcpframe && frame.getLength() < frameSize+6);
+    if (ones == 6) bit = getModemBit(60000);                   // trailing bit on flag
+    if (!rcpframe && frame.getLength() < frameSize+6) {
+       /*
+        * The HDLC frame was terminated early by a flag.  T.30 A.3.5 states that
+        * frame size cannot change during one page, and T.4 A.3.6.2 seems to provide
+        * for padding in order to get that last frame on a block to always line up
+        * on a byte and frame boundary.  However, the NOTE 2 there seemse to give
+        * leniency to that requirement, and in fact many senders will send short
+        * frames on the last frame of a block.  So we run a couple of additional
+        * checks here (in addition to FCS checking) to limit the remote chance
+        * of FCS actually checking out on corrupt data (although that may be very
+        * remote indeed).  We don't do these "trailing flag" tests on normal-sized
+        * frames because we deliberately don't look for a trailing flag when we
+        * get enough data.
+        */
        if (bit) {                              // should have been zero
            protoTrace("Bad HDLC terminating flag received.");
            return (false);
@@ -1084,6 +1088,7 @@ Class1Modem::recvECMFrame(HDLCFrame& frame)
            return (false);
        }
     }
+    traceHDLCFrame("-->", frame, true);
     if (bit == EOF) {
        protoTrace("EOF received.");
        return (false);