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