]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
[Bug 197] Class1 : +FTS=n must be used
authorDarren Nickerson <darren.nickerson@ifax.com>
Fri, 15 Feb 2002 03:55:03 +0000 (03:55 +0000)
committerDarren Nickerson <darren.nickerson@ifax.com>
Fri, 15 Feb 2002 03:55:03 +0000 (03:55 +0000)
Use +FTS=n instead of software pause() to improve Class1 timing, and revert
EOP-related pause to ~95 ms, its historic value which was recently (probably)
erroneously changed (see Bug 152). Thanks to everyone who contributed their
feedback & votes!

config/class1
etc/faxaddmodem.sh.in
faxd/Class1Send.c++
faxd/ModemConfig.c++
faxd/ModemConfig.h
man/hylafax-config.4f

index 8f9f5fba4f5a04ca6bae9e89e529329a7d748a28..8bd6a2afc758e50a5466e4e08ffb535e247ea4cd 100644 (file)
@@ -109,11 +109,11 @@ ModemType:                Class1          # use this to supply a hint
 #ModemSendFillOrder:   LSB2MSB         # bit order modem expects for transmit
 #
 Class1Cmd:             AT+FCLASS=1     # command to enter class 1
+Class1PPMWaitCmd:      AT+FTS=7        # command to stop and wait before PPM
+Class1TCFWaitCmd:      AT+FTS=7        # command to stop and wait before TCF
+Class1EOPWaitCmd:      AT+FTS=9        # command to stop and wait before EOP
 Class1TCFResponseDelay:        75              # 75ms delay between recv TCF & response
-Class1SendEOPDelay:    200             # 200ms delay preceding EOP send
 Class1SendMsgDelay:    75              # 75ms delay after training
-Class1SendPPMDelay:    75              # 75ms delay before sending PPM (MPS)
-Class1SendTCFDelay:    75              # 75ms delay between sending DCS & TCF
 Class1SwitchingDelay:  75              # 150ms delay in switching transmission direction
 Class1TrainingRecovery:        1500            # 1.5sec delay after training failure
 Class1RecvAbortOK:     200             # wait 200ms for abort response
index 77134e756b9ec050801ba3bf73351e1c70814433..6b5347cb475ff992b1e3d4b49a5e80aa95a54bbf 100644 (file)
@@ -1358,13 +1358,13 @@ Class1Parameters="
     Class1NFLOCmd
     Class1HFLOCmd
     Class1SFLOCmd
+    Class1PPMWaitCmd
+    Class1TCFWaitCmd
+    Class1EOPWaitCmd
     Class1FrameOverhead
     Class1RecvAbortOK
     Class1RecvIdentTimer
-    Class1SendEOPDelay
     Class1SendMsgDelay
-    Class1SendPPMDelay
-    Class1SendTCFDelay
     Class1SwitchingDelay
     Class1TCFMaxNonZero
     Class1TCFMinRun
@@ -1618,15 +1618,18 @@ AT      Class1HFLOCmd           \
        Command to setup hardware flow control after switch to Class 1
 AT     Class1SFLOCmd           \
        Command to setup software flow control after switch to Class 1
+AT     Class1PPMWaitCmd        \
+       Command to stop and wait prior to sending PPM
+AT     Class1TCFWaitCmd        \
+       Command to stop and wait prior to sending TCF
+AT     Class1EOPWaitCmd        \
+       Command to stop and wait prior to sending EOP
 #      Class1FrameOverhead     Extra bytes in a received HDLC frame
 #      Class1RecvAbortOK       \
        Maximum time to wait for OK after aborting a receive (ms)
 #      Class1RecvIdentTimer    \
        Maximum wait for initial identification frame (ms)
-#      Class1SendEOPDelay      Delay before sending EOP message (ms)
 #      Class1SendMsgDelay      Delay after completing training (ms)
-#      Class1SendPPMDelay      Delay before sending MPS message (ms)
-#      Class1SendTCFDelay      Delay between sending TCF and ack/nak (ms)
 #      Class1SwitchingDelay    Delay in switching transmission direction (ms)
 #      Class1TCFRecvTimeout    Timeout for receiving TCF (ms)
 #      Class1TCFResponseDelay  Delay before sending DCS and TCF (ms)
index d902a14aad02f8b6681a8b9655a4ded47ce400c0..6b95cd21fcf6b6c5ac1fd5a0190a2d752187ea2c 100644 (file)
@@ -259,20 +259,30 @@ Class1Modem::sendPhaseB(TIFF* tif, Class2Params& next, FaxMachineInfo& info,
        if (!decodePPM(pph, cmd, emsg))
            return (send_failed);
        int ncrp = 0;
+
        /*
         * Delay before switching to the low speed carrier to
-        * send the post-page-message frame.  We follow the spec
-        * in delaying 75ms before switching carriers, except
-        * when at EOP in which case we delay longer because,
-        * empirically, some machines need more time.  Beware
-        * that, reportedly, lengthening this delay too much can
-        * permit echo suppressors to kick in with bad results.
+        * send the post-page-message frame according to 
+        * T.30 chapter 5 note 4.  We provide for a different
+        * setting following EOP because, empirically, some 
+        * machines may need more time. Beware that, reportedly, 
+        * lengthening this delay too much can permit echo 
+        * suppressors to kick in with bad results.
         *
-        * NB: We do not use +FTS because many modems are slow
-        *     to send the OK result and so using pause is more
-        *     accurate.
+        * Historically this delay was done using a software pause
+        * rather than +FTS because the time between +FTS and the 
+        * OK response is longer than expected, and this was blamed
+        * for timing problems.  However, this "longer than expected"
+        * delay is a result of the time required by the modem's
+        * firmware to actually release the carrier.  T.30 requires
+        * a delay (period of silence), and this cannot be guaranteed
+        * by a simple pause.  +FTS must be used.
         */
-       pause(cmd == FCF_MPS ? conf.class1SendPPMDelay : conf.class1SendEOPDelay);
+       if (!atCmd(cmd == FCF_MPS ? conf.class1PPMWaitCmd : conf.class1EOPWaitCmd, AT_OK)) {
+           emsg = "Stop and wait failure (modem on hook)";
+           return (send_failed);
+       }
+
        do {
            /*
             * Send post-page message and get response.
@@ -522,17 +532,21 @@ Class1Modem::sendTraining(Class2Params& params, int tries, fxStr& emsg)
                protoTrace("Error sending T.30 prologue frames");
                continue;
            }
+
            /*
             * Delay before switching to high speed carrier
-            * to send the TCF data.  Note that we use pause
-            * instead of +FTS because many modems are slow
-            * to return the OK result and this can screw up
-            * timing.  Reportedly some modems won't work
-            * properly unless they see +FTS before the TCF,
-            * but for now we stick with what appears to work
-            * the best with the modems we use.
+            * to send the TCF data as required by T.30 chapter
+            * 5 note 3.
+            *
+            * Historically this delay was enforced by a pause,
+            * however, +FTS must be used.  See the notes preceding
+            * Class1PPMWaitCmd above.
             */
-           pause(conf.class1SendTCFDelay);
+           if (!atCmd(conf.class1TCFWaitCmd, AT_OK)) {
+               emsg = "Stop and wait failure (modem on hook)";
+               return (send_failed);
+           }
+
            if (!sendTCF(params, TCF_DURATION)) {
                if (abortRequested())
                    goto done;
index a00c7767d73f65c0cee02a323ac7294a1e293296..217e962ffe5b28830b525b5dc02faaf6eb59a6fc 100644 (file)
@@ -106,6 +106,9 @@ static const struct {
 { "class1nflocmd",             &ModemConfig::class1NFLOCmd },
 { "class1sflocmd",             &ModemConfig::class1SFLOCmd },
 { "class1hflocmd",             &ModemConfig::class1HFLOCmd },
+{ "class1ppmwaitcmd",          &ModemConfig::class1PPMWaitCmd, "AT+FTS=7" },
+{ "class1tcfwaitcmd",          &ModemConfig::class1TCFWaitCmd, "AT+FTS=7" },
+{ "class1eopwaitcmd",          &ModemConfig::class1EOPWaitCmd, "AT+FTS=9" },
 { "class2cmd",                 &ModemConfig::class2Cmd },
 { "class2borcmd",              &ModemConfig::class2BORCmd },
 { "class2relcmd",              &ModemConfig::class2RELCmd },
@@ -182,10 +185,7 @@ static const struct {
 { "modemsoftresetcmddelay",    &ModemConfig::softResetCmdDelay,     3000 },
 { "class1tcfrecvtimeout",      &ModemConfig::class1TCFRecvTimeout,  4500 },
 { "class1tcfresponsedelay",    &ModemConfig::class1TCFResponseDelay,75 },
-{ "class1sendeopdelay",                &ModemConfig::class1SendEOPDelay,    200 },
 { "class1sendmsgdelay",                &ModemConfig::class1SendMsgDelay,    75 },
-{ "class1sendppmdelay",                &ModemConfig::class1SendPPMDelay,    75 },
-{ "class1sendtcfdelay",                &ModemConfig::class1SendTCFDelay,    75 },
 { "class1switchingdelay",      &ModemConfig::class1SwitchingDelay,  75 },
 { "class1trainingrecovery",    &ModemConfig::class1TrainingRecovery,1500 },
 { "class1recvabortok",         &ModemConfig::class1RecvAbortOK,     200 },
index 4719c863fce06880d1ec144951c3cf5e8f0a05ab..26bce63d1b3d7b28034247d6b28de99360ec9c54 100644 (file)
@@ -111,12 +111,12 @@ public:
     fxStr      class1NFLOCmd;          // cmd to setup no flow control
     fxStr      class1SFLOCmd;          // cmd to setup software flow control
     fxStr      class1HFLOCmd;          // cmd to setup hardware flow control
+    fxStr      class1PPMWaitCmd;       // cmd to stop and wait prior to PPM
+    fxStr      class1TCFWaitCmd;       // cmd to stop and wait prior to TCF
+    fxStr      class1EOPWaitCmd;       // cmd to stop and wait prior to EOP
     u_int      class1TCFRecvTimeout;   // timeout receiving TCF
     u_int      class1TCFResponseDelay; // delay (ms) btwn TCF & ack/nak
-    u_int      class1SendEOPDelay;     // delay (ms) before sending EOP
     u_int      class1SendMsgDelay;     // delay (ms) after training
-    u_int      class1SendPPMDelay;     // delay (ms) before sending PPM (MPS)
-    u_int      class1SendTCFDelay;     // delay (ms) btwn sending DCS & TCF
     u_int      class1SwitchingDelay;   // delay (ms) in switching transmission direction
     u_int      class1TrainingRecovery; // delay (ms) after failed training
     u_int      class1RecvAbortOK;      // if non-zero, OK sent after recv abort
index 7b2bcdc50260e691aac16f6de204a069d735f963..95df69109d4f49b0713716379a9edf5a633c5f0f 100644 (file)
@@ -254,14 +254,14 @@ Class1NFLOCmd     string  \-      Class 1: command to set no flow control
 Class1RecvAbortOK      integer \s-1200\s+1     Class 1: max wait (ms) for ``\s-1OK\s+1'' after recv abort
 Class1RecvIdentTimer   integer \s-140000\s+1   Class 1: max wait (ms) for initial ident frame
 Class1SFLOCmd  string  \-      Class 1: command to set software flow control
+Class1PPMWaitCmd       string  \s-1AT+FTS=7\s+1        Class 1: command to stop and wait before PPM
+Class1TCFWaitCmd       string  \s-1AT+FTS=7\s+1        Class 1: command to stop and wait before TCF
+Class1EOPWaitCmd       string  \s-1AT+FTS=9\s+1        Class 1: command to stop and wait before EOP
 Class1TCFMaxNonZero    integer \s-110\s+1      Class 1: max% of non-zero data in good \s-1TCF\s+1
 Class1TCFMinRun        integer \s-11000\s+1    Class 1: minimum zero run in good \s-1TCF\s+1
 Class1TCFRecvTimeout   integer \s-14500\s+1    Class 1: max wait (ms) for \s-1TCF\s+1
 Class1TCFResponseDelay integer \s-175\s+1      Class 1: delay between \s-1TCF\s+1 and ack/nak
-Class1SendEOPDelay     integer \s-1200\s+1     Class 1: delay before sending EOP
 Class1SendMsgDelay     integer \s-175\s+1      Class 1: delay before sending image data
-Class1SendPPMDelay     integer \s-175\s+1      Class 1: delay before sending MPS post-page message
-Class1SendTCFDelay     integer \s-175\s+1      Class 1: delay between sending \s-1DCS\s+1 and \s-1TCF\s+1
 Class1SwitchingDelay   integer \s-175\s+1      Class 1: delay in switching transmision direction (ms)
 Class1TrainingRecovery integer \s-11500\s+1    Class 1: delay after failed training
 .sp .5
@@ -1926,6 +1926,26 @@ This command is issued immediately after sending the
 .B Class1Cmd
 to switch the modem to Class 1 operation.
 .TP
+.B Class1PPMWaitCmd
+The command used to stop and wait before sending the post page message,
+except before sending EOP, when
+.B Class1EOPWaitCmd
+is used instead.  We must ensure that the high-speed carrier has
+stopped completely.
+According to T.30, Chapter 5, Note 4, this delay should be 75 +/- 20 ms.
+.TP
+.B Class1TCFWaitCmd
+The command used to stop and wait before sending TCF, similar to
+.B Class1PPMWaitCmd.
+According to T.30, Chapter 5, Note 3, this delay should be 75 +/- 20 ms.
+.TP
+.B Class1EOPWaitCmd
+The command used to stop and wait before sending the post page message
+similar to
+.B Class1PPMWaitCmd.
+We allow a different setting in the case of EOP, however, because
+empirically some machines may need more time.
+.TP
 .B Class1RecvAbortOK
 The time, in milliseconds, to wait for an ``\s-1OK\s+1'' result code
 from the modem after aborting an 
@@ -1951,27 +1971,10 @@ above under the
 .B AdaptiveAnswer
 parameter may require that this timer be shortened.
 .TP
-.B Class1SendEOPDelay
-The time, in milliseconds, to delay between dropping the high
-speed message carrier and sending the EOP post-page message/command.
-Empirically, this value needs to be greater than
-.B Class1SendPPMDelay
-to prevent modem response timeouts.
-.TP
 .B Class1SendMsgDelay
 The time, in milliseconds, to delay just before sending the image data.
 According to T.30: 5.3.2.4 this should be no less than 75 ms (default).
 .TP
-.B Class1SendPPMDelay
-The time, in milliseconds, to delay between dropping the high
-speed message carrier and sending the MPS post-page message/command.
-.TP
-.B Class1SendTCFDelay
-The time, in milliseconds, to delay between sending 
-.SM DCS
-and
-.SM TCF.
-.TP
 .B Class1SwitchingDelay
 The time, in milliseconds, to delay when switching the direction
 of transmission when receiving, as recommended by T.31.