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