#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
Class1NFLOCmd
Class1HFLOCmd
Class1SFLOCmd
+ Class1PPMWaitCmd
+ Class1TCFWaitCmd
+ Class1EOPWaitCmd
Class1FrameOverhead
Class1RecvAbortOK
Class1RecvIdentTimer
- Class1SendEOPDelay
Class1SendMsgDelay
- Class1SendPPMDelay
- Class1SendTCFDelay
Class1SwitchingDelay
Class1TCFMaxNonZero
Class1TCFMinRun
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)
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.
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;
{ "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 },
{ "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 },
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
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
.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
.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.