]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Class1: Add Class1HookSensitivity
authorAidan Van Dyk <aidan@ifax.com>
Wed, 26 Sep 2007 12:55:03 +0000 (12:55 +0000)
committerAidan Van Dyk <aidan@ifax.com>
Wed, 26 Sep 2007 12:55:03 +0000 (12:55 +0000)
From the series of Lee's commits:
| commit 7146de7880370793f3a8fd5a67422eee8be05b76
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Thu Jul 19 19:06:49 2007 +0000
|
|   Some modems appear to return ERROR to AT+FRH=3 when the modem is *not* on-hook.
|   So to persist through this condition we are setting up the
|   Class1HookSensitivity feature which will permit the modem to continue through
|   those instances.
|
|   I'm only applying it now to the DCS-receive portion now.  I'm sure later
|   it will get applied to other places where "gotEOT" is handled.
|
|   I'm seeing the condition happen with a Zyxel Omni 288S modem when it hears
|   persistent CNG after answering and sending prologue:
|
|   <-- AT+FRH=3
|   (5 seconds or so elapse)
|   --> ERROR
|
|   This is most likely because the V.21 DSP picks up on the CNG audio, but does
|   not issue a CONNECT due to not seeing HDLC.  When the CNG audio drops then
|   the modem gives ERROR.  It probably should not be doing anything of the sort,
|   merely waiting until HDLC is detected in a carrier, but if it were to follow
|   some interpretations of the T.31 sample sessions, then maybe a NO CARRIER
|   result would have been more appropriate than ERROR.
|
|   In any case, setting Class1HookSensitivity to some number like 10 should
|   prevent the situation from causing the Class 1 driver to give up.

| commit 747ca8412d2b4327dee29c982d55c8889dcad9d3
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Tue Jul 24 22:43:19 2007 +0000
|
|   extend Class1HookSensitivity into recvFrame

| commit 5fa1785ea842ebbe169007705fb669e76b7768e9
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Tue Jul 24 22:47:11 2007 +0000
|
|   Undo earlier Class1Sensitivity involvement, as our usage in recvFrame
|   replaces it.

| commit 0f4aa8eac0ec822825104811a7b912df2478f21d
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Thu Jul 26 15:50:21 2007 +0000
|
|   Try again on Class1HookSensitivity...

| commit f174befaa4b730cffae0b3fe01dfdced2cd5ac8b
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Tue Jul 31 16:13:40 2007 +0000
|
|   Hrmm... the install path was changed but not the runtime path.  Argh.

faxd/Class1.c++
faxd/Class1.h
faxd/Class1Recv.c++
faxd/ModemConfig.c++
faxd/ModemConfig.h
man/hylafax-config.4f

index 868675235c381771be887157f4863da763ad4b17..f35b66fe340f13f944845ccc5e4ee36676bde94d 100644 (file)
@@ -1397,10 +1397,11 @@ Class1Modem::transmitData(int br, u_char* data, u_int cc,
  * retransmit the frame. 
  */
 bool
-Class1Modem::recvFrame(HDLCFrame& frame, u_char dir, long ms, bool readPending, bool docrp)
+Class1Modem::recvFrame(HDLCFrame& frame, u_char dir, long ms, bool readPending, bool docrp, bool usehooksensitivity)
 {
     bool gotframe;
     u_short crpcnt = 0, rhcnt = 0;
+    u_int onhooks = 0;
     gotCONNECT = true;
     if (useV34) {
        do {
@@ -1424,7 +1425,18 @@ Class1Modem::recvFrame(HDLCFrame& frame, u_char dir, long ms, bool readPending,
        do {
            readPending = atCmd(rhCmd, AT_NOTHING, 0) && waitFor(AT_CONNECT, 0);
            if (lastResponse == AT_FCERROR) pause(200);
-       } while (lastResponse == AT_FCERROR && !wasTimeout());
+           if (lastResponse == AT_ERROR && !wasTimeout() && ++onhooks <= conf.class1HookSensitivity) {
+               if (!usehooksensitivity) {
+                   /*
+                    * Class1HookSensitivity is used by the calling function, not us.
+                    */
+                   break;
+               } else {
+                   stopTimeout("");
+                   startTimeout(ms);
+               }
+           }
+       } while ((lastResponse == AT_FCERROR || (lastResponse == AT_ERROR && onhooks <= conf.class1HookSensitivity)) && !wasTimeout());
     }
     if (readPending) {
         stopTimeout("waiting for HDLC flags");
index cadd55ed2cf4b970bf871fcf255e35173b674094..1b5c6d2f8115227191c76a08dcef3049ce8609d4 100644 (file)
@@ -185,7 +185,7 @@ protected:
     bool       sendClass1Data(const u_char* data, u_int cc, const u_char* bitrev, bool eod, long ms);
     bool       sendClass1ECMData(const u_char* data, u_int cc,
                     const u_char* bitrev, bool eod, u_int ppmcmd, Status& eresult);
-    bool       recvFrame(HDLCFrame& frame, u_char dir, long ms = 10*1000, bool readPending = false, bool docrp = true);
+    bool       recvFrame(HDLCFrame& frame, u_char dir, long ms = 10*1000, bool readPending = false, bool docrp = true, bool usehooksensitivity = true);
     bool       recvTCF(int br, HDLCFrame&, const u_char* bitrev, long ms);
     bool       recvRawFrame(HDLCFrame& frame);
     bool       recvECMFrame(HDLCFrame& frame);
index 5570c8b048b18661b1c3bb03be2d59851fec00fd..b09541e0637ec4fe5ad52e0b3174d21514a2b656 100644 (file)
@@ -148,6 +148,7 @@ Class1Modem::recvIdentification(
     time_t start = Sys::now();
     HDLCFrame frame(conf.class1FrameOverhead);
     bool framesSent = false;
+    u_int onhooks = 0;
 
     eresult = Status(102, "No sender protocol (T.30 T1 timeout)");
     if (!notransmit) {
@@ -201,7 +202,7 @@ Class1Modem::recvIdentification(
             * Wait for a response to be received.  We wait T2
             * rather than T4 due to empirical evidence for that need.
             */
-           if (recvFrame(frame, FCF_RCVR, conf.t2Timer)) {
+           if (recvFrame(frame, FCF_RCVR, conf.t2Timer, false, true, false)) {
                do {
                    /*
                     * Verify a DCS command response and, if
@@ -239,7 +240,7 @@ Class1Modem::recvIdentification(
                            if (lastResponse == AT_FRH3 && waitFor(AT_CONNECT,0)) {
                                // It's unclear if we are in "COMMAND REC" or "RESPONSE REC" mode,
                                // but since we are already detecting the carrier, wait the longer.
-                               gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true);
+                               gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true, true, false);
                                lastResponse = AT_NOTHING;
                            }
                        }
@@ -256,10 +257,10 @@ Class1Modem::recvIdentification(
                     * the full T1 timeout, as specified by the protocol.
                     */
                    t1 = howmany(conf.t1Timer, 1000);
-               } while (recvFrame(frame, FCF_RCVR, conf.t2Timer));
+               } while (recvFrame(frame, FCF_RCVR, conf.t2Timer, false, true, false));
            }
        }
-       if (gotEOT) {
+       if (gotEOT && ++onhooks > conf.class1HookSensitivity) {
            eresult = Status(106, "RSPREC error/got EOT");
            return (false);
        }
index 3634f783a0b9335f14a1d05489bc251ef34664cc..8be2a1c5487c813760d8d1d93d761ab18b2871f5 100644 (file)
@@ -204,6 +204,7 @@ static struct {
 { "class1tcfrecvtimeout",      &ModemConfig::class1TCFRecvTimeout,  4500 },
 { "class1recvabortok",         &ModemConfig::class1RecvAbortOK,     200 },
 { "class1rmpersistence",       &ModemConfig::class1RMPersistence,   2 },
+{ "class1hooksensitivity",     &ModemConfig::class1HookSensitivity, 0 },
 { "class1frameoverhead",       &ModemConfig::class1FrameOverhead,   4 },
 { "class1recvidenttimer",      &ModemConfig::class1RecvIdentTimer,  TIMER_T1 },
 { "class1tcfmaxnonzero",       &ModemConfig::class1TCFMaxNonZero,   10 },
index 17284ff55394e02cd5f34c608652b79e72aed7b6..3895e99ae9deccd4787bddee4854f4b1cf932426 100644 (file)
@@ -156,6 +156,7 @@ public:
     u_int      class1TCFRecvTimeout;   // timeout receiving TCF
     u_int      class1RecvAbortOK;      // if non-zero, OK sent after recv abort
     u_int      class1RMPersistence;    // how many times to persist through +FCERROR
+    u_int      class1HookSensitivity;  // how many times to persist through on-hook detections
     u_int      class1Resolutions;      // resolutions support
     u_int      class1FrameOverhead;    // overhead bytes in received frames
     u_int      class1RecvIdentTimer;   // timeout receiving initial identity
index 99038608974c2c45a912d18224081641c6b796e9..e190629680883b6298a9db2abdedfefa17941c5f 100644 (file)
@@ -297,6 +297,7 @@ Class1HasRHConnectBug       boolean \s-1No\s+1      Class 1/1.0: modem can report CONNECT i
 Class1HFLOCmd  string  \-      Class 1/1.0: command to set hardware flow control
 Class1FrameOverhead    integer \s-14\s+1       Class 1/1.0: extra bytes in a received \s-1HDLC\s+1 frame
 Class1GreyJPEGSupport  boolean \s-1No\s+1      Class 1/1.0: to enable grey JPEG fax support
+Class1HookSensitivity  integer \s-10\s+1       Class 1/1.0: times to ignore on-hook detection
 Class1JBIGSupport      string  \s-1\fIsee below\fP\s+1 Class 1/1.0: to enable monochrome JBIG fax support
 Class1MRSupport        boolean \s-1Yes\s+1     Class 1/1.0: enable 2-D MR support
 Class1MMRSupport       boolean \s-1Yes\s+1     Class 1/1.0: enable 2-D MMR support
@@ -2438,6 +2439,10 @@ with JPEG compression.  This is always enabled if
 .B Class1ColorJPEGSupport
 is enabled.
 .TP
+.B Class1HookSensitivity
+The number of times to ignore on-hook detections and merely treat them
+as command or modem errors.
+.TP
 .B Class1JBIGSupport
 Whether or not to enable support for T.85 monochrome facsimile
 with JBIG compression.  Options are ``true'' for support in both