Class1Recv.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:67k
源码类别:

传真(Fax)编程

开发平台:

C/C++

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