Hylafax Developers Mailing List Archives

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

[hylafax-devel] Endless RTN -- seems to be fixed now!



I am glad to inform you that after a couple of days of hard work I have
found a bug which caused infamous "endless RTN" problem. There is nothing
special - Hylafax just violated T.4/T.class2 protocol specs :-)

To be more specific, T.4/T.class2 (Class 2.0 standard) defines the
following format for the Phase C data (core of G3 fax protocol):

<EOL>
<1-st encoded raw>
<EOL>
<2-nd encoded raw>
<EOL>
...
<last encoded raw>
<RTC>
<DLE><EOP>

But Hylafax generates:

<EOL>             \
<1-st encoded raw> \
<EOL>               \
<2-nd encoded raw>   \ from Hylafax-generated g3 TIFF contains it
<EOL>                /
...                 /
<last encoded raw> /
<RTC>             /     
<RTC>             -- sendRTC()
<DLE><EOP>

(not always -- just when no chopping happened. See the attached patches for
details).

As you can see, RTC is transmitted twice, and it may cause missing of the
RTC/EOP and generating RTN/other transmission errors by the remote fax
machine. Endless RTN (and possibly other unidentified errors) is here.

Well, the attached patches seems to fix that. They are still experimental
and possibly incomplete, but they work for me (tested with Zyxel 1496E in
Class 2.0 mode).  A Panasonic BX780 fax machine, connected to the server
via PBX, i.e. directly, now successfully generates MCF (always responded
with RTN before). Could you, folks, check if they work for you also.

Any comments are always welcome,

Hope to hear from you soon,
Dmitry

P.S. I am also going to publish tsi processing bug fixes (after some
testing). Stay tuned :-)

--- faxd\Class2Send.c++.orig	Sat Jun 12 21:00:00 1999
+++ faxd\Class2Send.c++	Fri Mar 10 20:49:04 2000
@@ -376,6 +376,39 @@
 		off += (u_int) sbc;
 	}
 	totdata -= pageChop;		// deduct trailing white space not sent
+
+	/*
+	 * There should be no EOL or RTC after the last
+	 * pixel row; we will or will not send RTC later
+	 * depending on the class of the modem
+	 * via Class2Modem::sendRTC().
+	 *
+	 * If the image was chopped, last row's EOL
+	 * was removed during that process - that's
+	 * OK, nothing else should be done.
+	 *
+	 * If there was no chopping, full 1-D or 2-D
+	 * RTC (6 consecutive EOL's) may be present
+	 * since it was written to the TIFF file -
+	 * remove it.
+	 */
+
+        if( !pageChop ){
+	    /*
+	     * Method of deleting RTC is not quite correct
+	     * since RTC may not present in the TIFF
+	     * file (if the TIFF was not Hylafax-generated).
+	     * It this case we will corrupt some last rows.
+	     * Also (again if the TIFF was not Hylafax-generated)
+	     * RTC may be not byte-aligned, and again, we will
+	     * corrupt some image data.
+	     * Ideally, we should scan TIFF for RTC and remove
+	     * it where it's found. Maybe I will implement this later
+	     * - D.B. 
+	     */
+            totdata -= (params.is2D())? 10: 9;
+	}
+        
 	/*
 	 * Image the tag line, if intended, and then
 	 * pass the data to the modem, filtering DLE's

--- faxd\Class20.c++.orig	Sat Jun 12 21:00:00 1999
+++ faxd\Class20.c++	Fri Mar 10 19:42:26 2000
@@ -162,12 +162,24 @@
 	    case AT_FHNG:
 		if (!isNormalHangup())
 		    return (false);
-		/* fall thru... */
-	    case AT_OK:				// page data good
-		ppr = PPR_MCF;			// could be PPR_RTP/PPR_PIP
+		ppr = PPR_MCF;
 		return (true);
-	    case AT_ERROR:			// page data bad
-		ppr = PPR_RTN;			// could be PPR_PIN
+	    case AT_OK:
+	    case AT_ERROR:
+		/*
+		 * Despite of the (wrong) comment above,
+		 * we do explicit status query e.g. to
+		 * distinguish between RTN and PIN 
+		 */
+		{
+		    fxStr s;
+		    if(!atQuery("AT+FPS?", s) ||
+		       sscanf(s, "%u", &ppr) != 1){
+		        protoTrace("MODEM protocol botch (\"%s\"), %s",
+		    		   (char*)s, "can not parse PPR");
+		        return (false);		// force termination
+		    }
+		}
 		return (true);
 	    case AT_EMPTYLINE:
 	    case AT_TIMEOUT:

--- faxd\G3Encoder.c++.orig	Sat Jun 12 21:00:00 1999
+++ faxd\G3Encoder.c++	Fri Mar 10 19:42:44 2000
@@ -72,13 +72,14 @@
 {
     u_int rowbytes = howmany(w, 8);
 
+    short eol = (is2D) ? (EOL<<1)|1 : EOL;
+    short eol_len = (is2D) ? 13 : 12;
+    short fill_bits = 16 - eol_len;
     while (h-- > 0) {
-	if (bit != 4)					// byte-align EOL
-	    putBits(0, (bit < 4) ? bit+4 : bit-4);
-	if (is2D)
-	    putBits((EOL<<1)|1, 12+1);
-	else
-	    putBits(EOL, 12);
+	if (bit != fill_bits)	
+	    // byte-align EOL
+	    putBits(0, (bit < fill_bits) ? bit+fill_bits : bit-fill_bits );
+	putBits(eol, eol_len);
 	int bs = 0, span;
 	const u_char* bp = (const u_char*) vp;
 	for (;;) {



Home
Report any problems to webmaster@hylafax.org

HylaFAX is a trademark of Silicon Graphics Corporation.
Internet connectivity for hylafax.org is provided by:
VirtuALL Private Host Services