]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Bug 555: fix V.17 fallback procedure after CTC/CTR exchange
authorLee Howard <faxguy@howardsilvan.com>
Mon, 21 Jun 2004 22:11:38 +0000 (22:11 +0000)
committerLee Howard <faxguy@howardsilvan.com>
Mon, 21 Jun 2004 22:11:38 +0000 (22:11 +0000)
CHANGES
faxd/Class1Recv.c++
faxd/Class1Send.c++

diff --git a/CHANGES b/CHANGES
index 4f891a2dec93db8ac93d57ef56f708f64ed7eef2..9e380366a36b5f2047ad11da56fa7dcef915adfb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@
 
 Changelog for HylaFAX 4.2.0
 
+* fix V.17 fallbacks after the CTC/CTR exchange (21 Jun 2004)
 * tune setting of -rpath when linking on linux (21 Jun 2004)
 * add admin option and dialstring alteration to faxalter (20 Jun 2004)
 * add -end option for xferfaxstats and recvstats (17 Jun 2004)
index 770c62774b6ee94855b0e445f2c5be3b47a11dc0..a9403d6d7104529472439d42ca63a9f6c4354d9b 100644 (file)
@@ -760,7 +760,7 @@ Class1Modem::recvPageECMData(TIFF* tif, const Class2Params& params, fxStr& emsg)
        u_short pprcnt = 0;
        u_int fcount = 0;
        u_short syncattempts = 0;
-       bool blockgood = false;
+       bool blockgood = false, dolongtrain = false;
        do {
            sentERR = false;
            resetBlock();
@@ -775,7 +775,13 @@ Class1Modem::recvPageECMData(TIFF* tif, const Class2Params& params, fxStr& emsg)
                    emsg = "Failure to receive silence.";
                    return (false);
                }
-               fxStr rmCmd(curcap[HasShortTraining(curcap)].value, rmCmdFmt);
+               /*
+                * T.30 Section 5, Note 5 states that we must use long training
+                * on the first high-speed data message following CTR.
+                */
+               fxStr rmCmd;
+               if (dolongtrain) rmCmd = fxStr(curcap->value, rmCmdFmt);
+               else rmCmd = fxStr(curcap[HasShortTraining(curcap)].value, rmCmdFmt);
                u_short attempts = 0;
                ATResponse response = AT_NOTHING;
                while ((response == AT_NOTHING || response == AT_FCERROR) && attempts++ < 20) {
@@ -793,6 +799,7 @@ Class1Modem::recvPageECMData(TIFF* tif, const Class2Params& params, fxStr& emsg)
                    if (wasTimeout()) abortReceive();   // return to command mode
                    return (false);
                }
+               dolongtrain = false;
            } else {
                if (!gotEOT) {
                    bool gotprimary = waitForDCEChannel(false);
@@ -1083,6 +1090,7 @@ Class1Modem::recvPageECMData(TIFF* tif, const Class2Params& params, fxStr& emsg)
                                                }
                                                (void) transmitFrame(FCF_CTR|FCF_RCVR);
                                                tracePPR("RECV send", FCF_CTR);
+                                               dolongtrain = true;
                                                break;
                                            case FCF_EOR:
                                                tracePPM("RECV recv", rtnframe.getFCF2());
index 67f1dac6f392e75b6991c98c649a71c5ba3d0099..50b274a3f381c534bcac57df3934496805155aa0 100644 (file)
@@ -796,10 +796,9 @@ Class1Modem::dropToNextBR(Class2Params& params)
        if (curcap) {
            /*
             * Hunt for compatibility with remote at this baud rate.
-            * We don't drop from V.29 to V.17 because...
-            *   1) it will lock up the hardware on some receivers
-            *   2) if the receiver supports V.17 then we probably tried
-            *      it already without success
+            * We don't drop from V.29 to V.17 because if the 
+            * receiver supports V.17 then we probably tried
+            * it already without success.
             */
            while (curcap->br == params.br) {
                if (isCapable(curcap->sr, dis) && !(oldcap->mod == V29 && curcap->mod == V17))
@@ -901,6 +900,7 @@ Class1Modem::blockFrame(const u_char* bitrev, bool lastframe, u_int ppmcmd, fxSt
        char ppr[32];                           // 256 bits
        for (u_int i = 0; i < 32; i++) ppr[i] = 0xff;
        u_short badframes = frameNumber, badframesbefore = 0;
+       bool dolongtrain = false;
 
        do {
            u_short fcount = 0;
@@ -981,11 +981,18 @@ Class1Modem::blockFrame(const u_char* bitrev, bool lastframe, u_int ppmcmd, fxSt
                setXONXOFF(FLOW_XONXOFF, FLOW_NONE, ACT_FLUSH);
            if (!useV34) {
                pause(conf.class1SendMsgDelay);         // T.30 5.3.2.4
-               fxStr tmCmd(curcap[HasShortTraining(curcap)].value, tmCmdFmt);
+               /*
+                * T.30 Section 5, Note 5 states that we must use long training
+                * on the first high-speed data message following CTC.
+                */
+               fxStr tmCmd;
+               if (dolongtrain) tmCmd = fxStr(curcap->value, tmCmdFmt);
+               else tmCmd = fxStr(curcap[HasShortTraining(curcap)].value, tmCmdFmt);
                if (!atCmd(tmCmd, AT_CONNECT))
                    return (false);
                pause(conf.class1TMConnectDelay);
            }
+           dolongtrain = false;
 
            // The block is assembled.  Transmit it, adding transparent DLEs.  End with DLE+ETX.
            u_char buf[2];
@@ -1289,6 +1296,7 @@ Class1Modem::blockFrame(const u_char* bitrev, bool lastframe, u_int ppmcmd, fxSt
                                    protoTrace(emsg);
                                    return (false);
                                }
+                               dolongtrain = true;     // T.30 states that we must use long-training next
                            } else {
                                /*
                                 * At this point data corruption is inevitable if all data