"Fossies" - the Fresh Open Source Software Archive

Member "hylafax-7.0.2/faxd/Class1Recv.c++" (5 Dec 2019, 85254 Bytes) of package /linux/misc/hylafax-7.0.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "Class1Recv.c++": 7.0.1_vs_7.0.2.

    1 /*  $Id: Class1Recv.c++ 1133 2012-12-26 06:51:02Z faxguy $ */
    2 /*
    3  * Copyright (c) 1990-1996 Sam Leffler
    4  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
    5  * HylaFAX is a trademark of Silicon Graphics
    6  *
    7  * Permission to use, copy, modify, distribute, and sell this software and 
    8  * its documentation for any purpose is hereby granted without fee, provided
    9  * that (i) the above copyright notices and this permission notice appear in
   10  * all copies of the software and related documentation, and (ii) the names of
   11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
   12  * publicity relating to the software without the specific, prior written
   13  * permission of Sam Leffler and Silicon Graphics.
   14  * 
   15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
   16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
   17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
   18  * 
   19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
   20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
   21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
   23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
   24  * OF THIS SOFTWARE.
   25  */
   26 
   27 /*
   28  * EIA/TIA-578 (Class 1) Modem Driver.
   29  *
   30  * Receive protocol.
   31  */
   32 #include <stdio.h>
   33 #include <sys/time.h>
   34 #include <pthread.h>
   35 #include "Class1.h"
   36 #include "ModemConfig.h"
   37 #include "HDLCFrame.h"
   38 #include "StackBuffer.h"        // XXX
   39 
   40 #include "config.h"
   41 #include "t.30.h"
   42 #include "Sys.h"
   43 #include "config.h"
   44 #include "FaxParams.h"
   45 
   46 /*
   47  * Tell the modem to answer the phone.  We override
   48  * this method so that we can force the terminal's
   49  * flow control state to be setup to our liking.
   50  */
   51 CallType
   52 Class1Modem::answerCall(AnswerType type, fxStr& emsg, const char* number)
   53 {
   54     // Reset modemParams.br to non-V.34 settings.  If V.8 handshaking
   55     // succeeds, then it will be changed again.
   56     modemParams.br = nonV34br;
   57 
   58     if (flowControl == FLOW_XONXOFF)
   59     setXONXOFF(FLOW_NONE, FLOW_NONE, ACT_FLUSH);
   60     return ClassModem::answerCall(type, emsg, number);
   61 }
   62 
   63 /*
   64  * Process an answer response from the modem.
   65  * Since some Class 1 modems do not give a connect
   66  * message that distinguishes between DATA and FAX,
   67  * we override the default handling of "CONNECT"
   68  * message here to force the high level code to
   69  * probe further.
   70  */
   71 const AnswerMsg*
   72 Class1Modem::findAnswer(const char* s)
   73 {
   74     static const AnswerMsg answer[2] = {
   75     { "CONNECT ", 8,
   76       FaxModem::AT_NOTHING, FaxModem::OK, FaxModem::CALLTYPE_DATA },
   77     { "CONNECT",  7,
   78       FaxModem::AT_NOTHING, FaxModem::OK, FaxModem::CALLTYPE_UNKNOWN },
   79     };
   80     return strneq(s, answer[0].msg, answer[0].len) ? &answer[0] :
   81        strneq(s, answer[1].msg, answer[1].len) ? &answer[1] :
   82           FaxModem::findAnswer(s);
   83 }
   84 
   85 /*
   86  * Begin the receive protocol.
   87  */
   88 bool
   89 Class1Modem::recvBegin(FaxSetup* setupinfo, fxStr& emsg)
   90 {
   91     setInputBuffering(false);
   92     prevPage = 0;               // no previous page received
   93     pageGood = false;               // quality of received page
   94     messageReceived = false;            // expect message carrier
   95     recvdDCN = false;               // haven't seen DCN
   96     lastPPM = FCF_DCN;              // anything will do
   97     sendCFR = false;                // TCF was not received
   98     lastMCF = 0;                // no MCF heard yet
   99     capsUsed = 0;               // no DCS or CTC seen yet
  100     dataSent = 0;               // start with a clean slate...
  101     dataMissed = 0;             // unfortunately, this will reset after EOM
  102     pageDataMissed = 0;
  103     senderSkipsV29 = false;
  104     senderHasV17Trouble = false;
  105 
  106     if (setupinfo) {
  107     senderSkipsV29 = setupinfo->senderSkipsV29;
  108     senderHasV17Trouble = setupinfo->senderHasV17Trouble;
  109     }
  110 
  111     fxStr nsf;
  112     encodeNSF(nsf, HYLAFAX_VERSION);
  113 
  114     if (!isSSLFax && useV34 && !gotCTRL) waitForDCEChannel(true);   // expect control channel
  115 
  116     FaxParams dis = modemDIS();
  117 
  118     if (senderSkipsV29 && senderHasV17Trouble) {
  119     dis.setBit(FaxParams::BITNUM_SIGRATE_14, false);    // disable V.17 support
  120     protoTrace("This sender skips V.29 and has trouble with V.17.  Concealing V.17 support.");
  121     }
  122     if (conf.class1RestrictPoorSenders && setupinfo && setupinfo->senderDataSent && 
  123     (u_int) (setupinfo->senderDataMissed * 100 / setupinfo->senderDataSent) > conf.class1RestrictPoorSenders) {
  124     dis.setBit(FaxParams::BITNUM_VR_FINE, false);   // disable fine resolution support
  125     dis.setBit(FaxParams::BITNUM_VR_R8, false); // disable superfine resolution support
  126     dis.setBit(FaxParams::BITNUM_VR_300X300, false);// disable 300x300 dpi support
  127     dis.setBit(FaxParams::BITNUM_VR_R16, false);    // disable hyperfine resolution support
  128     dis.setBit(FaxParams::BITNUM_JPEG, false);  // disable JPEG support
  129     dis.setBit(FaxParams::BITNUM_FULLCOLOR, false); // disable color JPEG support
  130     protoTrace("This sender exhibits poor call audio quality.  Concealing resolution and color support.");
  131     }
  132 
  133     bool ok = FaxModem::recvBegin(setupinfo, emsg) && recvIdentification(
  134     0, fxStr::null,
  135     0, fxStr::null,
  136     FCF_NSF|FCF_RCVR, nsf,
  137     FCF_CSI|FCF_RCVR, lid,
  138     FCF_DIS|FCF_RCVR, dis,
  139     conf.class1RecvIdentTimer, false, emsg);
  140     if (setupinfo) {
  141     /*
  142      * Update FaxMachine info...
  143      */
  144     setupinfo->senderSkipsV29 = senderSkipsV29;
  145     setupinfo->senderHasV17Trouble = senderHasV17Trouble;
  146     setupinfo->senderDataSent = dataSent;
  147     setupinfo->senderDataMissed = dataMissed;
  148     }
  149     return (ok);
  150 }
  151 
  152 /*
  153  * Begin the receive protocol after an EOM signal.
  154  */
  155 bool
  156 Class1Modem::recvEOMBegin(FaxSetup* setupinfo, fxStr& emsg)
  157 {
  158     /*
  159      * We must raise the transmission carrier to mimic the state following ATA.
  160      */
  161     if (!isSSLFax && !useV34) {
  162     pause(conf.t2Timer);    // T.30 Fig 5.2B requires T2 to elapse
  163     if (!(atCmd(thCmd, AT_NOTHING) && atResponse(rbuf, 0) == AT_CONNECT)) {
  164         emsg = "Failure to raise V.21 transmission carrier. {E101}";
  165         protoTrace(emsg);
  166         return (false);
  167     }
  168     }
  169     return Class1Modem::recvBegin(setupinfo, emsg);
  170 }
  171 
  172 /*
  173  * Transmit local identification and wait for the
  174  * remote side to respond with their identification.
  175  */
  176 bool
  177 Class1Modem::recvIdentification(
  178     u_int f1, const fxStr& pwd,
  179     u_int f2, const fxStr& addr,
  180     u_int f3, const fxStr& nsf,
  181     u_int f4, const fxStr& id,
  182     u_int f5, FaxParams& dics,
  183     u_int timer, bool notransmit, fxStr& emsg)
  184 {
  185     u_int t1 = howmany(timer, 1000);        // in seconds
  186     time_t start = Sys::now();
  187     HDLCFrame frame(conf.class1FrameOverhead);
  188     bool framesSent = false;
  189     u_int onhooks = 0;
  190 
  191     /* Here, "features" defines HylaFAX-specific features. */
  192     u_char features[1] = { 0 };
  193     if (conf.class1SSLFaxSupport) features[0] |= frameRev[FaxParams::FEATURE_SSLFAX];   // Enable "SSL Fax"
  194 
  195     emsg = "No sender protocol (T.30 T1 timeout) {E102}";
  196     if (!notransmit) {
  197     /*
  198      * Transmit (PWD) (SUB) (CSI) DIS frames when the receiving
  199      * station or (PWD) (SEP) (CIG) DTC when initiating a poll.
  200      */
  201     if (f1) {
  202         startTimeout(7550);
  203         framesSent = sendFrame(f1, pwd, false);
  204         stopTimeout("sending PWD frame");
  205     } else if (f2) {
  206         startTimeout(7550);
  207         framesSent = sendFrame(f2, addr, false);
  208         stopTimeout("sending SUB/SEP frame");
  209     } else if (f3) {
  210         startTimeout(7550);
  211         framesSent = sendFrame(f3, (const u_char*)HYLAFAX_NSF, (const u_char*) features, nsf, false);
  212         stopTimeout("sending NSF frame");
  213     } else {
  214         startTimeout(7550);
  215         framesSent = sendFrame(f4, id, false);
  216         stopTimeout("sending CSI/CIG frame");
  217     }
  218     }
  219     for (;;) {
  220     if (framesSent && !notransmit) {
  221         if (f1) {
  222         startTimeout(7550);
  223         framesSent = sendFrame(f2, addr, false);
  224         stopTimeout("sending SUB/SEP frame");
  225         }
  226         if (framesSent && f2) {
  227         startTimeout(7550);
  228         framesSent = sendFrame(f3, (const u_char*)HYLAFAX_NSF, (const u_char*) features, nsf, false);
  229         stopTimeout("sending NSF frame");
  230         }
  231         if (framesSent && f3) {
  232         startTimeout(7550);
  233         framesSent = sendFrame(f4, id, false);
  234         stopTimeout("sending CSI/CIG frame");
  235         }
  236         if (framesSent) {
  237         startTimeout(7550);
  238         framesSent = sendFrame(f5, dics);
  239         stopTimeout("sending DIS/DCS frame");
  240         }
  241     }
  242     if (framesSent || notransmit) {
  243         /*
  244          * Wait for a response to be received.  We wait T2
  245          * rather than T4 due to empirical evidence for that need.
  246          */
  247         if (recvFrame(frame, FCF_RCVR, conf.t2Timer, false, true, false)) {
  248         do {
  249             /*
  250              * Verify a DCS command response and, if
  251              * all is correct, receive phasing/training.
  252              */
  253             bool gotframe = true;
  254             while (gotframe) {
  255             if (!recvDCSFrames(frame)) {
  256                 switch (frame.getFCF()) {
  257                 case FCF_DCN:
  258                     emsg = "RSPREC error/got DCN (sender abort) {E103}";
  259                     recvdDCN = true;
  260                     return (false);
  261                 case FCF_MPS:
  262                 case FCF_EOP:
  263                 case FCF_EOM:
  264                     if (!switchingPause(emsg)) return (false);
  265                     transmitFrame(signalSent);
  266                     traceFCF("RECV send", (u_char) signalSent[2]);
  267                     break;
  268                 case FCF_FTT:
  269                     /* probably just our own echo */
  270                     break;
  271                 case FCF_CRP:
  272                     /* do nothing here, just let us repeat NSF, CSI, DIS */
  273                     break;
  274                 default:    // XXX DTC/DIS not handled
  275                     emsg = "RSPREC invalid response received {E104}";
  276                     break;
  277                 }
  278                 break;
  279             }
  280             gotframe = false;
  281             if (recvTraining()) {
  282                 emsg = "";
  283                 return (true);
  284             } else {
  285                 if (lastResponse == AT_FRH3 && waitFor(AT_CONNECT, conf.t2Timer)) {
  286                 // It's unclear if we are in "COMMAND REC" or "RESPONSE REC" mode,
  287                 // but since we are already detecting the carrier, wait the longer.
  288                 gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true, false, false);
  289                 if (!gotframe && !frame.getLength() && lastResponse == AT_NOCARRIER) {
  290                     /*
  291                      * The modem may have incorrectly detected V.21 HDLC.
  292                      * The TCF signal is yet to come.  So, try again.
  293                      */
  294                     if (recvTraining()) {
  295                     emsg = "";
  296                     return (true);
  297                     }
  298                     if (lastResponse == AT_FRH3 && waitFor(AT_CONNECT, conf.t2Timer)) {
  299                     // It's unclear if we are in "COMMAND REC" or "RESPONSE REC" mode,
  300                     // but since we are already detecting the carrier, wait the longer.
  301                     gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true, true, false);
  302                     }
  303                 }
  304                 lastResponse = AT_NOTHING;
  305                 }
  306             }
  307             }
  308             if (gotframe) break;    // where recvDCSFrames fails without DCN
  309             emsg = "Failure to train modems {E105}";
  310             /*
  311              * Reset the timeout to insure the T1 timer is
  312              * used.  This is done because the adaptive answer
  313              * strategy may setup a shorter timeout that's
  314              * used to wait for the initial identification
  315              * frame.  If we get here then we know the remote
  316              * side is a fax machine and so we should wait
  317              * the full T1 timeout, as specified by the protocol.
  318              */
  319             t1 = howmany(conf.t1Timer, 1000);
  320         } while (recvFrame(frame, FCF_RCVR, conf.t2Timer, false, true, false));
  321         }
  322     }
  323     if (gotEOT && ++onhooks > conf.class1HookSensitivity) {
  324         emsg = "RSPREC error/got EOT {E106}";
  325         return (false);
  326     }
  327     /*
  328      * We failed to send our frames or failed to receive
  329      * DCS from the other side.  First verify there is
  330      * time to make another attempt...
  331      */
  332     if ((u_int) Sys::now()-start >= t1)
  333         return (false);
  334     if (frame.getFCF() != FCF_CRP) {
  335         /*
  336          * Historically we waited "Class1TrainingRecovery" (1500 ms)
  337          * at this point to try to try to avoid retransmitting while
  338          * the sender is also transmitting.  Sometimes it proved to be
  339          * a faulty approach.  Really what we're trying to do is to
  340          * not be transmitting at the same time as the other end is.
  341          * The best way to do that is to make sure that there is
  342          * silence on the line, and  we do that with Class1SwitchingCmd.
  343          */
  344         if (!switchingPause(emsg)) {
  345         return (false);
  346         }
  347     }
  348     if (!notransmit) {
  349         /*
  350          * Retransmit ident frames.
  351          */
  352         if (f1)
  353         framesSent = transmitFrame(f1, pwd, false);
  354         else if (f2)
  355         framesSent = transmitFrame(f2, addr, false);
  356         else if (f3)
  357         framesSent = transmitFrame(f3, (const u_char*)HYLAFAX_NSF, (const u_char*) features, nsf, false);
  358         else
  359         framesSent = transmitFrame(f4, id, false);
  360     }
  361     }
  362     return (false);
  363 }
  364 
  365 /*
  366  * Receive DCS preceded by any optional frames.
  367  * Although technically this is "RESPONSE REC",
  368  * we wait T2 due to empirical evidence of that need.
  369  */
  370 bool
  371 Class1Modem::recvDCSFrames(HDLCFrame& frame)
  372 {
  373     fxStr s;
  374     do {
  375     traceFCF("RECV recv", frame.getFCF());
  376     switch (frame.getFCF()) {
  377     case FCF_PWD:
  378         recvPWD(decodePWD(s, frame));
  379         break;
  380     case FCF_SUB:
  381         recvSUB(decodePWD(s, frame));
  382         break;
  383     case FCF_TSI:
  384         recvTSI(decodeTSI(s, frame));
  385         break;
  386     case FCF_TSA:
  387         {
  388         fxStr s;
  389         decodeCSA(s, frame);
  390         protoTrace("REMOTE TSA \"%s\", type 0x%X", (const char*) s, remoteCSAType);
  391         if (remoteCSAType == 0x40 && s.length() > 6 && strncmp((const char*) s, "ssl://", 6) == 0) {
  392             // Looks like this is an SSL Fax sender.
  393             if (conf.class1SSLFaxSupport) useSSLFax = true;
  394             u_int atpos = s.next(6, '@');
  395             if (atpos < s.length()) {
  396             sslFaxPasscode = s.extract(6, atpos-6);
  397             remoteCSAinfo = s.tail(s.length() - atpos - 1);
  398             } else {
  399             sslFaxPasscode = "";
  400             remoteCSAinfo = s.tail(s.length() - 6);
  401             }
  402         }
  403         }
  404         break;
  405     case FCF_DCS:
  406         if (frame.getFrameDataLength() < 4) return (false); // minimum acceptable DCS frame size
  407         processDCSFrame(frame);
  408         break;
  409     case FCF_DCN:
  410         gotEOT = true;
  411         recvdDCN = true;
  412         break;
  413     }
  414     /*
  415      * Sometimes echo is bad enough that we hear ourselves.  So if we hear DIS, we're probably
  416      * hearing ourselves.  Just ignore it and listen again.
  417      */
  418     } while (!recvdDCN && (frame.moreFrames() || frame.getFCF() == FCF_DIS) && recvFrame(frame, FCF_RCVR, conf.t2Timer));
  419     return (frame.isOK() && frame.getFCF() == FCF_DCS);
  420 }
  421 
  422 /*
  423  * Receive training and analyze TCF.
  424  */
  425 bool
  426 Class1Modem::recvTraining()
  427 {
  428     if (isSSLFax || useV34) {
  429     sendCFR = true;
  430     return (true);
  431     }
  432     /*
  433      * It is possible (and with some modems likely) that the sending
  434      * system has not yet dropped its V.21 carrier because the modem may
  435      * simply signal OK when the HDLC frame is received completely and not
  436      * not wait for the carrier drop to occur.  We don't follow the strategy 
  437      * documented in T.31 Appendix II.1 about issuing another +FRH and 
  438      * waiting for NO CARRIER because it's possible that the sender does not
  439      * send enough V.21 HDLC after the last frame to make that work.
  440      *
  441      * The remote has to wait 75 +/- 20 ms after DCS before sending us TCF 
  442      * as dictated by T.30 Chapter 5, Note 3.  If we have a modem that gives
  443      * us an OK after DCS before the sender actually drops the carrier, then
  444      * the best approach will be to simply look for silence with AT+FRS=1.
  445      * Unfortunately, +FRS is not supported on all modems, and so when they
  446      * need it, they will have to simply use a <delay:n> or possibly use
  447      * a different command sequence.
  448      *
  449      */
  450     if (!atCmd(conf.class1TCFRecvHackCmd, AT_OK)) {
  451     return (false);
  452     }
  453 
  454     protoTrace("RECV training at %s %s",
  455     modulationNames[curcap->mod],
  456     Class2Params::bitRateNames[curcap->br]);
  457     HDLCFrame buf(conf.class1FrameOverhead);
  458     bool ok = recvTCF(curcap->value, buf, frameRev, conf.class1TCFRecvTimeout);
  459     if (curcap->mod == V17) senderHasV17Trouble = !ok;  // if TCF failed
  460     if (ok) {                   // check TCF data
  461     u_int n = buf.getLength();
  462     u_int nonzero = 0;
  463     u_int zerorun = 0;
  464     u_int i = 0;
  465     /*
  466      * Skip any initial non-zero training noise.
  467      */
  468     while (i < n && buf[i] != 0)
  469         i++;
  470     /*
  471      * Determine number of non-zero bytes and
  472      * the longest zero-fill run in the data.
  473      */
  474     if (i < n) {
  475         while (i < n) {
  476         u_int j;
  477         for (; i < n && buf[i] != 0; i++)
  478             nonzero++;
  479         for (j = i; j < n && buf[j] == 0; j++)
  480             ;
  481         if (j-i > zerorun)
  482             zerorun = j-i;
  483         i = j;
  484         }
  485     } else {
  486         /*
  487          * There was no non-zero data.
  488          */
  489         nonzero = n;
  490     }
  491     /*
  492      * Our criteria for accepting is that there must be
  493      * no more than 10% non-zero (bad) data and the longest
  494      * zero-run must be at least at least 2/3'rds of the
  495      * expected TCF duration.  This is a hack, but seems
  496      * to work well enough.  What would be better is to
  497      * anaylze the bit error distribution and decide whether
  498      * or not we would receive page data with <N% error,
  499      * where N is probably ~5.  If we had access to the
  500      * modem hardware, the best thing that we could probably
  501      * do is read the Eye Quality register (or similar)
  502      * and derive an indicator of the real S/N ratio.
  503      */
  504     u_int fullrun = params.transferSize(TCF_DURATION);
  505     u_int minrun = params.transferSize(conf.class1TCFMinRun);
  506     if (params.ec != EC_DISABLE && conf.class1TCFMinRunECMMod > 0) {
  507         /*
  508          * When using ECM it may not be wise to fail TCF so easily
  509          * as retransmissions can compensate for data corruption.
  510          * For example, if there is a regular disturbance in the 
  511          * audio every second that will cause TCFs to fail, but where
  512          * the majority of the TCF data is "clean", then it will
  513          * likely be better to pass TCF more easily at the faster
  514          * rate rather than letting things slow down where the 
  515          * disturbance will only cause slower retransmissions (and
  516          * more of them, too).
  517          */
  518         minrun /= conf.class1TCFMinRunECMMod;
  519     }
  520     nonzero = (100*nonzero) / (n == 0 ? 1 : n);
  521     protoTrace("RECV: TCF %u bytes, %u%% non-zero, %u zero-run",
  522         n, nonzero, zerorun);
  523     if (zerorun < fullrun && nonzero > conf.class1TCFMaxNonZero) {
  524         protoTrace("RECV: reject TCF (too many non-zero, max %u%%)",
  525         conf.class1TCFMaxNonZero);
  526         ok = false;
  527     }
  528     if (zerorun < minrun) {
  529         protoTrace("RECV: reject TCF (zero run too short, min %u)", minrun);
  530         ok = false;
  531     }
  532     if (!wasTimeout()) {
  533         /*
  534          * We expect the message carrier to drop.  However, some senders will
  535          * transmit garbage after we see <DLE><ETX> but before we see NO CARRIER.
  536          */
  537         time_t nocarrierstart = Sys::now();
  538         bool gotnocarrier = false;
  539         do {
  540         gotnocarrier = waitFor(AT_NOCARRIER, 2*1000);
  541         } while (!gotnocarrier && Sys::now() < (nocarrierstart + 5));
  542     }
  543     } else {
  544     // the CONNECT is waited for later...
  545     if (lastResponse == AT_FCERROR && atCmd(rhCmd, AT_NOTHING)) lastResponse = AT_FRH3;
  546     if (lastResponse == AT_FRH3) return (false);    // detected V.21 carrier
  547     }
  548     /*
  549      * Send training response; we follow the spec
  550      * by delaying 75ms before switching carriers.
  551      */
  552     fxStr emsg;
  553     if (!switchingPause(emsg)) return (false);
  554     if (ok) {
  555     /*
  556      * Send CFR later so that we can cancel
  557      * session by DCN if it's needed. 
  558      */
  559     sendCFR = true;
  560     protoTrace("TRAINING succeeded");
  561     } else {
  562     transmitFrame(FCF_FTT|FCF_RCVR);
  563     sendCFR = false;
  564     protoTrace("TRAINING failed");
  565     }
  566     return (ok);
  567 }
  568 
  569 void
  570 Class1Modem::processNewCapabilityUsage()
  571 {
  572     capsUsed |= BIT(curcap->num);       // add this modulation+bitrate to the used list
  573     if ((capsUsed & 0x94) == 0x94) {
  574     senderSkipsV29 = ((capsUsed & 0xDC) == 0x94);
  575     }
  576 }
  577 
  578 /*
  579  * Process a received DCS frame.
  580  */
  581 void
  582 Class1Modem::processDCSFrame(const HDLCFrame& frame)
  583 {
  584     FaxParams dcs_caps = frame.getDIS();            // NB: really DCS
  585 
  586     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_FRAMESIZE_DCS)) frameSize = 64;
  587     else frameSize = 256;
  588     /*
  589      * Some equipment out there will signal DCS bits 1 or 3 but cannot subsequently
  590      * handle a CSA frame (violating T.30) and will disconnect after seeing it.  So,
  591      * we avoid sending CSA for SSL Fax when only bit 1 (T.37) or bit 3 (T.38) is
  592      * used.  They must both be used in DCS in order for us to send CSA.
  593      */
  594     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_T37) && dcs_caps.isBitEnabled(FaxParams::BITNUM_T38)) {
  595     protoTrace("REMOTE wants internet fax");
  596     if (conf.class1SSLFaxSupport) useSSLFax = true;
  597     } else if (dcs_caps.isBitEnabled(FaxParams::BITNUM_T37)) {
  598     protoTrace("REMOTE wants internet fax (T.37)");
  599     } else if (dcs_caps.isBitEnabled(FaxParams::BITNUM_T38)) {
  600     protoTrace("REMOTE wants internet fax (T.38)");
  601     }
  602     params.setFromDCS(dcs_caps);
  603     if (!isSSLFax && useV34) params.br = primaryV34Rate-1;
  604     else if (!isSSLFax) {
  605     curcap = findSRCapability((dcs_caps.getByte(1)<<8)&DCS_SIGRATE, recvCaps);
  606     processNewCapabilityUsage();
  607     }
  608     setDataTimeout(60, params.br);
  609     recvDCS(params);                // announce session params
  610 }
  611 
  612 const u_int Class1Modem::modemPPMCodes[8] = {
  613     0,          // 0
  614     PPM_EOM,        // FCF_EOM+FCF_PRI_EOM
  615     PPM_MPS,        // FCF_MPS+FCF_PRI_MPS
  616     0,          // 3
  617     PPM_EOP,        // FCF_EOP+FCF_PRI_EOP
  618     0,          // 5
  619     0,          // 6
  620     0,          // 7
  621 };
  622 
  623 /*
  624  * Data structure for pthread argument for TIFFWriteDirectory wrapper.
  625  */
  626 struct recvTIFFWriteDirectoryData {
  627     int pfd;
  628     TIFF* tif;
  629 
  630     recvTIFFWriteDirectoryData(int a, TIFF* b) : pfd(a), tif(b) {}
  631 };
  632 
  633 /*
  634  * Static wrapper function for TIFFWriteDirectory
  635  * with signal used with pthread.
  636  */
  637 void*
  638 recvTIFFWriteDirectory(void* rd)
  639 {
  640     recvTIFFWriteDirectoryData *r = (recvTIFFWriteDirectoryData*) rd;
  641     TIFFWriteDirectory(r->tif);
  642     char tbuf[1];   // trigger signal
  643     tbuf[0] = 0xFF;
  644     Sys::write(r->pfd, tbuf, 1);
  645     return (NULL);
  646 }
  647 
  648 /*
  649  * Receive a page of data.
  650  *
  651  * This routine is called after receiving training or after
  652  * sending a post-page response in a multi-page document.
  653  */
  654 bool
  655 Class1Modem::recvPage(TIFF* tif, u_int& ppm, fxStr& emsg, const fxStr& id, u_int maxPages)
  656 {
  657     if (lastPPM == FCF_MPS && prevPage) {
  658     /*
  659      * Resume sending HDLC frame (send data)
  660      * The carrier is already raised.  Thus we
  661      * use sendFrame() instead of transmitFrame().
  662      */
  663     if (pageGood) {
  664         startTimeout(7550);
  665         (void) sendFrame((sendERR ? FCF_ERR : FCF_MCF)|FCF_RCVR);
  666         stopTimeout("sending HDLC frame");
  667         lastMCF = Sys::now();
  668     } else if (conf.badPageHandling == FaxModem::BADPAGE_RTNSAVE) {
  669         startTimeout(7550);
  670         (void) sendFrame(FCF_RTN|FCF_RCVR);
  671         stopTimeout("sending HDLC frame");
  672         FaxParams dis = modemDIS();
  673         if (!recvIdentification(0, fxStr::null, 0, fxStr::null, 
  674         0, fxStr::null, 0, fxStr::null, 0, dis,
  675         conf.class1RecvIdentTimer, true, emsg)) {
  676         return (false);
  677         }
  678     }
  679     }
  680 
  681     time_t t2end = 0;
  682     signalRcvd = 0;
  683     sendERR = false;
  684     gotCONNECT = true;
  685 
  686     do {
  687     ATResponse rmResponse = AT_NOTHING;
  688     long timer = conf.t2Timer;
  689     if (!messageReceived) {
  690         if (sendCFR ) {
  691 #if defined(HAVE_SSL)
  692         if (!isSSLFax && useSSLFax && remoteCSAType == 0x40 && remoteCSAinfo.length()) {
  693             protoTrace("Connecting to %s for SSL Fax transmission.", (const char*) remoteCSAinfo);
  694             SSLFax sslfax;
  695             sslFaxProcess = sslfax.startClient(remoteCSAinfo, sslFaxPasscode, rtcRev, conf.class1SSLFaxServerTimeout);
  696             if (sslFaxProcess.emsg != "") protoTrace("SSL Fax: \"%s\"", (const char*) sslFaxProcess.emsg);
  697             if (!sslFaxProcess.server) {
  698             protoTrace("SSL Fax connection failed.");
  699             if (!conf.class1SSLFaxInfo.length()) useSSLFax = false;
  700             } else {
  701             protoTrace("SSL Fax connection was successful.");
  702             isSSLFax = true;
  703             }
  704         }
  705 
  706         if (!isSSLFax && useSSLFax && conf.class1SSLFaxInfo.length()) {
  707             SSLFax sslfax;
  708             sslFaxProcess = sslfax.startServer(conf.class1SSLFaxInfo, conf.class1SSLFaxCert);
  709             if (sslFaxProcess.emsg.length()) protoTrace("SSL Fax: \"%s\"", (const char*) sslFaxProcess.emsg);
  710             if (sslFaxProcess.server == 0 ) {
  711             setSSLFaxFd(0);
  712             useSSLFax = false;
  713             }
  714             if (useSSLFax) {
  715             fxStr csa;
  716             encodeCSA(csa, conf.class1SSLFaxInfo);
  717             protoTrace("Send CSA frame to accept HylaFAX SSL fax feature.");
  718             startTimeout(7550);
  719             transmitFrame(FCF_CSA|FCF_RCVR, csa, false);
  720             stopTimeout("sending CSA frame");
  721             startTimeout(7550);
  722             sendFrame(FCF_CFR|FCF_RCVR);
  723             stopTimeout("sending CFR frame");
  724             } else {
  725             startTimeout(7550);
  726             transmitFrame(FCF_CFR|FCF_RCVR);
  727             stopTimeout("sending CFR frame");
  728             }
  729         } else {
  730 #endif
  731             startTimeout(7550);
  732             transmitFrame(FCF_CFR|FCF_RCVR);
  733             stopTimeout("sending CFR frame");
  734 #if defined(HAVE_SSL)
  735         }
  736 #endif
  737         sendCFR = false;
  738 #if defined(HAVE_SSL)
  739         if (!isSSLFax) {
  740             if (sslFaxProcess.server && useSSLFax) {
  741             // We setSSLFaxFd here because we needed to get the modem's "OK" before interfering with modem reads.
  742             setSSLFaxFd(sslFaxProcess.server);  // tells ModemServer to also watch for an incoming SSL Fax connection
  743             } else {
  744             // Seems that both we and the sender support internet fax, but there is no service advertised.
  745             useSSLFax = false;
  746             }
  747         }
  748 #endif
  749         }
  750         pageGood = pageStarted = false;
  751         resetLineCounts();      // in case we don't make it to initializeDecoder
  752         recvSetupTIFF(tif, group3opts, FILLORDER_LSB2MSB, id);
  753         rmResponse = AT_NOTHING;
  754         if (params.ec != EC_DISABLE || useV34) {
  755         pageGood = recvPageData(tif, emsg);
  756         messageReceived = true;
  757         prevPage++;
  758         } else {
  759         bool retryrmcmd;
  760         int rmattempted = 0;
  761         do {
  762             retryrmcmd = false;
  763             /*
  764              * Look for message carrier and receive Phase C data.
  765              */
  766             /*
  767              * Same reasoning here as before receiving TCF.
  768              */
  769             if (!isSSLFax && !atCmd(conf.class1MsgRecvHackCmd, AT_OK)) {
  770             emsg = "Failure to receive silence (synchronization failure). {E100}";
  771             return (false);
  772             }
  773             /*
  774              * Set high speed carrier & start receive.  If the
  775              * negotiated modulation technique includes short
  776              * training, then we use it here (it's used for all
  777              * high speed carrier traffic other than the TCF).
  778              *
  779              * Timing here is very critical.  It is more "tricky" than timing
  780              * for AT+FRM for TCF because unlike with TCF, where the direction
  781              * of communication doesn't change, here it does change because 
  782              * we just sent CFR but now have to do AT+FRM.  In practice, if we 
  783              * issue AT+FRM after the sender does AT+FTM then we'll get +FCERROR.
  784              * Using Class1MsgRecvHackCmd often only complicates the problem.
  785              * If the modem doesn't drop its transmission carrier (OK response
  786              * following CFR) quickly enough, then we'll see more +FCERROR.
  787              */
  788             fxStr rmCmd(curcap[HasShortTraining(curcap)].value, rmCmdFmt);
  789             u_short attempts = 0;
  790             if (!isSSLFax) {
  791             if (useSSLFax) sslWatchModem = true;
  792             do {
  793                 (void) atCmd(rmCmd, AT_NOTHING);
  794                 rmResponse = atResponse(rbuf, conf.class1RMPersistence ? conf.t2Timer + 2900 : conf.t2Timer - 2900);
  795             } while ((rmResponse == AT_NOTHING || rmResponse == AT_FCERROR) && ++attempts < conf.class1RMPersistence && !getSSLFaxConnection());
  796 #if defined(HAVE_SSL)
  797             if (useSSLFax) {
  798                 SSLFax sslfax;
  799                 if (!getSSLFaxConnection()) {
  800                 protoTrace("Traditional fax detected.  Shutting down SSL Fax listener.");
  801                 sslfax.cleanup(sslFaxProcess);
  802                 useSSLFax = false;
  803                 sslWatchModem = false;
  804                 setSSLFaxFd(0);
  805                 } else {
  806                 protoTrace("SSL Fax connection detected.");
  807                 sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
  808                 if (sslFaxProcess.emsg != "") protoTrace("SSL Fax accept client: %s", (const char*) sslFaxProcess.emsg);
  809                 if (!sslFaxProcess.server) {
  810                     protoTrace("SSL Fax client accept failure.  Expecting a traditional fax now.");
  811                     sslfax.cleanup(sslFaxProcess);
  812                     useSSLFax = false;
  813                     sslWatchModem = false;
  814                     setSSLFaxFd(0);
  815                     do {
  816                     rmResponse = atResponse(rbuf, conf.class1RMPersistence ? conf.t2Timer + 2900 : conf.t2Timer - 2900);
  817                     } while ((rmResponse == AT_NOTHING || rmResponse == AT_FCERROR) && ++attempts < conf.class1RMPersistence && atCmd(rmCmd, AT_NOTHING));
  818                     } else {
  819                     isSSLFax = true;
  820                 }
  821                 }
  822             }
  823 #endif
  824             }
  825             if (isSSLFax || rmResponse == AT_CONNECT) {
  826             /*
  827              * We don't want the AT+FRM=n command to get buffered,
  828              * so buffering and flow control must be done after CONNECT.
  829              * Flushing now would be a mistake as data may already be
  830              * in the buffer.
  831              */
  832             setInputBuffering(true);
  833             if (flowControl == FLOW_XONXOFF)
  834                 (void) setXONXOFF(FLOW_NONE, FLOW_XONXOFF, ACT_NOW);
  835             /*
  836              * The message carrier was recognized;
  837              * receive the Phase C data.
  838              */
  839             protoTrace("RECV: begin page");
  840             pageGood = recvPageData(tif, emsg);
  841             protoTrace("RECV: end page");
  842             if (wasSSLFax) {
  843                 wasSSLFax = false;
  844             } else if (!wasTimeout()) {
  845                 /*
  846                  * The data was received correctly, wait patiently
  847                  * for the modem to signal carrier drop.  Some senders
  848                  * may send a lot of garbage after RTC, so be patient.
  849                  */
  850                 time_t nocarrierstart = Sys::now();
  851                 do {
  852                 messageReceived = (isSSLFax || waitFor(AT_NOCARRIER, 60*1000));
  853                 } while (!messageReceived && Sys::now() < (nocarrierstart + 60));
  854                 if (messageReceived)
  855                 prevPage++;
  856                     timer = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;  // wait longer for PPM (estimate 80KB)
  857             }
  858             } else {
  859             if (wasTimeout()) {
  860                 abortReceive();     // return to command mode
  861                 setTimeout(false);
  862             }
  863             bool getframe = false;
  864             long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
  865             if (rmResponse == AT_FRH3) getframe = waitFor(AT_CONNECT, wait);
  866             else if (!isSSLFax && rmResponse != AT_NOCARRIER && rmResponse != AT_ERROR) getframe = atCmd(rhCmd, AT_CONNECT, wait);  // wait longer
  867             if (getframe) {
  868                 HDLCFrame frame(conf.class1FrameOverhead);
  869                 if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true, false)) {
  870                 traceFCF("RECV recv", frame.getFCF());
  871                 signalRcvd = frame.getFCF();
  872                 messageReceived = true;
  873                 } else {
  874                 /*
  875                  * V.21 HDLC was detected and then the carrier was lost without
  876                  * receiving any data.  It's possible that the modem erred in 
  877                  * its detection of the high-speed carrier.  But, it's also 
  878                  * possible that echo of our CFR was detected or that there is 
  879                  * another receiver on the line (another fax machine sharing the 
  880                  * line on the send-side), and we heard them.  Often we can still 
  881                  * acquire the high-speed carrier if we just re-issue AT+FRM=n.
  882                  */
  883                 if (lastResponse == AT_NOCARRIER) retryrmcmd = true;
  884                 }
  885             }
  886             }
  887         } while (retryrmcmd && ++rmattempted < 2);
  888         }
  889         if (signalRcvd != 0) {
  890         if (flowControl == FLOW_XONXOFF)
  891             (void) setXONXOFF(FLOW_NONE, FLOW_NONE, ACT_DRAIN);
  892         setInputBuffering(false);
  893         }
  894         if (!messageReceived && rmResponse != AT_FCERROR && rmResponse != AT_FRH3) {
  895         if (rmResponse != AT_ERROR) {
  896             /*
  897              * One of many things may have happened:
  898              * o if we lost carrier, then some modems will return
  899              *   AT_NOCARRIER or AT_EMPTYLINE in response to the
  900              *   AT+FRM request.
  901              * o otherwise, there may have been a timeout receiving
  902              *   the message data, or there was a timeout waiting
  903              *   for the carrier to drop.
  904              */
  905             if (!wasTimeout()) {
  906             /*
  907              * We found the wrong carrier, which means that there
  908              * is an HDLC frame waiting for us--in which case it
  909              * should get picked up below.
  910              */
  911             break;
  912             }
  913             /*
  914              * The timeout expired - thus we missed the carrier either
  915              * raising or dropping.
  916              */
  917             abortReceive();     // return to command state
  918             break;
  919         } else {
  920             /*
  921              * Some modems respond ERROR instead +FCERROR on wrong carrier
  922              * and not return to command state.
  923              */
  924             abortReceive();     // return to command state
  925         }
  926         }
  927     }
  928     /*
  929      * T.30 says to process operator intervention requests
  930      * here rather than before the page data is received.
  931      * This has the benefit of not recording the page as
  932      * received when the post-page response might need to
  933      * be retransmited.
  934      */
  935     if (abortRequested()) {
  936         // XXX no way to purge TIFF directory
  937         emsg = "Receive aborted due to operator intervention {E301}";
  938         return (false);
  939     }
  940 
  941     /*
  942      * Acknowledge PPM from ECM protocol.
  943      */
  944     HDLCFrame frame(conf.class1FrameOverhead);
  945     bool ppmrcvd;
  946     if (signalRcvd != 0) {
  947         ppmrcvd = true;
  948         lastPPM = signalRcvd;
  949         for (u_int i = 0; i < frameRcvd.length(); i++) frame.put(frameRcvd[i]);
  950         frame.setOK(true);
  951     } else {
  952         gotCONNECT = false;
  953         u_short recvFrameCount = 0;
  954         time_t ppmstart = Sys::now();
  955         do {
  956         /*
  957          * Some modems will report CONNECT erroniously on high-speed Phase C data.
  958          * Then they will time-out on HDLC data presentation instead of dumping
  959          * garbage or quickly resulting ERROR.  So we give instances where CONNECT
  960          * occurs a bit more tolerance here...
  961          */
  962         ppmrcvd = recvFrame(frame, FCF_RCVR, timer);
  963         } while (!ppmrcvd && gotCONNECT && wasTimeout() && !gotEOT && ++recvFrameCount < 3);
  964         if (ppmrcvd) lastPPM = frame.getFCF();
  965         /*
  966          * To combat premature carrier loss leading to MCF instead of RTN on short/partial pages,
  967          * We started a timer above and measured the time it took to receive PPM.  If longer
  968          * longer than 5 seconds, and if we did not see RTC, then we assume that premature
  969          * carrier loss occurred and set pageGood to false.
  970          */
  971         if (Sys::now() - ppmstart > 5 && !getSeenRTC()) {
  972         protoTrace("RECV detected premature Phase C carrier loss.");
  973         pageGood = false;
  974         }
  975     }
  976     /*
  977      * Do command received logic.
  978      */
  979     if (ppmrcvd) {
  980         switch (lastPPM) {
  981         case FCF_DIS:           // XXX no support
  982         if (!pageGood) recvResetPage(tif);
  983         protoTrace("RECV DIS/DTC");
  984         emsg = "Can not continue after DIS/DTC {E107}";
  985         return (false);
  986         case FCF_PWD:
  987         case FCF_SUB:
  988         case FCF_NSS:
  989         case FCF_TSI:
  990         case FCF_DCS:
  991         {
  992             signalRcvd = 0;
  993             if (!pageGood) recvResetPage(tif);
  994             // look for high speed carrier only if training successful
  995             messageReceived = !(FaxModem::recvBegin(NULL, emsg));
  996             bool trainok = true;
  997             short traincount = 0;
  998             do {
  999             if (!messageReceived) messageReceived = !(recvDCSFrames(frame));
 1000             if (recvdDCN) {
 1001                 messageReceived = true;
 1002                 signalRcvd = FCF_DCN;
 1003                 lastResponse = AT_NOTHING;
 1004                 return (false);
 1005             }
 1006             if (!messageReceived) {
 1007                 trainok = recvTraining();
 1008                 messageReceived = (!trainok && lastResponse == AT_FRH3);
 1009             }
 1010             } while (!trainok && traincount++ < 3 && lastResponse != AT_FRH3 && recvFrame(frame, FCF_RCVR, timer));
 1011             if (messageReceived && lastResponse == AT_FRH3 && waitFor(AT_CONNECT, conf.t2Timer)) {
 1012             messageReceived = false;
 1013             if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true, false)) {
 1014                 messageReceived = true;
 1015                 signalRcvd = frame.getFCF();
 1016             }
 1017             if (!frame.getLength() && lastResponse == AT_NOCARRIER) {
 1018                 // The modem may have indicated V.21 HDLC incorrectly.  TCF may be coming.  Get ready.
 1019                 trainok = recvTraining();
 1020                 messageReceived = (!trainok && lastResponse == AT_FRH3);
 1021                 if (messageReceived && lastResponse == AT_FRH3 && waitFor(AT_CONNECT, conf.t2Timer)) {
 1022                 messageReceived = false;
 1023                 if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true)) {
 1024                     messageReceived = true;
 1025                     signalRcvd = frame.getFCF();
 1026                 }
 1027                 }
 1028             }
 1029             lastResponse = AT_NOTHING;
 1030             } else messageReceived = false;
 1031             break;
 1032         }
 1033         case FCF_MPS:           // MPS
 1034         case FCF_EOM:           // EOM
 1035         case FCF_EOP:           // EOP
 1036         case FCF_PRI_MPS:           // PRI-MPS
 1037         case FCF_PRI_EOM:           // PRI-EOM
 1038         case FCF_PRI_EOP:           // PRI-EOP
 1039         if (!getRecvEOLCount()) {
 1040             // We have a null page, don't save it because it makes readers fail.
 1041             pageGood = false;
 1042             if (params.ec != EC_DISABLE) {
 1043             if (emsg == "") {
 1044                 /*
 1045                  * We negotiated ECM, got no valid ECM image data, and the 
 1046                  * ECM page reception routines did not set an error message.
 1047                  * The empty emsg is due to the ECM routines detecting a 
 1048                  * non-ECM-specific partial-page signal and wants it to
 1049                  * be handled here.  The sum total of all of this, and the 
 1050                  * fact that we got MPS/EOP/EOM tells us that the sender
 1051                  * is not using ECM.  In an effort to salvage the session we'll
 1052                  * disable ECM now and try to continue.
 1053                  */
 1054                 params.ec = EC_DISABLE;
 1055             } else
 1056                 return (false);
 1057             }
 1058         }
 1059         if (!pageGood && conf.badPageHandling == FaxModem::BADPAGE_RTN)
 1060             recvResetPage(tif);
 1061         if (signalRcvd == 0) traceFCF("RECV recv", lastPPM);
 1062 
 1063         /*
 1064          * [Re]transmit post page response.
 1065          */
 1066         if (pageGood || (conf.badPageHandling == FaxModem::BADPAGE_RTNSAVE && getRecvEOLCount())) {
 1067             if (!pageGood) lastPPM = FCF_MPS;   // FaxModem::BADPAGE_RTNSAVE
 1068             /*
 1069              * If post page message confirms the page
 1070              * that we just received, write it to disk.
 1071              */
 1072             if (messageReceived) {
 1073             if (!useV34 && emsg == "") (void) switchingPause(emsg);
 1074             /*
 1075              * On servers where disk access may be bottlenecked or stressed,
 1076              * the TIFFWriteDirectory call can lag.  The strategy, then, is
 1077              * to employ RNR/RR flow-control for ECM sessions and to use CRP
 1078              * in non-ECM sessions in order to grant TIFFWriteDirectory
 1079              * sufficient time to complete.
 1080              *
 1081              * We used to do this with a forked process, but because in an
 1082              * SSL Fax session immovable data is being manipulated both with
 1083              * the SSL operations as well as with the TIFF operation, it is
 1084              * much easier to use threads rather than ensure one of those
 1085              * operations is conducted entirely in memory shared between the
 1086              * forked processes.
 1087              */
 1088             int fcfd[2];        // flow control file descriptors for the pipe
 1089             if (pipe(fcfd) >= 0) {
 1090 
 1091                 // Start the thread calling TIFFWriteDirectory.
 1092                 pthread_t t;
 1093                 recvTIFFWriteDirectoryData r(fcfd[1], tif);
 1094                 if (pthread_create(&t, NULL, &recvTIFFWriteDirectory, (void *) &r) == 0) {
 1095 
 1096                 char tbuf[1];   // trigger signal
 1097                 tbuf[0] = 0xFF;
 1098                 time_t rrstart = Sys::now();
 1099                 do {
 1100                     fd_set rfds;
 1101                     FD_ZERO(&rfds);
 1102                     FD_SET(fcfd[0], &rfds);
 1103                     struct timeval tv;
 1104                     tv.tv_sec = 2;      // we've got a 3-second window, use it
 1105                     tv.tv_usec = 0;
 1106 #if CONFIG_BADSELECTPROTO
 1107                     if (!select(fcfd[0]+1, (int*) &rfds, NULL, NULL, &tv)) {
 1108 #else
 1109                     if (!select(fcfd[0]+1, &rfds, NULL, NULL, &tv)) {
 1110 #endif
 1111                     bool gotresponse = true;
 1112                     u_short rnrcnt = 0;
 1113                     do {
 1114                         if (emsg != "") break;
 1115                         (void) transmitFrame(params.ec != EC_DISABLE ? FCF_RNR : FCF_CRP|FCF_RCVR);
 1116                         traceFCF("RECV send", params.ec != EC_DISABLE ? FCF_RNR : FCF_CRP);
 1117                         HDLCFrame rrframe(conf.class1FrameOverhead);
 1118                         gotresponse = recvFrame(rrframe, FCF_RCVR, conf.t2Timer);
 1119                         if (gotresponse) {
 1120                         traceFCF("RECV recv", rrframe.getFCF());
 1121                         if (rrframe.getFCF() == FCF_DCN) {
 1122                             protoTrace("RECV recv DCN");
 1123                             emsg = "COMREC received DCN (sender abort) {E108}";
 1124                             gotEOT = true;
 1125                             recvdDCN = true;
 1126                         } else if (params.ec != EC_DISABLE && rrframe.getFCF() != FCF_RR) {
 1127                             protoTrace("Ignoring invalid response to RNR.");
 1128                         }
 1129                         (void) switchingPause(emsg);
 1130                         }
 1131                     } while (!gotEOT && !recvdDCN && !gotresponse && ++rnrcnt < 2 && Sys::now()-rrstart < 60);
 1132                     if (!gotresponse) emsg = "No response to RNR repeated 3 times. {E109}";
 1133                     } else {        // thread finished TIFFWriteDirectory
 1134                     tbuf[0] = 0;
 1135                     }
 1136                 } while (!gotEOT && !recvdDCN && tbuf[0] != 0 && Sys::now()-rrstart < 60);
 1137                 Sys::read(fcfd[0], NULL, 1);
 1138                 pthread_join(t, NULL);
 1139                 } else {
 1140                 protoTrace("Protocol flow control unavailable due to threading error.");
 1141                 TIFFWriteDirectory(tif);
 1142                 }
 1143                 Sys::close(fcfd[0]);
 1144                 Sys::close(fcfd[1]);
 1145             } else {
 1146                 protoTrace("Protocol flow control unavailable due to pipe error.");
 1147                 TIFFWriteDirectory(tif);
 1148             }
 1149             if (emsg == "" && prevPage > maxPages) {
 1150                 protoTrace("Number of pages received (%d) exceeds maxRecvPages (%d).", prevPage, maxPages);
 1151                 emsg = "Maximum receive page count exceeded";
 1152             }
 1153             if (emsg == "") {   // confirm only if there was no error
 1154                 if (pageGood) {
 1155                 traceFCF("RECV send", sendERR ? FCF_ERR : FCF_MCF);
 1156                 lastMCF = Sys::now();
 1157                 } else
 1158                 traceFCF("RECV send", FCF_RTN);
 1159 
 1160                 if (lastPPM == FCF_MPS) {
 1161                 /*
 1162                  * Raise the HDLC transmission carrier but do not
 1163                  * transmit MCF now.  This gives us at least a 3-second
 1164                  * window to buffer any delays in the post-page
 1165                  * processes.
 1166                  */
 1167                 if (!useV34 && !isSSLFax && !atCmd(thCmd, AT_CONNECT)) {
 1168                     emsg = "Failure to raise V.21 transmission carrier. {E101}";
 1169                     return (false);
 1170                 }
 1171                 } else {
 1172                 (void) transmitFrame((sendERR ? FCF_ERR : FCF_MCF)|FCF_RCVR);
 1173                 lastMCF = Sys::now();
 1174                 if (lastPPM == FCF_EOP) {
 1175                     /*
 1176                      * Because there are a couple of notifications that occur after this
 1177                      * things can hang and we can miss hearing DCN.  So we do it now.
 1178                      */
 1179                     recvdDCN = recvEnd(NULL, emsg);
 1180                 }
 1181                 }
 1182             }
 1183             /*
 1184              * Reset state so that the next call looks
 1185              * first for page carrier or frame according
 1186              * to what's expected.  (Grr, where's the
 1187              * state machine...)
 1188              */
 1189             messageReceived = (lastPPM == FCF_EOM);
 1190             ppm = modemPPMCodes[lastPPM&7];
 1191             return (true);
 1192             }
 1193         } else {
 1194             /*
 1195              * Page not received, or unacceptable; tell
 1196              * other side to retransmit after retrain.
 1197              */
 1198             /*
 1199              * As recommended in T.31 Appendix II.1, we try to
 1200              * prevent the rapid switching of the direction of 
 1201              * transmission by using +FRS.  Theoretically, "OK"
 1202              * is the only response, but if the sender has not
 1203              * gone silent, then we cannot continue anyway,
 1204              * and aborting here will give better information.
 1205              *
 1206              * Using +FRS is better than a software pause, which
 1207              * could not ensure loss of carrier.  +FRS is easier
 1208              * to implement than using +FRH and more reliable than
 1209              * using +FTS
 1210              */
 1211             if (!switchingPause(emsg)) {
 1212             return (false);
 1213             }
 1214             signalRcvd = 0;
 1215             if (params.ec == EC_DISABLE && rmResponse != AT_CONNECT && !getRecvEOLCount() && (Sys::now() - lastMCF < 9)) {
 1216             /*
 1217              * We last transmitted MCF a very, very short time ago, received no image data
 1218              * since then, and now we're seeing a PPM again.  In non-ECM mode the chances of 
 1219              * this meaning that we simply missed a very short page is extremely remote.  It
 1220              * probably means that the sender did not properly hear our MCF and that we just
 1221              * need to retransmit it. 
 1222              */
 1223             (void) transmitFrame(FCF_MCF|FCF_RCVR);
 1224             traceFCF("RECV send", FCF_MCF);
 1225             lastMCF = Sys::now();
 1226             messageReceived = (lastPPM != FCF_MPS); // expect Phase C if MPS
 1227             } else {
 1228             u_int rtnfcf = FCF_RTN;
 1229             if (!getRecvEOLCount() || conf.badPageHandling == FaxModem::BADPAGE_DCN) {
 1230                 /*
 1231                  * Regardless of the BadPageHandling setting, if we get no page image data at
 1232                  * all, then sending RTN at all risks confirming the non-page to RTN-confused 
 1233                  * senders, which risk is far worse than just simply hanging up.
 1234                  */
 1235                 emsg = "PPM received with no image data.  To continue risks receipt confirmation. {E155}";
 1236                 rtnfcf = FCF_DCN;
 1237             }
 1238             (void) transmitFrame(rtnfcf|FCF_RCVR);
 1239             traceFCF("RECV send", rtnfcf);
 1240             if (rtnfcf == FCF_DCN) {
 1241                 recvdDCN = true;
 1242                 return (false);
 1243             }
 1244             /*
 1245              * Reset the TIFF-related state so that subsequent
 1246              * writes will overwrite the previous data.
 1247              */
 1248             messageReceived = true; // expect DCS next
 1249             }
 1250         }
 1251         break;
 1252         case FCF_RR:
 1253         // The sender did not hear our MCF signal.  Treat it like CRP.
 1254         case FCF_CRP:
 1255         // command repeat... just repeat whatever we last sent
 1256         if (!switchingPause(emsg)) return (false);
 1257         transmitFrame(signalSent);
 1258         traceFCF("RECV send", (u_char) signalSent[2]);
 1259         /* fall through - to clear messageReceived and signalRcvd */
 1260         case FCF_MCF:
 1261         case FCF_CFR:
 1262         /* It's probably just our own echo. */
 1263         messageReceived = false;
 1264         signalRcvd = 0;
 1265         break;
 1266         case FCF_DCN:           // DCN
 1267         protoTrace("RECV recv DCN");
 1268         emsg = "COMREC received DCN (sender abort) {E108}";
 1269         recvdDCN = true;
 1270         if (prevPage && conf.saveUnconfirmedPages && getRecvEOLCount()) {   // only if there was data
 1271             TIFFWriteDirectory(tif);
 1272             protoTrace("RECV keeping unconfirmed page");
 1273             return (true);
 1274         }
 1275         return (false);
 1276         default:
 1277         if (!pageGood) recvResetPage(tif);
 1278         emsg = "COMREC invalid response received {E110}";
 1279         return (false);
 1280         }
 1281         t2end = 0;
 1282     } else {
 1283         /*
 1284          * We didn't get a message.  Try to be resiliant by
 1285          * looking for the signal again, but prevent infinite
 1286          * looping with a timer.  However, if the modem is on
 1287          * hook, then modem responds ERROR or NO CARRIER, and
 1288          * for those cases there is no point in resiliancy.
 1289          */
 1290         if (lastResponse == AT_NOCARRIER || lastResponse == AT_ERROR) break;
 1291         if (t2end) {
 1292         if (Sys::now() > t2end)
 1293             break;
 1294         } else {
 1295         t2end = Sys::now() + howmany(conf.t2Timer, 1000);
 1296         }
 1297     }
 1298     } while (gotCONNECT && !wasTimeout() && lastResponse != AT_EMPTYLINE);
 1299     emsg = "V.21 signal reception timeout; expected page possibly not received in full {E111}";
 1300     if (prevPage && conf.saveUnconfirmedPages && getRecvEOLCount()) {
 1301     TIFFWriteDirectory(tif);
 1302     protoTrace("RECV keeping unconfirmed page");
 1303     return (true);
 1304     }
 1305     return (false);
 1306 }
 1307 
 1308 void
 1309 Class1Modem::abortPageRecv()
 1310 {
 1311     if (wasSSLFax || isSSLFax || useV34) return;    // nothing to do in V.34
 1312     char c = CAN;               // anything other than DC1/DC3
 1313     putModem(&c, 1, 1);
 1314 }
 1315 
 1316 bool
 1317 Class1Modem::raiseRecvCarrier(bool& dolongtrain, fxStr& emsg)
 1318 {
 1319     if (!atCmd(conf.class1MsgRecvHackCmd, AT_OK)) {
 1320     emsg = "Failure to receive silence (synchronization failure). {E100}";
 1321     return (false);
 1322     }
 1323     /*
 1324      * T.30 Section 5, Note 5 states that we must use long training
 1325      * on the first high-speed data message following CTR.
 1326      */
 1327     fxStr rmCmd;
 1328     if (dolongtrain) rmCmd = fxStr(curcap->value, rmCmdFmt);
 1329     else rmCmd = fxStr(curcap[HasShortTraining(curcap)].value, rmCmdFmt);
 1330     u_short attempts = 0;
 1331     lastResponse = AT_NOTHING;
 1332     if (useSSLFax) sslWatchModem = true;
 1333     do {
 1334     (void) atCmd(rmCmd, AT_NOTHING);
 1335     lastResponse = atResponse(rbuf, conf.class1RMPersistence ? conf.t2Timer + 2900 : conf.t2Timer - 2900);
 1336     } while ((lastResponse == AT_NOTHING || lastResponse == AT_FCERROR) && ++attempts < conf.class1RMPersistence && !getSSLFaxConnection());
 1337 #if defined(HAVE_SSL)
 1338     if (useSSLFax) {
 1339     SSLFax sslfax;
 1340     if (!getSSLFaxConnection()) {
 1341         protoTrace("Traditional fax detected.  Shutting down SSL Fax listener.");
 1342         sslfax.cleanup(sslFaxProcess);
 1343         useSSLFax = false;
 1344         sslWatchModem = false;
 1345         setSSLFaxFd(0);
 1346     } else {
 1347         protoTrace("SSL Fax connection detected.");
 1348         sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
 1349         if (sslFaxProcess.emsg != "") protoTrace("SSL Fax accept client: %s", (const char*) sslFaxProcess.emsg);
 1350         if (!sslFaxProcess.server) {
 1351         protoTrace("SSL Fax client accept failure.  Expecting a traditional fax now.");
 1352         sslfax.cleanup(sslFaxProcess);
 1353         useSSLFax = false;
 1354         sslWatchModem = false;
 1355         setSSLFaxFd(0);
 1356         do {
 1357             lastResponse = atResponse(rbuf, conf.class1RMPersistence ? conf.t2Timer + 2900 : conf.t2Timer - 2900);
 1358         } while ((lastResponse == AT_NOTHING || lastResponse == AT_FCERROR) && ++attempts < conf.class1RMPersistence && atCmd(rmCmd, AT_NOTHING));
 1359         } else {
 1360         isSSLFax = true;
 1361         }
 1362     }
 1363     }
 1364 #endif
 1365     if (lastResponse == AT_ERROR) gotEOT = true;    // on hook
 1366     if (lastResponse == AT_FRH3 && waitFor(AT_CONNECT, conf.t2Timer)) {
 1367     gotRTNC = true;
 1368     gotEOT = false;
 1369     }
 1370     if (lastResponse != AT_CONNECT && !gotRTNC && !isSSLFax) {
 1371     emsg = "Failed to properly detect high-speed data carrier. {E112}";
 1372     return (false);
 1373     }
 1374     dolongtrain = false;
 1375     return (true);
 1376 }
 1377 
 1378 void
 1379 Class1Modem::abortPageECMRecv(TIFF* tif, const Class2Params& params, u_char* block, u_int fcount, u_short seq, bool pagedataseen, fxStr& emsg)
 1380 {
 1381     if (pagedataseen) {
 1382     writeECMData(tif, block, (fcount * frameSize), params, (seq |= 2), emsg);
 1383     if (conf.saveUnconfirmedPages) {
 1384         protoTrace("RECV keeping unconfirmed page");
 1385         prevPage++;
 1386     }
 1387     }
 1388     free(block);
 1389 }
 1390 
 1391 /*
 1392  * Data structure for pthread argument for writeECMData wrapper.
 1393  */
 1394 struct recvWriteECMDataData {
 1395     Class1Modem* obj;
 1396     int pfd;
 1397     TIFF* tif;
 1398     u_char* block;
 1399     u_int cc;
 1400     const Class2Params& params;
 1401     u_short seq;
 1402     fxStr& emsg;
 1403 
 1404     recvWriteECMDataData(Class1Modem* o, int a, TIFF* b, u_char* c, u_int d, const Class2Params& e, u_short f, fxStr& g) :
 1405     obj(o), pfd(a), tif(b), block(c), cc(d), params(e), seq(f), emsg(g) {}
 1406 };
 1407 
 1408 /*
 1409  * Static wrapper function for writeECMData
 1410  * with signal used with pthread.
 1411  */
 1412 void*
 1413 recvWriteECMData(void* rd)
 1414 {
 1415     recvWriteECMDataData *r = (recvWriteECMDataData*) rd;
 1416     (r->obj)->writeECMData(r->tif, r->block, r->cc, r->params, r->seq, r->emsg);
 1417     char tbuf[1];   // trigger signal
 1418     tbuf[0] = 0xFF;
 1419     Sys::write(r->pfd, tbuf, 1);
 1420     return (NULL);
 1421 }
 1422 
 1423 /*
 1424  * Receive Phase C data in T.30-A ECM mode.
 1425  */
 1426 bool
 1427 Class1Modem::recvPageECMData(TIFF* tif, const Class2Params& params, fxStr& emsg)
 1428 {
 1429     HDLCFrame frame(5);                 // A+C+FCF+FCS=5 bytes
 1430     u_char* block = (u_char*) malloc(frameSize*256);    // 256 frames per block - totalling 16/64KB
 1431     fxAssert(block != NULL, "ECM procedure error (receive block).");
 1432     memset(block, 0, (size_t) frameSize*256);
 1433     bool lastblock = false;
 1434     bool pagedataseen = false;
 1435     u_short seq = 1;                    // sequence code for the first block
 1436     prevBlock = 0;
 1437     u_int lastSignalRcvd = 0;
 1438 
 1439     do {
 1440     u_int fnum = 0;
 1441     char ppr[32];                   // 256 bits
 1442     for (u_int i = 0; i < 32; i++) ppr[i] = 0xff;   // ppr defaults to all 1's, T.4 A.4.4
 1443     u_short rcpcnt = 0;
 1444     u_short pprcnt = 0;
 1445     u_int fcount = 0;
 1446     u_short syncattempts = 0;
 1447     bool blockgood = false, dolongtrain = false;
 1448     bool gotoPhaseD = false;
 1449     do {
 1450         sendERR = false;
 1451         resetBlock();
 1452         lastSignalRcvd = signalRcvd;
 1453         signalRcvd = 0;
 1454         rcpcnt = 0;
 1455         bool dataseen = false;
 1456         bool retryrmcmd;
 1457         int rmattempted = 0;
 1458         do {
 1459         retryrmcmd = false;
 1460         if (!isSSLFax && !useV34 && !gotoPhaseD) {
 1461             gotRTNC = false;
 1462             if (!raiseRecvCarrier(dolongtrain, emsg) && !gotRTNC && !isSSLFax) {
 1463             if (wasTimeout()) {
 1464                 abortReceive();     // return to command mode
 1465                 setTimeout(false);
 1466             }
 1467             long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
 1468             if (lastResponse != AT_NOCARRIER && atCmd(rhCmd, AT_CONNECT, wait)) {   // wait longer
 1469                 // sender is transmitting V.21 instead, we may have
 1470                 // missed the first signal attempt, but should catch
 1471                 // the next attempt.  This "simulates" adaptive receive.
 1472                 emsg = "";  // reset
 1473                 gotRTNC = true;
 1474             } else {
 1475                 if (wasTimeout()) abortReceive();
 1476                 abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1477                 return (false);
 1478             }
 1479             }
 1480         }
 1481         if ((!isSSLFax && useV34) || gotRTNC) {     // V.34 mode or if +FRH:3 in adaptive reception
 1482             if (!gotEOT) {
 1483             bool gotprimary = false;
 1484             if (!isSSLFax && useV34) {
 1485                 if (useSSLFax) sslWatchModem = true;
 1486                 gotprimary = waitForDCEChannel(false);
 1487 #if defined(HAVE_SSL)
 1488                 if (useSSLFax) {
 1489                 SSLFax sslfax;
 1490                 if (!getSSLFaxConnection()) {
 1491                     protoTrace("Traditional fax detected.  Shutting down SSL Fax listener.");
 1492                     sslfax.cleanup(sslFaxProcess);
 1493                     useSSLFax = false;
 1494                     sslWatchModem = false;
 1495                     setSSLFaxFd(0);
 1496                 } else {
 1497                     protoTrace("SSL Fax connection detected.");
 1498                     sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
 1499                     if (sslFaxProcess.emsg != "") protoTrace("SSL Fax accept client: %s", (const char*) sslFaxProcess.emsg);
 1500                     if (!sslFaxProcess.server) {
 1501                     protoTrace("SSL Fax client accept failure.  Expecting a traditional fax now.");
 1502                     sslfax.cleanup(sslFaxProcess);
 1503                     useSSLFax = false;
 1504                     sslWatchModem = false;
 1505                     setSSLFaxFd(0);
 1506                     gotprimary = waitForDCEChannel(false);  // resume V.34-Fax session
 1507                     } else {
 1508                     isSSLFax = true;
 1509                     }
 1510                 }
 1511                 }
 1512 #endif
 1513             }
 1514             while (!sendERR && !gotEOT && (gotRTNC || (ctrlFrameRcvd != fxStr::null))) {
 1515                 /*
 1516                  * Remote requested control channel retrain, the remote didn't
 1517                  * properly hear our last signal, and/or we got an EOR signal 
 1518                  * after PPR.  So now we have to use a signal from the remote
 1519                  * and then respond appropriately to get us back or stay in sync.
 1520                  * DCS::CFR - PPS::PPR/MCF - EOR::ERR
 1521                  */
 1522                 HDLCFrame rtncframe(conf.class1FrameOverhead);
 1523                 bool gotrtncframe = false;
 1524                 if (!isSSLFax && useV34) {
 1525                 if (ctrlFrameRcvd != fxStr::null) {
 1526                     gotrtncframe = true;
 1527                     for (u_int i = 0; i < ctrlFrameRcvd.length(); i++)
 1528                     rtncframe.put(frameRev[ctrlFrameRcvd[i] & 0xFF]);
 1529                     traceHDLCFrame("-->", rtncframe);
 1530                 } else
 1531                     gotrtncframe = recvFrame(rtncframe, FCF_RCVR, conf.t2Timer);
 1532                 } else {
 1533                 gotrtncframe = recvFrame(rtncframe, FCF_RCVR, conf.t2Timer, true, false);
 1534                 }
 1535                 if (gotrtncframe) {
 1536                 traceFCF("RECV recv", rtncframe.getFCF());
 1537                 switch (rtncframe.getFCF()) {
 1538                     case FCF_PPS:
 1539                     if (rtncframe.getLength() > 5) {
 1540                         u_int fc = frameRev[rtncframe[6]] + 1;
 1541                         if ((fc == 256 || fc == 1) && !dataseen) fc = 0;    // distinguish 0 from 1 and 256
 1542                         traceFCF("RECV recv", rtncframe.getFCF2());
 1543                         u_int pgcount = u_int(prevPage/256)*256+frameRev[rtncframe[4]]; // cope with greater than 256 pages
 1544                         protoTrace("RECV received %u frames of block %u of page %u", \
 1545                         fc, frameRev[rtncframe[5]]+1, pgcount+1);
 1546                         switch (rtncframe.getFCF2()) {
 1547                         case 0:     // PPS-NULL
 1548                         case FCF_EOM:
 1549                         case FCF_MPS:
 1550                         case FCF_EOP:
 1551                         case FCF_PRI_EOM:
 1552                         case FCF_PRI_MPS:
 1553                         case FCF_PRI_EOP:
 1554                             if (!switchingPause(emsg)) {
 1555                             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1556                             return (false);
 1557                             }
 1558                             if (pgcount > prevPage || (pgcount == prevPage && frameRev[rtncframe[5]] >= prevBlock)) {
 1559                             (void) transmitFrame(FCF_PPR, fxStr(ppr, 32));
 1560                             traceFCF("RECV send", FCF_PPR);
 1561                             } else {
 1562                             (void) transmitFrame(FCF_MCF|FCF_RCVR);
 1563                             traceFCF("RECV send", FCF_MCF);
 1564                             }
 1565                             break;
 1566                         }
 1567                     }
 1568                     break;
 1569                     case FCF_EOR:
 1570                     if (rtncframe.getLength() > 5) {
 1571                         traceFCF("RECV recv", rtncframe.getFCF2());
 1572                         switch (rtncframe.getFCF2()) {
 1573                         case 0:     // PPS-NULL
 1574                         case FCF_EOM:
 1575                         case FCF_MPS:
 1576                         case FCF_EOP:
 1577                         case FCF_PRI_EOM:
 1578                         case FCF_PRI_MPS:
 1579                         case FCF_PRI_EOP:
 1580                             if (fcount) {
 1581                             /*
 1582                              * The block hasn't been written to disk.
 1583                              * This is expected when the sender sends
 1584                              * EOR after our PPR (e.g. after the 4th).
 1585                              */
 1586                             blockgood = true;
 1587                             signalRcvd = rtncframe.getFCF2();
 1588                             if (signalRcvd) lastblock = true;
 1589                             sendERR = true;
 1590                             } else {
 1591                             if (!switchingPause(emsg)) {
 1592                                 abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1593                                 return (false);
 1594                             }
 1595                             (void) transmitFrame(FCF_ERR|FCF_RCVR);
 1596                             traceFCF("RECV send", FCF_ERR);
 1597                             }
 1598                             break;
 1599                         }
 1600                     }
 1601                     break;
 1602                     case FCF_CTC:
 1603                     {
 1604                         u_int dcs;          // possible bits 1-16 of DCS in FIF
 1605                         if (isSSLFax || useV34) {
 1606                         // T.30 F.3.4.5 Note 1 does not permit CTC in V.34-fax
 1607                         emsg = "Received invalid CTC signal in V.34-Fax. {E113}";
 1608                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1609                         return (false);
 1610                         }
 1611                         /*
 1612                          * See the other comments about T.30 A.1.3.  Some senders
 1613                          * are habitually wrong in sending CTC at incorrect moments.
 1614                          */
 1615                         // use 16-bit FIF to alter speed, curcap
 1616                         dcs = rtncframe[3] | (rtncframe[4]<<8);
 1617                         curcap = findSRCapability(dcs&DCS_SIGRATE, recvCaps);
 1618                         processNewCapabilityUsage();
 1619                         // requisite pause before sending response (CTR)
 1620                         if (!switchingPause(emsg)) {
 1621                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1622                         return (false);
 1623                         }
 1624                         (void) transmitFrame(FCF_CTR|FCF_RCVR);
 1625                         traceFCF("RECV send", FCF_CTR);
 1626                         dolongtrain = true;
 1627                         pprcnt = 0;
 1628                         break;
 1629                     }
 1630                     case FCF_CRP:
 1631                     // command repeat... just repeat whatever we last sent
 1632                     if (!switchingPause(emsg)) {
 1633                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1634                         return (false);
 1635                     }
 1636                     transmitFrame(signalSent);
 1637                     traceFCF("RECV send", (u_char) signalSent[2]);
 1638                     break;
 1639                     case FCF_DCN:
 1640                     emsg = "COMREC received DCN (sender abort) {E108}";
 1641                     gotEOT = true;
 1642                     recvdDCN = true;
 1643                     continue;
 1644                     case FCF_MCF:
 1645                     case FCF_CFR:
 1646                     case FCF_CTR:
 1647                     if ((rtncframe[2] & 0x80) == FCF_RCVR) {
 1648                         /*
 1649                          * Echo on the channel may be so lagged that we're hearing 
 1650                          * ourselves.  Ignore it.  Try again.
 1651                          */
 1652                         break;
 1653                     }
 1654                     /* intentional pass-through */
 1655                     default:
 1656                     // The message is not ECM-specific: fall out of ECM receive, and let
 1657                     // the earlier message-handling routines try to cope with the signal.
 1658                     signalRcvd = rtncframe.getFCF();
 1659                     messageReceived = true;
 1660                     abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1661                     if (getRecvEOLCount() == 0) {
 1662                         prevPage--;     // counteract the forthcoming increment
 1663                         return (true);
 1664                     } else {
 1665                         emsg = "COMREC invalid response received {E110}";   // plain ol' error
 1666                         return (false);
 1667                     }
 1668                 }
 1669                 if (!sendERR) { // as long as we're not trying to send the ERR signal (set above)
 1670                     if (!isSSLFax && useV34) gotprimary = waitForDCEChannel(false);
 1671                     else {
 1672                     gotRTNC = false;
 1673                     if (!isSSLFax && !raiseRecvCarrier(dolongtrain, emsg) && !gotRTNC) {
 1674                         if (wasTimeout()) {
 1675                         abortReceive(); // return to command mode
 1676                         setTimeout(false);
 1677                         }
 1678                         long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
 1679                         if (lastResponse != AT_NOCARRIER && atCmd(rhCmd, AT_CONNECT, wait)) {   // wait longer
 1680                         // simulate adaptive receive
 1681                         emsg = "";      // clear the failure
 1682                         gotRTNC = true;
 1683                         } else {
 1684                         if (wasTimeout()) abortReceive();
 1685                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1686                         return (false);
 1687                         }
 1688                     } else gotprimary = true;
 1689                     }
 1690                 }
 1691                 } else {
 1692                 gotprimary = false;
 1693                 if (!isSSLFax && !useV34) {
 1694                     if (wasTimeout()) {
 1695                     if (lastResponse != AT_OK) abortReceive();
 1696                     break;
 1697                     }
 1698                     if (lastResponse == AT_NOCARRIER) {
 1699                     /*
 1700                      * The modem reported V.21 HDLC but then reported that carrier was lost.
 1701                      * The modem may have erred in its detection of the high-speed carrier.
 1702                      * But it may also have detected echo from our end or there may be 
 1703                      * another receiver on the line (the sender is sharing the line with two
 1704                      * machines).  Try AT+FRM=n again.
 1705                      */
 1706                     retryrmcmd = true;
 1707                     if (rmattempted+1 < 2) {
 1708                         gotRTNC = false;
 1709                     } else {
 1710                         gotRTNC = true;
 1711                         if (!atCmd(rhCmd, AT_CONNECT, conf.t1Timer)) break;
 1712                     }
 1713                     } else {
 1714                     if (!atCmd(rhCmd, AT_CONNECT, conf.t1Timer)) break;
 1715                     }
 1716                 }
 1717                 }
 1718             }
 1719             if (!isSSLFax && !gotprimary && !sendERR && !(retryrmcmd && rmattempted+1 < 2)) {
 1720                 if (emsg == "") {
 1721                 if (!isSSLFax && useV34) emsg = "Failed to properly open V.34 primary channel. {E114}";
 1722                 else emsg = "Failed to properly detect high-speed data carrier. {E112}";
 1723                 }
 1724                 protoTrace(emsg);
 1725                 abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1726                 return (false);
 1727             }
 1728             }
 1729             if (gotEOT) {       // intentionally not an else of the previous if
 1730             if (useV34 && emsg == "") emsg = "Received premature V.34 termination. {E115}";
 1731             protoTrace(emsg);
 1732             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1733             return (false);
 1734             }
 1735         }
 1736         } while (retryrmcmd && ++rmattempted < 2);
 1737         /*
 1738          * Buffering and flow control must be done after AT+FRM=n.
 1739          * We do not flush in order avoid losing data already buffered.
 1740          */
 1741         setInputBuffering(true);
 1742         if (flowControl == FLOW_XONXOFF)
 1743         (void) setXONXOFF(FLOW_NONE, FLOW_XONXOFF, ACT_NOW);
 1744         gotoPhaseD = false;
 1745         if (!sendERR && ((!isSSLFax && useV34) || syncECMFrame())) {    // no synchronization needed w/V.34-fax
 1746         time_t start = Sys::now();
 1747         do {
 1748             frame.reset();
 1749             if (recvECMFrame(frame)) {
 1750             if (frame[2] == 0x60) {     // FCF is FCD
 1751                 dataseen = true;
 1752                 pagedataseen = true;
 1753                 rcpcnt = 0;         // reset RCP counter
 1754                 fnum = frameRev[frame[3]];  // T.4 A.3.6.1 says LSB2MSB
 1755                 protoTrace("RECV received frame number %u", fnum);
 1756                 // some modems may erroneously recreate valid CRC on short frames, so possibly check length, too
 1757                 if (conf.class1ECMCheckFrameLength ? frame.checkCRC() && frame.getLength() == frameSize+6 : frame.checkCRC()) {
 1758                 // store received frame in block at position fnum (A+C+FCF+Frame No.=4 bytes)
 1759                 for (u_int i = 0; i < frameSize; i++) {
 1760                     if (frame.getLength() - 6 > i)  // (A+C+FCF+Frame No.+FCS=6 bytes)
 1761                     block[fnum*frameSize+i] = frameRev[frame[i+4]]; // LSB2MSB
 1762                 }
 1763                 if (fcount < (fnum + 1)) fcount = fnum + 1;
 1764                 // valid frame, set the corresponding bit in ppr to 0
 1765                 u_int pprpos, pprval;
 1766                 for (pprpos = 0, pprval = fnum; pprval >= 8; pprval -= 8) pprpos++;
 1767                 if (ppr[pprpos] & frameRev[1 << pprval]) ppr[pprpos] ^= frameRev[1 << pprval];
 1768                 } else {
 1769                 protoTrace("RECV frame FCS check failed");
 1770                 }
 1771             } else if (frame[2] == 0x61 && frame.checkCRC()) {  // FCF is RCP
 1772                 rcpcnt++;
 1773             } else {
 1774                 dataseen = true;
 1775                 if (frame.getLength() > 4 && frame.checkCRC()) {
 1776                 traceFCF("Invalid and confusing placement of", frame.getFCF());
 1777                 } else {
 1778                 protoTrace("HDLC frame with bad FCF %#x", frame[2]);
 1779                 }
 1780             }
 1781             } else {
 1782             dataseen = true;    // assume that garbage was meant to be data
 1783             if (wasTimeout()) break;
 1784             if (isSSLFax || !useV34) syncECMFrame();
 1785             if ((!isSSLFax && useV34) && (gotEOT || gotCTRL)) rcpcnt = 3;
 1786             }
 1787             // some senders don't send the requisite three RCP signals
 1788         } while (rcpcnt == 0 && (unsigned) Sys::now()-start < 5*60);    // can't expect 50 ms of flags, some violate T.4 A.3.8
 1789         if (flowControl == FLOW_XONXOFF)
 1790             (void) setXONXOFF(FLOW_NONE, FLOW_NONE, ACT_DRAIN);
 1791         setInputBuffering(false);
 1792         if (!isSSLFax && useV34) {
 1793             if (!gotEOT && !gotCTRL && !waitForDCEChannel(true)) {
 1794             emsg = "Failed to properly open V.34 control channel. {E116}";
 1795             protoTrace(emsg);
 1796             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1797             return (false);
 1798             }
 1799             if (gotEOT) {
 1800             emsg = "Received premature V.34 termination. {E115}";
 1801             protoTrace(emsg);
 1802             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1803             return (false);
 1804             }
 1805         } else {
 1806             if (!endECMBlock()) {               // wait for <DLE><ETX>
 1807             if (wasTimeout()) {
 1808                 abortReceive();
 1809                 emsg = "Timeout waiting for Phase C carrier drop. {E154}";
 1810                 protoTrace(emsg);
 1811                 abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1812                 return (false);
 1813             }
 1814             }
 1815         }
 1816         if (!isSSLFax && !useV34) {
 1817             // wait for message carrier to drop
 1818             time_t nocarrierstart = Sys::now();
 1819             bool gotnocarrier = false;
 1820             do {
 1821             gotnocarrier = waitFor(AT_NOCARRIER, 2*1000);
 1822             if (lastResponse == AT_OK) gotnocarrier = true; // some modems may return to command-mode in some instances
 1823             } while (!gotnocarrier && lastResponse != AT_EMPTYLINE && Sys::now() < (nocarrierstart + 5));
 1824         }
 1825         bool gotpps = false;
 1826         HDLCFrame ppsframe(conf.class1FrameOverhead);
 1827         u_short recvFrameCount = 0;
 1828         do {
 1829             /*
 1830              * It is possible that the high-speed carrier drop was
 1831              * detected in error or that some line noise caused it but
 1832              * that the sender has not disconnected.  It is possible
 1833              * then, that T2 will not be long enough to receive the
 1834              * partial-page signal because the sender is still transmitting
 1835              * high-speed data.  So we calculate the wait for 80KB (the 
 1836              * ECM block plus some wriggle-room) at the current bitrate.
 1837              */
 1838             u_int br = useV34 ? primaryV34Rate : curcap->br + 1;
 1839             long wait = br >= 1 && br <= 15 ? 273066 / br : conf.t2Timer;
 1840             gotpps = recvFrame(ppsframe, FCF_RCVR, wait);   // wait longer
 1841         } while (!gotpps && gotCONNECT && !wasTimeout() && !gotEOT && ++recvFrameCount < 5);
 1842         if (gotpps) {
 1843             traceFCF("RECV recv", ppsframe.getFCF());
 1844             if (ppsframe.getFCF() == FCF_PPS) {
 1845             // sender may violate T.30-A.4.3 and send another signal (i.e. DCN)
 1846             traceFCF("RECV recv", ppsframe.getFCF2());
 1847             }
 1848             u_int pgcount = u_int(prevPage/256)*256+frameRev[ppsframe[4]];  // cope with greater than 256 pages
 1849             switch (ppsframe.getFCF()) {
 1850             /*
 1851              * PPS is the only valid signal, Figure A.8/T.30; however, some
 1852              * senders don't handle T.30 A.1.3 ("When PPR is received four
 1853              * times for the same block...") properly (possibly because T.30
 1854              * A.4.1 isn't clear about the "per-block" requirement), and so
 1855              * it is possible for us to get CTC or EOR here (if the modem
 1856              * quickly reported NO CARRIER when we went looking for the
 1857              * non-existent high-speed carrier and the sender is persistent).
 1858              *
 1859              * CRP is a bizarre signal to get instead of PPS, but some
 1860              * senders repeatedly transmit this instead of PPS.  So to
 1861              * handle it as best as possible we interpret the signal as
 1862              * meaning PPS-NULL (full block) unless there was no data seen
 1863              * (in which case PPS-MPS is assumed) in order to prevent 
 1864              * any data loss, and we let the sender cope with it from there.
 1865              *
 1866              * Because there is no way to express "zero" in the frame count
 1867              * byte there exists some confusion in some senders which attempt
 1868              * to do just that.  Consequently, the frame count values of 0x00
 1869              * and 0xFF need consideration as to whether they represent 0, 1, 
 1870              * or 256.  To allow for the bizarre situation where a sender may
 1871              * signal PPS-NULL with a frame count less than 256 we trust the
 1872              * PPS-NULL frame count except in cases where it is determined to
 1873              * be "1" because most-likely that determination only comes from
 1874              * some garbage detected during the high-speed carrier.
 1875              */
 1876             case FCF_PPS:
 1877             case FCF_CRP:
 1878                 {
 1879                 u_int fc = ppsframe.getFCF() == FCF_CRP ? 256 : frameRev[ppsframe[6]] + 1;
 1880                 if ((fc == 256 || fc == 1) && !dataseen) fc = 0;    // distinguish 0 from 1 and 256
 1881                 // See comment above.  It's extremely unlikely to get PPS-NULL with a frame-count meaning "1"...
 1882                 if (ppsframe.getFCF() == FCF_PPS && ppsframe.getFCF2() == 0x00 && fc == 1) fc = 0;
 1883                 if (fcount < fc) fcount = fc;
 1884                 if (ppsframe.getFCF() == FCF_CRP) {
 1885                     if (fc) ppsframe[3] = 0x00;     // FCF2 = NULL
 1886                     else ppsframe[3] = FCF_MPS;
 1887                     protoTrace("RECV unexpected CRP - assume %u frames of block %u of page %u", \
 1888                     fc, prevBlock + 1, prevPage + 1);
 1889                 } else {
 1890                     protoTrace("RECV received %u frames of block %u of page %u", \
 1891                     fc, frameRev[ppsframe[5]]+1, pgcount+1);
 1892                 }
 1893                 blockgood = true;
 1894                 /*
 1895                  * The sender may send no frames.  This will happen for at least three
 1896                  * reasons.
 1897                  *
 1898                  * 1) If we previously received data from this block and responded
 1899                  * with PPR but the sender is done retransmitting frames as the sender
 1900                  * thinks that our PPR signal did not indicate any frame that the 
 1901                  * sender transmitted.  This should only happen with the last frame
 1902                  * of a block due to counting errors.  So, in the case where we received
 1903                  * no frames from the sender we ignore the last frame in the block when
 1904                  * checking.
 1905                  *
 1906                  * 2) The sender feeds paper into a scanner during the initial
 1907                  * synchronization and it expected another page but didn't get it 
 1908                  * (e.g. paper feed problem).  We respond with a full PPR in hopes that
 1909                  * the sender knows what they're doing by sending PPS instead of DCN.
 1910                  * The sender can recover by sending data with the block retransmission.
 1911                  *
 1912                  * 3) The sender sent only one frame but for some reason we did not see
 1913                  * any data, and so the frame-count in the PPS signal ended up getting
 1914                  * interpreted as a zero.  Only in the case that the frame happens to be
 1915                  * the last frame in a block and we're dealing with MH, MR, or MMR data 
 1916                  * we will send MCF (to accomodate #1), and so this frame will then be 
 1917                  * lost.  This should be rare and have little impact on actual image data
 1918                  * loss when it does occur.  This approach cannot be followed with JPEG
 1919                  * and JBIG data formats or when the signal is PPS-NULL.  This approach
 1920                  * cannot be followed when we previously saw exactly one frame of data.
 1921                  */
 1922                 if (fcount) {
 1923                     u_int fbad = 0;
 1924                     for (u_int i = 0; i <= (fcount - ((fcount < 2 || fc || params.df > DF_2DMMR || ppsframe.getFCF() == 0) ? 1 : 2)); i++) {
 1925                     u_int pprpos, pprval;
 1926                     for (pprpos = 0, pprval = i; pprval >= 8; pprval -= 8) pprpos++;
 1927                     if (ppr[pprpos] & frameRev[1 << pprval]) {
 1928                         blockgood = false;
 1929                         fbad++;
 1930                     }
 1931                     }
 1932                     dataSent += fcount;
 1933                     dataMissed += fbad;
 1934                     pageDataMissed += fbad;
 1935                     if (fcount && ! blockgood) protoTrace("Block incomplete: %d frames (%d%%) corrupt or missing", fbad, ((fbad*100)/fcount));
 1936                     if (pgcount < prevPage || (pgcount == prevPage && frameRev[ppsframe[5]] < prevBlock))
 1937                     blockgood = false;  // we already confirmed this block receipt... (see below)
 1938                 } else {
 1939                     blockgood = false;  // MCF only if we have data
 1940                 }
 1941 
 1942                 // requisite pause before sending response (PPR/MCF)
 1943                 if (!blockgood && !switchingPause(emsg)) {
 1944                     abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1945                     return (false);
 1946                 }
 1947                 }
 1948                 /* ... pass through ... */
 1949             case FCF_CTC:
 1950             case FCF_EOR:
 1951                 if (! blockgood) {
 1952                 if ((ppsframe.getFCF() == FCF_CTC || ppsframe.getFCF() == FCF_EOR) &&
 1953                      (!useV34 || !conf.class1PersistentECM)) {  // only if we can make use of the signal
 1954                     signalRcvd = ppsframe.getFCF();
 1955                     pprcnt = 4;
 1956                 }
 1957                 if (signalRcvd == 0) {
 1958                     if (pgcount > prevPage || (pgcount == prevPage && frameRev[ppsframe[5]] >= prevBlock)) {
 1959                     // inform the remote that one or more frames were invalid
 1960                     transmitFrame(FCF_PPR, fxStr(ppr, 32));
 1961                     traceFCF("RECV send", FCF_PPR);
 1962                     pprcnt++;
 1963                     if (pprcnt > 4) pprcnt = 4;     // could've been 4 before increment
 1964                     } else {
 1965                     /*
 1966                      * The silly sender already sent us this block and we already confirmed it.
 1967                      * Just confirm it again, but let's behave as if we sent a full PPR without
 1968                      * incrementing pprcnt.
 1969                      */
 1970                     (void) transmitFrame(FCF_MCF|FCF_RCVR);
 1971                     traceFCF("RECV send", FCF_MCF);
 1972                     for (u_int i = 0; i < 32; i++) ppr[i] = 0xff;   // ppr defaults to all 1's, T.4 A.4.4
 1973                     }
 1974                 }
 1975                 if (pprcnt == 4 && ((!useV34 && !isSSLFax) || !conf.class1PersistentECM)) {
 1976                     HDLCFrame rtnframe(conf.class1FrameOverhead);
 1977                     if (signalRcvd == 0) {
 1978                     // expect sender to send CTC/EOR after every fourth PPR, not just the fourth
 1979                     protoTrace("RECV sent fourth PPR");
 1980                     } else {
 1981                     // we already got the signal
 1982                     rtnframe.put(ppsframe, ppsframe.getLength());
 1983                     }
 1984                     pprcnt = 0;
 1985                     if (signalRcvd != 0 || recvFrame(rtnframe, FCF_RCVR, conf.t2Timer)) {
 1986                     bool gotrtnframe = true;
 1987                     if (signalRcvd == 0) traceFCF("RECV recv", rtnframe.getFCF());
 1988                     else signalRcvd = 0;        // reset it, we're in-sync now
 1989                     recvFrameCount = 0;
 1990                     lastResponse = AT_NOTHING;
 1991                     while (rtnframe.getFCF() == FCF_PPS && !gotEOT && recvFrameCount < 5 && gotrtnframe) {
 1992                         // we sent PPR, but got PPS again...
 1993                         if (!switchingPause(emsg)) {
 1994                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 1995                         return (false);
 1996                         }
 1997                         transmitFrame(FCF_PPR, fxStr(ppr, 32));
 1998                         traceFCF("RECV send", FCF_PPR);
 1999                         gotrtnframe = recvFrame(rtnframe, FCF_RCVR, conf.t2Timer);
 2000                         if (gotrtnframe)
 2001                         traceFCF("RECV recv", rtnframe.getFCF());
 2002                         recvFrameCount++;
 2003                     }
 2004                     u_int dcs;          // possible bits 1-16 of DCS in FIF
 2005                     switch (rtnframe.getFCF()) {
 2006                         case FCF_CTC:
 2007                         if (useV34) {
 2008                             // T.30 F.3.4.5 Note 1 does not permit CTC in V.34-fax
 2009                             emsg = "Received invalid CTC signal in V.34-Fax. {E113}";
 2010                             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2011                             return (false);
 2012                         }
 2013                         // use 16-bit FIF to alter speed, curcap
 2014                         dcs = rtnframe[3] | (rtnframe[4]<<8);
 2015                         curcap = findSRCapability(dcs&DCS_SIGRATE, recvCaps);
 2016                         processNewCapabilityUsage();
 2017                         // requisite pause before sending response (CTR)
 2018                         if (!switchingPause(emsg)) {
 2019                             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2020                             return (false);
 2021                         }
 2022                         (void) transmitFrame(FCF_CTR|FCF_RCVR);
 2023                         traceFCF("RECV send", FCF_CTR);
 2024                         dolongtrain = true;
 2025                         break;
 2026                         case FCF_EOR:
 2027                         traceFCF("RECV recv", rtnframe.getFCF2());
 2028                         /*
 2029                          * It may be wise to disconnect here if MMR is being
 2030                          * used because there will surely be image data loss.
 2031                          * However, since the sender knows what the extent of
 2032                          * the data loss will be, we'll naively assume that
 2033                          * the sender knows what it's doing, and we'll
 2034                          * proceed as instructed by it.
 2035                          */
 2036                         blockgood = true;
 2037                         switch (rtnframe.getFCF2()) {
 2038                             case 0:
 2039                             // EOR-NULL partial page boundary
 2040                             break;
 2041                             case FCF_EOM:
 2042                             case FCF_MPS:
 2043                             case FCF_EOP:
 2044                             case FCF_PRI_EOM:
 2045                             case FCF_PRI_MPS:
 2046                             case FCF_PRI_EOP:
 2047                             lastblock = true;
 2048                             signalRcvd = rtnframe.getFCF2();
 2049                             break;
 2050                             default:
 2051                             emsg = "COMREC invalid response to repeated PPR received {E117}";
 2052                             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2053                             return (false);
 2054                         }
 2055                         sendERR = true;     // do it later
 2056                         break;
 2057                         case FCF_DCN:
 2058                         emsg = "COMREC received DCN (sender abort) {E108}";
 2059                         gotEOT = true;
 2060                         recvdDCN = true;  
 2061                         default:
 2062                         if (emsg == "") emsg = "COMREC invalid response to repeated PPR received {E117}";
 2063                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2064                         return (false);
 2065                     }
 2066                     } else {
 2067                     emsg = "T.30 T2 timeout, expected signal not received {E118}";
 2068                     abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2069                     return (false);
 2070                     }
 2071                 }
 2072                 }
 2073                 if (signalRcvd == 0) {      // don't overwrite EOR settings
 2074                 switch (ppsframe.getFCF2()) {
 2075                     case 0:
 2076                     // PPS-NULL partial page boundary
 2077                     break;
 2078                     case FCF_EOM:
 2079                     case FCF_MPS:
 2080                     case FCF_EOP:
 2081                     case FCF_PRI_EOM:
 2082                     case FCF_PRI_MPS:
 2083                     case FCF_PRI_EOP:
 2084                     lastblock = true;
 2085                     signalRcvd = ppsframe.getFCF2();
 2086                     break;
 2087                     default:
 2088                     if (blockgood) {
 2089                         emsg = "COMREC invalid partial-page signal received {E119}";
 2090                         abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2091                         return (false);
 2092                     }
 2093                     /*
 2094                      * If the sender signalled PPS-<??> (where the FCF2 is meaningless) 
 2095                      * and if the block isn't good then we already signalled back PPR... 
 2096                      * which is appropriate despite whatever the strange FCF2 was supposed
 2097                      * to mean, and hopefully it will not re-use it on the next go-around.
 2098                      */
 2099                     break;
 2100                 }
 2101                 }
 2102                 break;
 2103             case FCF_DCN:
 2104                 emsg = "COMREC received DCN (sender abort) {E108}";
 2105                 gotEOT = true;
 2106                 recvdDCN = true;
 2107                 abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2108                 return (false);
 2109             default:
 2110                 // The message is not ECM-specific: fall out of ECM receive, and let
 2111                 // the earlier message-handling routines try to cope with the signal.
 2112                 signalRcvd = ppsframe.getFCF();
 2113                 messageReceived = true;
 2114                 abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2115                 if (getRecvEOLCount() == 0) {
 2116                  prevPage--;        // counteract the forthcoming increment
 2117                 return (true);
 2118                 } else {
 2119                 emsg = "COMREC invalid response received {E110}";   // plain ol' error
 2120                 return (false);
 2121                 }
 2122             }
 2123         } else {
 2124             emsg = "T.30 T2 timeout, expected signal not received {E118}";
 2125             abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
 2126             return (false);
 2127         }
 2128         } else {
 2129         if (wasTimeout()) {
 2130             abortReceive();
 2131             if (!useV34 && !isSSLFax) {
 2132             // must now await V.21 signalling
 2133             long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
 2134             gotRTNC = (lastResponse == AT_FRH3 && waitFor(AT_CONNECT, conf.t2Timer)) || atCmd(rhCmd, AT_CONNECT, wait);
 2135             gotoPhaseD = gotRTNC;
 2136             if (!gotRTNC) syncattempts = 21;
 2137             else setTimeout(false);
 2138             }
 2139         }
 2140         if (syncattempts++ > 20) {
 2141             emsg = "Cannot synchronize ECM frame reception. {E120}";
 2142             abortPageECMRecv(tif, params, block, fcount, seq, true, emsg);
 2143             return(false);
 2144         }
 2145         }
 2146     } while (! blockgood);
 2147 
 2148     u_int cc = fcount * frameSize;
 2149     if (lastblock) {
 2150         // trim zero padding
 2151         while (cc > 0 && block[cc - 1] == 0) cc--;
 2152     }
 2153     // write the block to file
 2154     if (lastblock) seq |= 2;            // seq code for the last block
 2155 
 2156     /*
 2157      * On servers where disk or CPU may be bottlenecked or stressed,
 2158      * the writeECMData call can lag.  The strategy, then, is
 2159      * to employ RNR/RR flow-control in order to grant writeECMData
 2160      * sufficient time to complete.
 2161      *
 2162      * We used to do this with a forked process, but because in an
 2163      * SSL Fax session immovable data is being manipulated both with
 2164      * the SSL operations as well as with the TIFF operation, it is
 2165      * much easier to use threads rather than ensure one of those
 2166      * operations is conducted entirely in memory shared between the
 2167      * forked processes.
 2168      */
 2169     int fcfd[2];        // flow control file descriptors for the pipe
 2170     if (pipe(fcfd) >= 0) {
 2171 
 2172         pthread_t t;
 2173         recvWriteECMDataData r(this, fcfd[1], tif, block, cc, params, seq, emsg);
 2174         if (pthread_create(&t, NULL, &recvWriteECMData, (void *) &r) == 0) {
 2175 
 2176         char tbuf[1];   // trigger signal
 2177         tbuf[0] = 0xFF;
 2178         time_t rrstart = Sys::now();
 2179         do {
 2180             fd_set rfds;
 2181             FD_ZERO(&rfds);
 2182             FD_SET(fcfd[0], &rfds);
 2183             struct timeval tv;
 2184             tv.tv_sec = 1;      // 1000 ms should be safe
 2185             tv.tv_usec = 0;
 2186 #if CONFIG_BADSELECTPROTO
 2187             if (!select(fcfd[0]+1, (int*) &rfds, NULL, NULL, &tv)) {
 2188 #else
 2189             if (!select(fcfd[0]+1, &rfds, NULL, NULL, &tv)) {
 2190 #endif
 2191             bool gotresponse = true;
 2192             u_short rnrcnt = 0;
 2193             do {
 2194                 (void) switchingPause(emsg);
 2195                 if (emsg != "") break;
 2196                 (void) transmitFrame(FCF_RNR|FCF_RCVR);
 2197                 traceFCF("RECV send", FCF_RNR);
 2198                 HDLCFrame rrframe(conf.class1FrameOverhead);
 2199                 gotresponse = recvFrame(rrframe, FCF_RCVR, conf.t2Timer);
 2200                 if (gotresponse) {
 2201                 traceFCF("RECV recv", rrframe.getFCF());
 2202                 if (rrframe.getFCF() == FCF_DCN) {
 2203                     protoTrace("RECV recv DCN");
 2204                     emsg = "COMREC received DCN (sender abort) {E108}";
 2205                     gotEOT = true;
 2206                     recvdDCN = true;
 2207                 } else if (params.ec != EC_DISABLE && rrframe.getFCF() != FCF_RR) {
 2208                     protoTrace("Ignoring invalid response to RNR.");
 2209                 }
 2210                 }
 2211             } while (!recvdDCN && !gotEOT && !gotresponse && ++rnrcnt < 2 && Sys::now()-rrstart < 60);
 2212             if (!gotresponse) emsg = "No response to RNR repeated 3 times. {E109}";
 2213             } else tbuf[0] = 0; // thread finished writeECMData
 2214         } while (!gotEOT && !recvdDCN && tbuf[0] != 0 && Sys::now()-rrstart < 60);
 2215         Sys::read(fcfd[0], NULL, 1);
 2216         pthread_join(t, NULL);
 2217         } else {
 2218         protoTrace("Protocol flow control unavailable due to fork error.");
 2219         writeECMData(tif, block, cc, params, seq, emsg);
 2220         }
 2221         Sys::close(fcfd[0]);
 2222         Sys::close(fcfd[1]);
 2223     } else {
 2224         protoTrace("Protocol flow control unavailable due to pipe error.");
 2225         writeECMData(tif, block, cc, params, seq, emsg);
 2226     }
 2227     seq = 0;                    // seq code for in-between blocks
 2228 
 2229     if (!lastblock) {
 2230         // confirm block received as good
 2231         (void) switchingPause(emsg);
 2232         (void) transmitFrame((sendERR ? FCF_ERR : FCF_MCF)|FCF_RCVR);
 2233         traceFCF("RECV send", sendERR ? FCF_ERR : FCF_MCF);
 2234     }
 2235     prevBlock++;
 2236     } while (! lastblock);
 2237 
 2238     free(block);
 2239     recvEndPage(tif, params);
 2240 
 2241     if (getRecvEOLCount() == 0) {
 2242     // Just because image data blocks are received properly doesn't guarantee that
 2243     // those blocks actually contain image data.  If the decoder finds no image
 2244     // data at all we send DCN instead of MCF in hopes of a retransmission.
 2245     emsg = "ECM page received containing no image data. {E121}";
 2246     return (false);
 2247     }
 2248     if (!signalRcvd) {
 2249     // It appears that the sender did something bizarre such as first signaling
 2250     // PPS-MPS and then after a PPR exchange later signaled PPS-NULL.  We've come
 2251     // to here because lastblock was set true as was blockgood.  So let's restore
 2252     // signalRcvd to the non-null value so that we can do something useful after.
 2253     signalRcvd = lastSignalRcvd;
 2254     }
 2255     return (true);          // signalRcvd is set, full page is received...
 2256 }
 2257 
 2258 /*
 2259  * Receive Phase C data w/ or w/o copy quality checking.
 2260  */
 2261 bool
 2262 Class1Modem::recvPageData(TIFF* tif, fxStr& emsg)
 2263 {
 2264     bool ret = false;
 2265     /*
 2266      * T.30-A ECM mode requires a substantially different protocol than non-ECM faxes.
 2267      */
 2268     if (params.ec != EC_DISABLE) {
 2269     if (!recvPageECMData(tif, params, emsg)) {
 2270         /*
 2271          * The previous page experienced some kind of error.  Falsify
 2272          * some event settings in order to cope with the error gracefully.
 2273          */
 2274         signalRcvd = FCF_EOP;
 2275         messageReceived = true;
 2276         if (prevPage)
 2277         recvEndPage(tif, params);
 2278     }
 2279         /* data regeneration always occurs in ECM */
 2280     TIFFSetField(tif, TIFFTAG_CLEANFAXDATA, pageDataMissed ?
 2281         CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN);
 2282     if (pageDataMissed) {
 2283         TIFFSetField(tif, TIFFTAG_BADFAXLINES, pageDataMissed);
 2284     }
 2285     ret = true;     // no RTN with ECM
 2286     } else {
 2287     (void) recvPageDLEData(tif, checkQuality(), params, emsg);
 2288     dataSent += getRecvEOLCount();
 2289     dataMissed += getRecvBadLineCount();
 2290         /* data regeneration only occurs in copy quality checking */
 2291     TIFFSetField(tif, TIFFTAG_CLEANFAXDATA, getRecvBadLineCount() ?
 2292         (checkQuality() ? CLEANFAXDATA_REGENERATED : CLEANFAXDATA_UNCLEAN) : CLEANFAXDATA_CLEAN);
 2293     if (getRecvBadLineCount()) {
 2294         TIFFSetField(tif, TIFFTAG_BADFAXLINES, getRecvBadLineCount());
 2295         TIFFSetField(tif, TIFFTAG_CONSECUTIVEBADFAXLINES,
 2296         getRecvConsecutiveBadLineCount());
 2297     }
 2298     ret = isQualityOK(params);
 2299     }
 2300     pageDataMissed = 0;
 2301     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, getRecvEOLCount());
 2302     return (ret);
 2303 }
 2304 
 2305 /*
 2306  * Complete a receive session.
 2307  */
 2308 bool
 2309 Class1Modem::recvEnd(FaxSetup* setupinfo, fxStr& emsg)
 2310 {
 2311     if (setupinfo) {
 2312     /*
 2313      * Update FaxMachine info...
 2314      */
 2315     setupinfo->senderSkipsV29 = senderSkipsV29;
 2316     setupinfo->senderHasV17Trouble = senderHasV17Trouble;
 2317     setupinfo->senderDataSent = dataSent;
 2318     setupinfo->senderDataMissed = dataMissed;
 2319     }
 2320     if (!recvdDCN && !gotEOT) {
 2321     u_int t1 = howmany(conf.t1Timer, 1000); // T1 timer in seconds
 2322     time_t start = Sys::now();
 2323     /*
 2324      * Wait for DCN and retransmit ack of EOP if needed.
 2325      */
 2326     HDLCFrame frame(conf.class1FrameOverhead);
 2327     do {
 2328         gotRTNC = false;
 2329         if (recvFrame(frame, FCF_RCVR, conf.t2Timer)) {
 2330         traceFCF("RECV recv", frame.getFCF());
 2331         switch (frame.getFCF()) {
 2332         case FCF_PPS:
 2333         case FCF_EOP:
 2334         case FCF_CRP:
 2335         case FCF_RR:
 2336             (void) switchingPause(emsg);
 2337             (void) transmitFrame(FCF_MCF|FCF_RCVR);
 2338             traceFCF("RECV send", FCF_MCF);
 2339             break;
 2340         case FCF_DCN:
 2341             recvdDCN = true;
 2342             break;
 2343         default:
 2344             (void) switchingPause(emsg);
 2345             transmitFrame(FCF_DCN|FCF_RCVR);
 2346             recvdDCN = true;
 2347             break;
 2348         }
 2349         } else if (gotRTNC) {
 2350         (void) transmitFrame(FCF_MCF|FCF_RCVR);
 2351         traceFCF("RECV send", FCF_MCF);
 2352         } else if (!wasTimeout() && lastResponse != AT_FCERROR && lastResponse != AT_FRH3) {
 2353         /*
 2354          * Beware of unexpected responses from the modem.  If
 2355          * we lose carrier, then we can loop here if we accept
 2356          * null responses, or the like.
 2357          */
 2358         break;
 2359         }
 2360     } while ((unsigned) Sys::now()-start < t1 && (!frame.isOK() || !recvdDCN));
 2361     }
 2362     setInputBuffering(true);
 2363     return (true);
 2364 }
 2365 
 2366 /*
 2367  * Abort an active receive session.
 2368  */
 2369 void
 2370 Class1Modem::recvAbort()
 2371 {
 2372     if (!recvdDCN && !gotEOT) {
 2373     fxStr emsg;
 2374     switchingPause(emsg);
 2375     transmitFrame(FCF_DCN|FCF_RCVR);
 2376     }
 2377     recvdDCN = true;                // don't hang around in recvEnd
 2378 }