Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package hylafax+ for openSUSE:Factory checked in at 2022-04-03 21:30:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hylafax+ (Old) and /work/SRC/openSUSE:Factory/.hylafax+.new.1900 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hylafax+" Sun Apr 3 21:30:51 2022 rev:41 rq:966558 version:7.0.5 Changes: -------- --- /work/SRC/openSUSE:Factory/hylafax+/hylafax+.changes 2021-10-23 00:51:47.237142806 +0200 +++ /work/SRC/openSUSE:Factory/.hylafax+.new.1900/hylafax+.changes 2022-04-03 21:30:59.435819148 +0200 @@ -1,0 +2,28 @@ +Sat Apr 2 16:23:46 UTC 2022 - Axel Braun <axel.br...@gmx.de> + +- version 7.0.5 + * hylafax.diff removed - included in source + * extend Class1RecvAbortOK = 0 timeout to 500 ms (4 Dec 2021) + * cope with Si2435 V.34/V.8 connection glitch (17, 19 Nov 2021) + * cope with spurious +FCERROR or other delayed messages from modem (26 Oct 2021) + * avoid letting corrupt RTC signals lead to RTN (26 Oct 2021) + * don't refer to DCN as an invalid response in error messages (20 Oct 2021) + * handle TSI during procedural interrupt (19 Oct 2021) + * do better with waiting on prologue frames from receiver (13 Oct 2021) + * cope with echo of ERR (13 Oct 2021) + * run ps2fax, pdf2fax, tiff2fax, pcl2fax coverters as fax user (12 Oct 2021) + * attempt to cope with receivers who signal RTN in ECM Phase D (23 Sep 2021) + * fix hfaxd build when LDAP libs are not present (23 Sep 2021) + * handle PPR echo after fourth PPR (22 Sep 2021) + * don't use CRP when waiting for CFR following training (15 Sep 2021) + * attempt to cope with receivers which signal CFR after PPS (14 Sep 2021) + * cope with senders who signal FTT in Phase D (10 Sep 2021) + * fix problem with handling NSF/CSI/DIS frame after CTC/EOR (9 Sep 2021) + * cope with senders who signal PPS without the PPS FCF (9 Sep 2021) + * handle echo of PPR when expecting CTC/EOR (8 Sep 2021) + * add failure messages for unspecified training failures (7 Sep 2021) + * don't use CRP when waiting for CTR (7 Sep 2021) + * handle echo of EOR, don't use CRP when waiting for ERR (7 Sep 2021) + * repeat PIN if sender repeats post-page or partial-page message (7-8 Sep 2021) + +------------------------------------------------------------------- Old: ---- hylafax-7.0.4.tar.gz hylafax.diff New: ---- hylafax-7.0.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hylafax+.spec ++++++ --- /var/tmp/diff_new_pack.NTqIC4/_old 2022-04-03 21:31:01.347797744 +0200 +++ /var/tmp/diff_new_pack.NTqIC4/_new 2022-04-03 21:31:01.351797700 +0200 @@ -1,7 +1,7 @@ # # spec file for package hylafax+ # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %global faxspool %{_localstatedir}/spool/hylafax %define lib_version %(echo %{version} | tr \. _) Name: hylafax+ -Version: 7.0.4 +Version: 7.0.5 Release: 0 Summary: A fax server License: BSD-3-Clause @@ -40,7 +40,6 @@ Source14: hylafax-faxmodem@.service Source15: hylafax-service.xml Source16: hylafax-helper.xml -Patch0: hylafax.diff BuildRequires: firewalld BuildRequires: gcc-c++ @@ -105,7 +104,7 @@ %prep %setup -q -n hylafax-%{version} -%patch0 -p2 + cp %{SOURCE8} . cp %{SOURCE9} . # pretend, that libtiff 4.4 is similar to 4.{0,1} ++++++ hylafax-7.0.4.tar.gz -> hylafax-7.0.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/CHANGES new/hylafax-7.0.5/CHANGES --- old/hylafax-7.0.4/CHANGES 2021-08-27 02:30:30.000000000 +0200 +++ new/hylafax-7.0.5/CHANGES 2021-12-05 05:53:43.000000000 +0100 @@ -2,6 +2,31 @@ New Changes +* extend Class1RecvAbortOK = 0 timeout to 500 ms (4 Dec 2021) +* cope with Si2435 V.34/V.8 connection glitch (17, 19 Nov 2021) +* cope with spurious +FCERROR or other delayed messages from modem (26 Oct 2021) +* avoid letting corrupt RTC signals lead to RTN (26 Oct 2021) +* don't refer to DCN as an invalid response in error messages (20 Oct 2021) +* handle TSI during procedural interrupt (19 Oct 2021) +* do better with waiting on prologue frames from receiver (13 Oct 2021) +* cope with echo of ERR (13 Oct 2021) +* run ps2fax, pdf2fax, tiff2fax, pcl2fax coverters as fax user (12 Oct 2021) +* attempt to cope with receivers who signal RTN in ECM Phase D (23 Sep 2021) +* fix hfaxd build when LDAP libs are not present (23 Sep 2021) +* handle PPR echo after fourth PPR (22 Sep 2021) +* don't use CRP when waiting for CFR following training (15 Sep 2021) +* attempt to cope with receivers which signal CFR after PPS (14 Sep 2021) +* cope with senders who signal FTT in Phase D (10 Sep 2021) +* fix problem with handling NSF/CSI/DIS frame after CTC/EOR (9 Sep 2021) +* cope with senders who signal PPS without the PPS FCF (9 Sep 2021) +* handle echo of PPR when expecting CTC/EOR (8 Sep 2021) +* add failure messages for unspecified training failures (7 Sep 2021) +* don't use CRP when waiting for CTR (7 Sep 2021) +* handle echo of EOR, don't use CRP when waiting for ERR (7 Sep 2021) +* repeat PIN if sender repeats post-page or partial-page message (7-8 Sep 2021) + +(7.0.4) + * retry training twice at the same bitrate unless FTT (26 Aug 2021) * add missing reason messages for session failures (21 Aug 2021) * stop attempts to send or receive signals if the call ended prematurely (16-19 Aug 2021) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/VERSION new/hylafax-7.0.5/VERSION --- old/hylafax-7.0.4/VERSION 2021-03-01 23:50:04.000000000 +0100 +++ new/hylafax-7.0.5/VERSION 2021-09-08 04:03:25.000000000 +0200 @@ -1 +1 @@ -7.0.4 +7.0.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/config/silabs new/hylafax-7.0.5/config/silabs --- old/hylafax-7.0.4/config/silabs 2021-02-05 17:04:28.000000000 +0100 +++ new/hylafax-7.0.5/config/silabs 2021-12-08 17:13:58.000000000 +0100 @@ -2,6 +2,7 @@ # prototype config for Silicon Laboratories Si2435 and Si2417 # +# CONFIG:CLASS1:D3:18F:.*: Manufacturer=SiLabs Model='Si2417' # CONFIG:CLASS1:F:18F:.*: Manufacturer=SiLabs Model='Si2417' # # BEGIN-SERVER @@ -13,6 +14,8 @@ ModemMfrQueryCmd: !SiLabs ModemModelQueryCmd: ATI6 +Class1RecvAbortOK: 0 # abort behavior is inconsistent + # If your line supports Caller-ID, you may want to uncomment this... # ModemResetCmds: AT+VCID=1 # CallIDPattern: "NMBR=" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/config/silabs-10 new/hylafax-7.0.5/config/silabs-10 --- old/hylafax-7.0.4/config/silabs-10 2021-02-05 17:04:28.000000000 +0100 +++ new/hylafax-7.0.5/config/silabs-10 2021-12-08 17:14:44.000000000 +0100 @@ -2,6 +2,7 @@ # prototype config for Silicon Laboratories Si2435 # +# CONFIG:CLASS1.0:D3:18F:.*: Manufacturer=SiLabs Model='Si2435' # CONFIG:CLASS1.0:F:18F:.*: Manufacturer=SiLabs Model='Si2435' # # BEGIN-SERVER @@ -14,11 +15,13 @@ ModemMfrQueryCmd: !SiLabs ModemModelQueryCmd: ATI6 +Class1RecvAbortOK: 0 # abort behavior is inconsistent + Class1EnableV34Cmd: "AT+F34=14,1\nAT+A8E=6,5" # 33600-2400 primary, fixed 1200 control, issue +A8x indications ModemClassQueryCmd: !0,1,1.0,8 # the Si2435 supports Class 1.0 but omits it in the +FCLASS=? response ModemOnHookCmd: "<delay:5>ATH0" # avoids non-response after V.34-Fax session terminates (Si3018 Rev F / Si2435 Rev F) Class10AutoFallback: false # DTE must implement G3 fallback -ModemSecondAnswerCmd: AT+FTM=3 # to restart answer process after failure to detect V.8 handshake +ModemSecondAnswerCmd: AT+FTH=3 # to restart answer process after failure to detect V.8 handshake # If your line supports Caller-ID, you may want to uncomment this... # ModemResetCmds: AT+VCID=1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/etc/faxaddmodem.sh.in new/hylafax-7.0.5/etc/faxaddmodem.sh.in --- old/hylafax-7.0.4/etc/faxaddmodem.sh.in 2020-07-28 03:29:41.000000000 +0200 +++ new/hylafax-7.0.5/etc/faxaddmodem.sh.in 2021-10-12 21:36:58.000000000 +0200 @@ -92,10 +92,10 @@ # directory. # if [ -e $SPOOL/etc/setup.cache ] && [ ! -e $DIR_LIBDATA/setup.cache ]; then - ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache + ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache || ln -s $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache fi if [ -e $SPOOL/etc/setup.modem ] && [ ! -e $DIR_LIBDATA/setup.modem ]; then - ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem + ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem || ln -s $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem fi test -f $DIR_LIBDATA/setup.cache || { @@ -1233,9 +1233,9 @@ # Here we build up a MODEMCLASSES string and follow # (for no real reason) the enumeration in faxd/ClassModem.c++ # Class 1 = 1; Class 2 = 2; Class 2.0 = 3; - # Class 1.0 = 4; Class 2.1 = 5; + # Class 1.0 = 4; Class 2.1 = 5; Class 256 = 6 - RESPONSE="`echo $RESPONSE | $SED -e 's/[()]//g' \ + RESPONSE="`echo $RESPONSE | $SED -e 's/[()]//g' -e 's/256/6/g' \ -e 's/2\.0/3/g' -e 's/1\.0/4/g' -e 's/2\.1/5/g'`"; SUPPORT="This modem looks to have support for Class " MODEMCLASSES=""; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/etc/faxsetup.sh.in new/hylafax-7.0.5/etc/faxsetup.sh.in --- old/hylafax-7.0.4/etc/faxsetup.sh.in 2020-07-28 03:29:41.000000000 +0200 +++ new/hylafax-7.0.5/etc/faxsetup.sh.in 2021-10-12 21:39:04.000000000 +0200 @@ -778,10 +778,10 @@ # directory. # if [ -e $SPOOL/etc/setup.cache ] && [ ! -e $DIR_LIBDATA/setup.cache ]; then - ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache + ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache || ln -s $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache fi if [ -e $SPOOL/etc/setup.modem ] && [ ! -e $DIR_LIBDATA/setup.modem ]; then - ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem + ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem || ln -s $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem fi # @@ -2204,7 +2204,7 @@ $RM $DIR_SPOOL/etc/setup.modem $MV $DIR_LIBDATA/setup.tmp $DIR_LIBDATA/setup.modem $CHMOD 444 $DIR_LIBDATA/setup.modem - $LN $DIR_LIBDATA/setup.modem $DIR_SPOOL/etc/setup.modem + $LN $DIR_LIBDATA/setup.modem $DIR_SPOOL/etc/setup.modem || $LN -s $DIR_LIBDATA/setup.modem $DIR_SPOOL/etc/setup.modem $RM $DIR_LIBDATA/setup.cache $RM $DIR_SPOOL/etc/setup.cache @@ -2212,7 +2212,7 @@ echo '# on' `date` "for ${USER:-$euid}" dumpvals |sort)> $DIR_LIBDATA/setup.cache $CHMOD 444 $DIR_LIBDATA/setup.cache - $LN $DIR_LIBDATA/setup.cache $DIR_SPOOL/etc/setup.cache + $LN $DIR_LIBDATA/setup.cache $DIR_SPOOL/etc/setup.cache || $LN -s $DIR_LIBDATA/setup.cache $DIR_SPOOL/etc/setup.cache Note "" Note "Modem support functions written to $DIR_LIBDATA/setup.modem." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/etc/hylafax.in new/hylafax-7.0.5/etc/hylafax.in --- old/hylafax-7.0.4/etc/hylafax.in 2020-07-28 03:29:41.000000000 +0200 +++ new/hylafax-7.0.5/etc/hylafax.in 2021-10-12 21:39:47.000000000 +0200 @@ -59,10 +59,10 @@ # directory. # if [ -e $SPOOL/etc/setup.cache ] && [ ! -e $DIR_LIBDATA/setup.cache ]; then - ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache + ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache || ln -s $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache fi if [ -e $SPOOL/etc/setup.modem ] && [ ! -e $DIR_LIBDATA/setup.modem ]; then - ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem + ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem || ln -s $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem fi test -f $DIR_LIBDATA/setup.cache || { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/etc/probemodem.sh.in new/hylafax-7.0.5/etc/probemodem.sh.in --- old/hylafax-7.0.4/etc/probemodem.sh.in 2020-07-28 03:29:41.000000000 +0200 +++ new/hylafax-7.0.5/etc/probemodem.sh.in 2021-10-12 21:40:31.000000000 +0200 @@ -79,10 +79,10 @@ # directory. # if [ -e $SPOOL/etc/setup.cache ] && [ ! -e $DIR_LIBDATA/setup.cache ]; then - ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache + ln $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache || ln -s $SPOOL/etc/setup.cache $DIR_LIBDATA/setup.cache fi if [ -e $SPOOL/etc/setup.modem ] && [ ! -e $DIR_LIBDATA/setup.modem ]; then - ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem + ln $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem || ln -s $SPOOL/etc/setup.modem $DIR_LIBDATA/setup.modem fi # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/Class1.c++ new/hylafax-7.0.5/faxd/Class1.c++ --- old/hylafax-7.0.4/faxd/Class1.c++ 2021-08-17 17:42:04.000000000 +0200 +++ new/hylafax-7.0.5/faxd/Class1.c++ 2021-12-05 05:52:46.000000000 +0100 @@ -764,7 +764,7 @@ if (conf.class1RecvAbortOK == 0) { // modem doesn't send OK response pause(200); flushModemInput(); - (void) atCmd("AT", AT_OK, 100); + (void) atCmd("AT", AT_OK, 500); } else while (!waitFor(AT_OK, conf.class1RecvAbortOK) && lastResponse == AT_OTHER && !wasTimeout()); setTimeout(b); // XXX putModem clobbers timeout state diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/Class1Recv.c++ new/hylafax-7.0.5/faxd/Class1Recv.c++ --- old/hylafax-7.0.4/faxd/Class1Recv.c++ 2021-08-21 17:24:39.000000000 +0200 +++ new/hylafax-7.0.5/faxd/Class1Recv.c++ 2021-10-20 01:11:46.000000000 +0200 @@ -1390,6 +1390,7 @@ case FCF_MCF: case FCF_CFR: case FCF_RTN: + case FCF_ERR: /* It's probably just our own echo. */ messageReceived = false; signalRcvd = 0; @@ -1787,6 +1788,7 @@ case FCF_CFR: case FCF_CTR: case FCF_PPR: + case FCF_ERR: if ((rtncframe[2] & 0x80) == FCF_RCVR) { /* * Echo on the channel may be so lagged that we're hearing @@ -2006,7 +2008,17 @@ // sender may violate T.30-A.4.3 and send another signal (i.e. DCN) traceFCF("RECV recv", ppsframe.getFCF2()); } - u_int pgcount = u_int(prevPage/256)*256+frameRev[ppsframe[4]]; // cope with greater than 256 pages + if ((ppsframe.getFCF() == FCF_MPS || ppsframe.getFCF() == FCF_EOP || ppsframe.getFCF() == FCF_EOR || ppsframe.getFCF() == 0x00) && ppsframe.getLength() > 5) { + // sender appears to have sent a PPS signal but omitted the PPS FCF, let's fix it for them + protoTrace("We'll fix the sender's careless PPS signal."); + int fb = ppsframe.getLength() - 1; + ppsframe.put(ppsframe[fb]); + for (; fb > 2; fb--) ppsframe[fb] = ppsframe[fb-1]; + ppsframe[2] = FCF_PPS; + } + // cope with greater than 256 pages + u_int pgcount = u_int(prevPage/256)*256; + if (ppsframe.getLength() > 4) pgcount += frameRev[ppsframe[4]]; switch (ppsframe.getFCF()) { /* * PPS is the only valid signal, Figure A.8/T.30; however, some @@ -2155,7 +2167,7 @@ rtnframe.put(ppsframe, ppsframe.getLength()); } pprcnt = 0; - if (signalRcvd != 0 || recvFrame(rtnframe, FCF_RCVR, conf.t2Timer)) { + if (signalRcvd != 0 || recvFrame(rtnframe, FCF_RCVR, conf.t2Timer, false, true, true, FCF_PPR)) { bool gotrtnframe = true; if (signalRcvd == 0) traceFCF("RECV recv", rtnframe.getFCF()); else signalRcvd = 0; // reset it, we're in-sync now @@ -2169,7 +2181,7 @@ } transmitFrame(FCF_PPR, fxStr(ppr, 32)); traceFCF("RECV send", FCF_PPR); - gotrtnframe = recvFrame(rtnframe, FCF_RCVR, conf.t2Timer); + gotrtnframe = recvFrame(rtnframe, FCF_RCVR, conf.t2Timer, false, true, true, FCF_PPR); if (gotrtnframe) traceFCF("RECV recv", rtnframe.getFCF()); recvFrameCount++; @@ -2527,6 +2539,22 @@ traceFCF("RECV recv", frame.getFCF()); again = frame.moreFrames(); switch (frame.getFCF()) { + case FCF_MPS: + case FCF_EOP: + case FCF_EOM: + // The sender repeated the post-page message. Maybe they didn't hear our interrupt signal. Try again. + if (counter > 1) { + // The sender is failing to respond properly to the interrupt signal. There's not much we can do that does not risk page receipt confirmation. + protoTrace("This sender appears to not respond properly to procedural interrupts."); + senderConfusesPIN = true; + emsg = "RSPREC invalid response to procedural interrupt"; + return (false); + } + (void) switchingPause(emsg); + (void) transmitFrame(interruptFCF|FCF_RCVR); + traceFCF("RECV send", interruptFCF); + again = true; + break; case FCF_PRI_MPS: case FCF_PRI_EOP: case FCF_PRI_EOM: @@ -2535,6 +2563,22 @@ case FCF_PPS: traceFCF("RECV recv", frame.getFCF2()); switch (frame.getFCF2()) { + case FCF_MPS: + case FCF_EOP: + case FCF_EOM: + // The sender repeated the partial-page message. Maybe they didn't hear our interrupt signal. Try again. + if (counter > 1) { + // The sender is failing to respond properly to the interrupt signal. There's not much we can do other than respond with PPR, which would defeat our reason for performing the interrupt. + protoTrace("This sender appears to not respond properly to procedural interrupts."); + senderConfusesPIN = true; + emsg = "RSPREC invalid response to procedural interrupt"; + return (false); + } + (void) switchingPause(emsg); + (void) transmitFrame(interruptFCF|FCF_RCVR); + traceFCF("RECV send", interruptFCF); + again = true; + break; case FCF_PRI_MPS: case FCF_PRI_EOP: case FCF_PRI_EOM: @@ -2542,7 +2586,6 @@ break; } break; - case FCF_TSI: case FCF_DCS: // The sender treats PIN as RTN. Expect TCF to follow, but we'll disregard both signals recvTraining(false); @@ -2550,7 +2593,7 @@ doCED = false; // CED introduces too much delay - and this sender isn't expecting it, anyway. break; case FCF_DCN: - protoTrace("This sender appears to not respond properly to PIN."); + protoTrace("This sender appears to not respond properly to procedural interrupts."); senderConfusesPIN = true; emsg = "RSPREC error/got DCN (sender abort) {E103}"; recvdDCN = true; @@ -2587,6 +2630,8 @@ return (false); } } + if (gotEOT) return (false); + FaxSetup setupinfo; setupinfo.senderConfusesRTN = senderConfusesRTN; setupinfo.senderConfusesPIN = senderConfusesPIN; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/Class1Send.c++ new/hylafax-7.0.5/faxd/Class1Send.c++ --- old/hylafax-7.0.4/faxd/Class1Send.c++ 2021-08-27 02:29:48.000000000 +0200 +++ new/hylafax-7.0.5/faxd/Class1Send.c++ 2021-11-19 15:29:34.000000000 +0100 @@ -125,10 +125,50 @@ */ if (conf.class1EnableV34Cmd != "" && serviceType == SERVICE_CLASS10) { if (conf.class10AutoFallback) return (V34FAIL); - if (atCmd(rhCmd, AT_NOTHING) && atResponse(rbuf, conf.t2Timer) == AT_CONNECT) return (OK); - if (wasTimeout()) abortReceive(); - // Apparently the call was answered, V.8 didn't occur, but no V.21 HDLC was detected. - return (NOCARRIER); + /* + * As the modem says that it already detected a carrier of some sort, presumably + * V.21 HDLC, we don't need to wait T1 or even T2 for it. So, we set a short + * timeout period for the CONNECT message here in case the modem glitch mentioned + * below is an issue on this call. + */ + if (atCmd(rhCmd, AT_NOTHING) && atResponse(rbuf, 2000) == AT_CONNECT) return (OK); + if (wasTimeout()) { + /* + * The Si2435 has a glitch (at least in "D" firmware) where it can miss the +FRH=3 + * command above at this point in the call. The workaround is to just re-issue the + * command. We deliberately do not abortRecive() here, as that trips things up further. + */ + if (atCmd(rhCmd, AT_NOTHING) && atResponse(rbuf, conf.t1Timer) == AT_CONNECT) return (OK); + if (wasTimeout()) { + // Apparently T1 elapsed with no further carrier signal. + abortReceive(); + return (NOCARRIER); + } + if (lastResponse == AT_OK) { + /* + * The second +FRH=3 actually canceled the first. So, in this instance there was + * no glitch, and we probably should have had a longer timeout setting on the first + * +FRH=3. But, since the glitch condition is more likely we'll just re-issue +FRH=3 + * one last time. + */ + if (atCmd(rhCmd, AT_NOTHING) && atResponse(rbuf, conf.t1Timer) == AT_CONNECT) return (OK); + if (wasTimeout()) { + // Apparently T1 elapsed with no further carrier signal. + abortReceive(); + return (NOCARRIER); + } + if (lastResponse == AT_OK) { + // The Si2435 appears to result OK on its own after 30 seconds' wait at this point. + return (NOCARRIER); + } + // We got some other result (besides CONNECT or OK) to the third +FRH=3 command. + return (FAILURE); + } + // We got some other result (besides CONNECT or OK) to the second +FRH=3 command. + return (FAILURE); + } + // We got some other result (besides CONNECT) to the second +FRH=3 command. + return (FAILURE); } if (r == AT_OK) return (NOCARRIER); @@ -270,7 +310,7 @@ curcap = NULL; // force initial setup break; } - } while (frame.moreFrames() && recvFrame(frame, FCF_SNDR, conf.t2Timer)); + } while (frame.moreFrames() && recvFrame(frame, FCF_SNDR, ((t1-(Sys::now()-start))*1000 + conf.t2Timer))); // wait to T1 timeout, but at least T2 if (frame.isOK()) { switch (frame.getRawFCF()) { case FCF_DIS: @@ -292,6 +332,10 @@ protoTrace(emsg); return (send_retry); default: + if (frame.getRawFCF() & FCF_SNDR) { + protoTrace("The receiver thinks that they are the sender."); + } + traceFCF("Unexpectedly received", frame.getFCF()); emsg = "COMREC invalid command received/no DIS or DTC {E125}"; protoTrace(emsg); break; @@ -301,10 +345,11 @@ /* * Wait up to T1 for a valid DIS. */ - if ((unsigned) Sys::now()-start >= t1) + time_t now = Sys::now(); + if ((unsigned) now-start >= t1) break; (void) switchingPause(emsg); - framerecvd = recvFrame(frame, FCF_SNDR, (Sys::now()-start)*1000); // timer here is T1 + framerecvd = recvFrame(frame, FCF_SNDR, ((t1-(now-start)))*1000 + conf.t2Timer); // wait to T1 timeout, but wait at least T2 } if (emsg == "") { emsg = "No receiver protocol (T.30 T1 timeout) {E126}"; @@ -758,6 +803,7 @@ return (send_retry); } break; + case FCF_FTT: case FCF_NSF: case FCF_CSI: case FCF_DIS: @@ -1117,7 +1163,7 @@ * FTT, or CFR; and also a premature DCN. */ HDLCFrame frame(conf.class1FrameOverhead); - bool gf = recvFrame(frame, FCF_SNDR, conf.t4Timer); + bool gf = recvFrame(frame, FCF_SNDR, conf.t4Timer, false, false); #if defined(HAVE_SSL) if (!isSSLFax && useSSLFax) { SSLFax sslfax; @@ -1145,9 +1191,9 @@ } // The SSL Fax connection tripped up recvFrame, so we need to repeat it. if (!isSSLFax) { - gf = (waitFor(AT_CONNECT, conf.t4Timer) && recvFrame(frame, FCF_SNDR, conf.t4Timer, true)); + gf = (waitFor(AT_CONNECT, conf.t4Timer) && recvFrame(frame, FCF_SNDR, conf.t4Timer, true, false)); } else { - gf = recvFrame(frame, FCF_SNDR, conf.t4Timer); + gf = recvFrame(frame, FCF_SNDR, conf.t4Timer, false, false); } } } @@ -1191,6 +1237,7 @@ if (!isSSLFax && !useV34) protoTrace("TRAINING succeeded"); setDataTimeout(60, params.br); return (true); + case FCF_RTN: // confusing signal to receive in Phase B, but this is how to handle it case FCF_FTT: // failure to train, retry t--; // immediately drop bitrate rather than trying the same bitrate again case FCF_CRP: // command repeat @@ -1269,6 +1316,7 @@ failed: emsg = "Failure to train remote modem at 2400 bps or minimum speed {E137}"; done: + if (!emsg.length()) emsg = "Unspecified failure to train with receiver"; if (!isSSLFax && !useV34) protoTrace("TRAINING failed"); return (false); } @@ -1647,7 +1695,7 @@ } } while (!gotppr && (++ppscnt < 3) && (crpcnt < 3) && !gotEOT && switchingPause(emsg)); if (gotppr) { - if (pprframe.getFCF() == FCF_NSF || pprframe.getFCF() == FCF_CSI || pprframe.getFCF() == FCF_DIS) { + if (pprframe.getFCF() == FCF_NSF || pprframe.getFCF() == FCF_CSI || pprframe.getFCF() == FCF_DIS || pprframe.getFCF() == FCF_FTT || pprframe.getFCF() == FCF_RTN) { // Takes us back to Phase B. Break out of the loop, and handle it upstream. blockgood = true; signalRcvd = pprframe.getFCF(); @@ -1702,6 +1750,7 @@ case FCF_NSF: case FCF_CSI: case FCF_DIS: + case FCF_RTN: gotppr = true; break; case FCF_RNR: @@ -1710,12 +1759,16 @@ } break; default: - emsg = "COMREC invalid response received to RR. {E140}"; + if (pprframe.getFCF() == FCF_DCN) { + emsg = "COMREC error/got DCN (receiver abort) {E103}"; + } else { + emsg = "COMREC invalid response received to RR. {E140}"; + } protoTrace(emsg); return (false); } } while (!gotppr); - if (pprframe.getFCF() == FCF_NSF || pprframe.getFCF() == FCF_CSI || pprframe.getFCF() == FCF_DIS) { + if (pprframe.getFCF() == FCF_NSF || pprframe.getFCF() == FCF_CSI || pprframe.getFCF() == FCF_DIS || pprframe.getFCF() == FCF_FTT || pprframe.getFCF() == FCF_RTN) { // Takes us back to Phase B. Break out of the loop, and handle it upstream. blockgood = true; signalRcvd = pprframe.getFCF(); @@ -1729,6 +1782,19 @@ blockgood = true; signalRcvd = pprframe.getFCF(); break; + case FCF_CFR: + /* + * The most likely situation where this could arise would be if the receiver + * didn't catch our Phase C signal on the first iteration of the first block + * on the first page. So, the receiver oddly chose to respond to PPS with a + * repeated CFR instead of a PPR signal. So, we treat it as a PPR signal, but + * we do need to reset pprcnt, as we do with an out-of-sync CTR response. + * However, in the event that we're not following the first iteration of the + * first block on the first page we're just going to presume that the receiver + * wants us to reset our status back to the first iteration of this block. So, + * we need to reset the ppr map. + */ + for (u_int i = 0; i < 32; i++) ppr[i] = 0xff; case FCF_CTR: /* * We didn't send CTC yet received CTR. We may be out-of-sync with the receiver @@ -1742,7 +1808,7 @@ { pprcnt++; // update ppr - for (u_int i = 3; i < (pprframe.getLength() - (conf.class1FrameOverhead - 2)); i++) { + for (u_int i = 3; i < (pprframe.getLength() - (conf.class1FrameOverhead - 2)) && i < 36; i++) { ppr[i-3] = pprframe[i]; } badframesbefore = badframes; @@ -1827,7 +1893,7 @@ sendFrame(FCF_CTC|FCF_SNDR, fxStr(ctc, 2)); stopTimeout("sending CTC frame"); traceFCF("SEND send", FCF_CTC); - gotctr = recvFrame(ctrframe, FCF_SNDR, conf.t4Timer, false, true, true, FCF_CTC); + gotctr = recvFrame(ctrframe, FCF_SNDR, conf.t4Timer, false, false, true, FCF_CTC); if (gotctr) { traceFCF("SEND recv", ctrframe.getFCF()); if (ctrframe.getFCF() == FCF_PPR) { @@ -1851,14 +1917,18 @@ protoTrace(emsg); return (false); } - if (ctrframe.getFCF() == FCF_NSF || ctrframe.getFCF() == FCF_CSI || ctrframe.getFCF() == FCF_DIS) { + if (ctrframe.getFCF() == FCF_NSF || ctrframe.getFCF() == FCF_CSI || ctrframe.getFCF() == FCF_DIS || ctrframe.getFCF() == FCF_FTT || ctrframe.getFCF() == FCF_RTN) { // Takes us back to Phase B. Break out of the loop, and handle it upstream. blockgood = true; - signalRcvd = pprframe.getFCF(); + signalRcvd = ctrframe.getFCF(); break; } if (!(ctrframe.getFCF() == FCF_CTR)) { - emsg = "COMREC invalid response received to CTC. {E142}"; + if (ctrframe.getFCF() == FCF_DCN) { + emsg = "COMREC error/got DCN (receiver abort) {E103}"; + } else { + emsg = "COMREC invalid response received to CTC. {E142}"; + } protoTrace(emsg); return (false); } @@ -1894,7 +1964,7 @@ stopTimeout("sending EOR frame"); traceFCF("SEND send", FCF_EOR); traceFCF("SEND send", pps[0]); - goterr = recvFrame(errframe, FCF_SNDR, conf.t4Timer); + goterr = recvFrame(errframe, FCF_SNDR, conf.t4Timer, false, false, true, FCF_EOR); if (goterr) { traceFCF("SEND recv", errframe.getFCF()); if (errframe.getFCF() == FCF_CRP) { @@ -1963,20 +2033,28 @@ } break; default: - emsg = "COMREC invalid response received to RR. {E140}"; + if (errframe.getFCF() == FCF_DCN) { + emsg = "COMREC error/got DCN (receiver abort) {E103}"; + } else { + emsg = "COMREC invalid response received to RR. {E140}"; + } protoTrace(emsg); return (false); } } while (!goterr); } - if (errframe.getFCF() == FCF_NSF || errframe.getFCF() == FCF_CSI || errframe.getFCF() == FCF_DIS) { + if (errframe.getFCF() == FCF_NSF || errframe.getFCF() == FCF_CSI || errframe.getFCF() == FCF_DIS || errframe.getFCF() == FCF_FTT || errframe.getFCF() == FCF_RTN) { // Takes us back to Phase B. Break out of the loop, and handle it upstream. blockgood = true; - signalRcvd = pprframe.getFCF(); + signalRcvd = errframe.getFCF(); break; } if (!(errframe.getFCF() == FCF_ERR)) { - emsg = "COMREC invalid response received to EOR. {E145}"; + if (errframe.getFCF() == FCF_DCN) { + emsg = "COMREC error/got DCN (receiver abort) {E103}"; + } else { + emsg = "COMREC invalid response received to EOR. {E145}"; + } protoTrace(emsg); return (false); } @@ -2053,6 +2131,7 @@ case FCF_DIS: case FCF_PIP: case FCF_PIN: + case FCF_FTT: /* * We got one of these signals in response to PPS-NULL. * We need to go return upstream to start this page over again. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/ClassModem.c++ new/hylafax-7.0.5/faxd/ClassModem.c++ --- old/hylafax-7.0.4/faxd/ClassModem.c++ 2021-07-16 07:32:23.000000000 +0200 +++ new/hylafax-7.0.5/faxd/ClassModem.c++ 2021-10-26 21:40:18.000000000 +0200 @@ -590,8 +590,8 @@ return (true); } -void ClassModem::flushModemInput() - { server.modemFlushInput(); } +void ClassModem::flushModemInput(bool silent) + { server.modemFlushInput(silent); } bool ClassModem::putModem(void* d, int n, long ms) { return server.putModem(d, n, ms); } bool ClassModem::putModemData(void* d, int n, long ms) @@ -953,6 +953,14 @@ u_int cmdlen; u_int pos; bool respPending; + + /* + * We clear any lingering input from the modem, as we're not going to be expecting it. + * Most notably we do sometimes see spurious +FCERROR messages from Si2417/Si2435 + * after an +FRM command is aborted. + */ + flushModemInput(true); + if (lastResponse == AT_RING) lastResponse = AT_NOTHING; do { cmdlen = cmd.length(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/ClassModem.h new/hylafax-7.0.5/faxd/ClassModem.h --- old/hylafax-7.0.4/faxd/ClassModem.h 2021-02-05 17:04:28.000000000 +0100 +++ new/hylafax-7.0.5/faxd/ClassModem.h 2021-10-26 21:40:18.000000000 +0200 @@ -271,7 +271,7 @@ bool wasTimeout(); bool wasModemError(); void setTimeout(bool); - void flushModemInput(); + void flushModemInput(bool silent = false); bool putModem(void* data, int n, long ms = 0); bool putModemData(void* data, int n, long ms = -1); bool putModemDLEData(const u_char* data, u_int, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/CopyQuality.c++ new/hylafax-7.0.5/faxd/CopyQuality.c++ --- old/hylafax-7.0.4/faxd/CopyQuality.c++ 2021-07-25 23:16:27.000000000 +0200 +++ new/hylafax-7.0.5/faxd/CopyQuality.c++ 2021-10-26 15:57:24.000000000 +0200 @@ -328,8 +328,6 @@ * junk from the sender. */ copyQualityTrace("Adjusting for trailing noise (%lu run)", cblc); - if (cblc > recvConsecutiveBadLineCount) - recvConsecutiveBadLineCount = cblc; recvEOLCount -= cblc; recvBadLineCount -= cblc; if ((recvRow -= cblc*rowSize) < buf) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/ModemServer.c++ new/hylafax-7.0.5/faxd/ModemServer.c++ --- old/hylafax-7.0.4/faxd/ModemServer.c++ 2021-07-25 23:16:27.000000000 +0200 +++ new/hylafax-7.0.5/faxd/ModemServer.c++ 2021-10-26 21:40:18.000000000 +0200 @@ -1618,9 +1618,9 @@ } void -ModemServer::modemFlushInput() +ModemServer::modemFlushInput(bool silent) { - traceModemOp("flush i/o"); + if (!silent) traceModemOp("flush i/o"); flushModemInput(); if (tcflush(modemFd, TCIFLUSH) != 0) traceModemOp("tcflush: %m"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/ModemServer.h new/hylafax-7.0.5/faxd/ModemServer.h --- old/hylafax-7.0.4/faxd/ModemServer.h 2021-02-05 17:04:28.000000000 +0100 +++ new/hylafax-7.0.5/faxd/ModemServer.h 2021-10-26 21:40:18.000000000 +0200 @@ -188,7 +188,7 @@ bool modemWaitForRings(u_short rings, CallType&, CallID&); CallType modemAnswerCall(AnswerType, fxStr&, const char* dialnumber = NULL, bool doSecondAnswer = false); void modemAnswerCallCmd(CallType); - void modemFlushInput(); + void modemFlushInput(bool silent = false); void modemHangup(); // server state and related control interfaces void changeState(ModemServerState, long timeout = 0, const char* msg = NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/faxd/faxQueueApp.c++ new/hylafax-7.0.5/faxd/faxQueueApp.c++ --- old/hylafax-7.0.4/faxd/faxQueueApp.c++ 2021-07-25 23:16:27.000000000 +0200 +++ new/hylafax-7.0.5/faxd/faxQueueApp.c++ 2021-10-13 00:16:45.000000000 +0200 @@ -1356,6 +1356,7 @@ dup2(fd, STDIN_FILENO); Sys::close(fd); } + setRealIDs(); // prevent root from operating on user-supplied files Sys::execv(app, argv); sleep(3); // XXX give parent time to catch signal _exit(255); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/hfaxd/HylaFAXServer.h new/hylafax-7.0.5/hfaxd/HylaFAXServer.h --- old/hylafax-7.0.4/hfaxd/HylaFAXServer.h 2021-07-25 23:16:27.000000000 +0200 +++ new/hylafax-7.0.5/hfaxd/HylaFAXServer.h 2021-09-23 16:07:10.000000000 +0200 @@ -54,11 +54,11 @@ #include <ldap.h> #include <string.h> #include <stdlib.h> -#include <stdint.h> #include <sys/time.h> #include <lber.h> #endif // HAVE_LDAP +#include <stdint.h> #include <sys/types.h> #include <sys/socket.h> #include <dirent.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-7.0.4/man/hylafax-config.4f new/hylafax-7.0.5/man/hylafax-config.4f --- old/hylafax-7.0.4/man/hylafax-config.4f 2021-08-16 19:18:24.000000000 +0200 +++ new/hylafax-7.0.5/man/hylafax-config.4f 2021-12-05 05:57:28.000000000 +0100 @@ -2995,7 +2995,7 @@ If this number is zero, then the modem is assumed to not correctly implement aborting and instead the driver will wait 200ms, flush any input, and then send ``\s-1AT\en\s+1'' and wait -100ms for an ``\s-1OK\s+1'' result. +500ms for an ``\s-1OK\s+1'' result. .TP .B Class1RecvIdentTimer The time, in milliseconds, to wait for an initial