if (recvFrame(frame, timer)) {
switch (lastPPM = frame.getFCF()) {
case FCF_DIS: // XXX no support
+ if (prevPage && !pageGood) recvResetPage(tif);
protoTrace("RECV DIS/DTC");
emsg = "Can not continue after DIS/DTC";
return (false);
case FCF_NSS:
case FCF_TSI:
case FCF_DCS:
+ if (prevPage && !pageGood) recvResetPage(tif);
// look for high speed carrier only if training successful
messageReceived = !(
FaxModem::recvBegin(emsg)
case FCF_PRI_MPS: // PRI-MPS
case FCF_PRI_EOM: // PRI-EOM
case FCF_PRI_EOP: // PRI-EOP
+ if (prevPage && !pageGood) recvResetPage(tif);
tracePPM("RECV recv", lastPPM);
if (!prevPage) {
/*
* Reset the TIFF-related state so that subsequent
* writes will overwrite the previous data.
*/
- recvResetPage(tif);
messageReceived = true; // expect DCS next
}
break;
protoTrace("RECV recv DCN");
emsg = "COMREC received DCN";
recvdDCN = true;
+ if (prevPage && conf.saveUnconfirmedPages) {
+ TIFFWriteDirectory(tif);
+ protoTrace("RECV keeping unconfirmed page");
+ return (true);
+ }
return (false);
default:
+ if (prevPage && !pageGood) recvResetPage(tif);
emsg = "COMREC invalid response received";
return (false);
}
*/
if (atCmd(thCmd, AT_NOTHING) && atResponse(rbuf, 0) == AT_CONNECT && recvBegin(emsg))
goto top;
- } else
+ } else {
emsg = "T.30 T2 timeout, expected page not received";
+ if (prevPage && conf.saveUnconfirmedPages) {
+ TIFFWriteDirectory(tif);
+ protoTrace("RECV keeping unconfirmed page");
+ return (true);
+ }
+ }
return (false);
}
Class2Modem::recvPage(TIFF* tif, u_int& ppm, fxStr& emsg)
{
int ppr;
+ bool prevPage = false;
+ bool pageGood = false;
do {
ppm = PPM_EOP;
do {
switch (r = atResponse(rbuf, conf.pageStartTimeout)) {
case AT_FDCS: // inter-page DCS
+ if (prevPage && !pageGood) recvResetPage(tif);
(void) recvDCS(rbuf);
break;
case AT_FTSI:
+ if (prevPage && !pageGood) recvResetPage(tif);
recvTSI(stripQuotes(skipStatus(rbuf)));
break;
case AT_FSA:
+ if (prevPage && !pageGood) recvResetPage(tif);
recvSUB(stripQuotes(skipStatus(rbuf)));
break;
#ifdef notdef
case AT_FPA:
+ if (prevPage && !pageGood) recvResetPage(tif);
recvSEP(stripQuotes(skipStatus(rbuf)));
break;
#endif
case AT_FPW:
+ if (prevPage && !pageGood) recvResetPage(tif);
recvPWD(stripQuotes(skipStatus(rbuf)));
break;
case AT_TIMEOUT:
* don't understand the FillOrder tag!
*/
recvSetupTIFF(tif, group3opts, FILLORDER_LSB2MSB);
- if (!recvPageData(tif, emsg) || !recvPPM(tif, ppr))
+ if (!recvPageData(tif, emsg)) {
+ prevPage = false;
goto bad;
+ }
+ else {
+ prevPage = true;
+ if (!recvPPM(tif, ppr))
+ goto bad;
+ }
if (!waitFor(AT_FET)) // post-page message status
goto bad;
ppm = atoi(skipStatus(rbuf));
*/
ppr = PPR_RTN;
#endif
- if (ppr & 1)
+ if (ppr & 1) {
+ pageGood = true;
TIFFWriteDirectory(tif); // complete page write
- else
- recvResetPage(tif); // reset to overwrite data
+ } else
+ pageGood = false;
tracePPR("RECV send", ppr);
if (ppr & 1) // page good, work complete
return (true);
if (hangupCode[0] == 0)
processHangup("90"); // "Unspecified Phase C error"
emsg = hangupCause(hangupCode);
+ if (prevPage && conf.saveUnconfirmedPages) {
+ TIFFWriteDirectory(tif);
+ protoTrace("RECV keeping unconfirmed page");
+ return (true);
+ }
return (false);
}
{
traceProtocol("RECV FAX: begin");
- fxStr emsg;
+ fxStr emsg = "";
FaxRecvInfoArray docs;
FaxRecvInfo info;
bool faxRecognized = false;
info.time = (u_int) getPageTransferTime();
info.params = modem->getRecvParams();
notifyPageRecvd(tif, info, ppm);
+ if (emsg != "") return (false); // got page with fatal error
if (PPM_PRI_MPS <= ppm && ppm <= PPM_PRI_EOP) {
emsg = "Procedure interrupt received, job terminated";
return (false);
setVolumeCmds("ATM0 ATL0M1 ATL1M1 ATL2M1 ATL3M1");
recvDataFormat = DF_ALL; // default to no transcoding
rtnHandling = FaxModem::RTN_RETRANSMIT; // retransmit until MCF/MPS
+ saveUnconfirmedPages = true; // keep unconfirmed pages
}
void
class2UseHex = getBoolean(value);
else if (streq(tag, "class2rtfcc"))
class2RTFCC = getBoolean(value);
+ else if (streq(tag, "saveunconfirmedpages"))
+ saveUnconfirmedPages = getBoolean(value);
else
return (false);
return (true);
u_int recvDataFormat; // received facsimile data format
RTNHandling rtnHandling; // RTN signal handling method
+ bool saveUnconfirmedPages; // don't delete unconfirmed pages
virtual ~ModemConfig();
RingTimout integer \s-16000\s+1 timeout in ms after RING before reset
RingVoice string \- distinctive ring voice call identifier
RTNHandlingMethod string \s-1Retransmit\s+1 RTN signal handling method
+SaveUnconfirmedPages boolean \s-1true\s+1 save or delete unconfirmed pages
SendFaxCmd\(S1 string \s-1bin/faxsend\s+1 fax transmit command script
SendPageCmd\(S1 string \s-1bin/pagesend\s+1 pager transmit command script
SendUUCPCmd\(S1 string \s-1bin/uucpsend\s+1 \s-1UUCP\s+1 transmit command script
(or will not) be missed but we have a chance to successfully send all other pages.
This behaviour can be activated by ``Ignore'' value.
.TP
+.B SaveUnconfirmedPages
+Whether or not to save a received facsimile image page if the sender disconnects
+without sending the post-page message, without hearing our message confirmation,
+without retraining as requested, or otherwise breaks fax protocol following such
+pages for which the sender should not have a ``receipt confirmation''.
+.TP
.B SendFaxCmd\(S1
The command to use to process outbound facsimile jobs; see
.IR faxsend (${MANNUM1_8}).