Hylafax Developers Mailing List Archives
|
[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
[hylafax-devel] a bundle of my patches, try #3 :-)
Here is the updated set of my changes against current CVS; I have separated
them into the different independent parts to make Robert happy :-) (well,
it's third attempt to commit this code; I hope it will be finally
successful :-)) But it may cause some problems: first, I had to split the
monolitic diff by hands, so could miss/break something, and second, they
cannot be automatically applied in sequence (although any single part
can). So be extremely careful!
OK, after the caution let's return to our business :-) Here is the list of
changes and appropriate diffs:
General Class1 changes
----------------------
Decoding of T.30 DIS frame
Due to the bug DIS decording routine failed on the short frames (with
"remote is not T.4 compatible" error).
HDLC timeout
Orginal code supposed that HDLC flags is present in DCE-supplied data (in
responce to AT+FRH=3) and set timeouts wrong way. This caused connection
sometimes to be incorrectly terminated.
Number of training attempts
If the training attempt was unsuccessful, original code tried every speed
twice, i.e.
14400->14400->12000->12000->9600->...
I believe it was only wasting the time. Not each speed is tried once:
14400->12000->9600->...
General Class 2.0 changes
-------------------------
Class 2.0 PPM query
Explicit status query to distinguish between RTN and PIN.
RTN related changes
-------------------
Reencoding first EOL and removing extra RTC/EOL in the end of TIFF data
Reencode TIFF data so that first EOL does not contain zero fill bits
(prohibited by T.4) and remove trailing RTC/EOL if present (will be appended
later if necessary).
Class2SendRTC now affects Class 2.0
According to Class 2.0 specs DCE sends RTC itself, so I have made
Class2SendRTC config parameter (with default value "no") affect Class2.0
operation as well as Class2 one.
RTNHandlingMethod parameter
Specifies how to react to RTN signal, received from the remote;
one of ``Retransmit'', ``Giveup'' and ``Ignore''. ``Retransmit''
assumes that the page is not sent succesfully if RTN signal has been received.
Hylafax will made up to 2 additional attempts to send the page,
decreasing signalling rate and retraining. If RTN is still there,
it will place up to 2 additional calls. So if the remote always respond with
RTN, the page will be send 9 times. Although this algorithm comply with
T.30 specs and was originally implemented by Sam Leffler as the only
possible choice, real fax machines behave completely different. There is a
non-written rule among fax developers, that RTN means ``over and out'' -- hang
up immediately and never try to send the same page to the same destination
again. That is because RTN usually indicates problems with flow control,
incorrectly encoded T.4 data, incompatibility between local and remote
equipment etc., but very rarely is caused by the real noise on the line.
This ``over and out'' behaviour can be activated by ``Giveup'' value.
There is also third option, not so radical as ``Giveup''. Yes, we will never
retransmit the page, but we can try to send the next page, and let the
remote to decide what to do (accept our decision or hang up). Thus one page will
(or will not) be missed but we have a chance to successfully send all other pages.
This behaviour can be activated by ``Ignore'' value.
Class1 RTN alrogithm
Adapted to use RTNHandlingMethod parameter, and work the same (right) way
as in Class2/2.0 mode.
Class2 RTN alrogithm
Adapted to use RTNHandlingMethod parameter
Default config values
---------------------
These changes affect only parameters' default value, i.e value used if the
parameter is not present in config.<modem> file. If the parameter's value
is explicitly specified, it will be used anyway.
Now all (I hope) Class* and Modem* parameters have reasonable defaults so
that most (if not all) modems should work "out of the box" with no Class*
and Modem* entries in their config.<modem> files. Of course, if you need
extra features (adaptive answer, custom dial commands etc.), you still have
to append necessary parameters yourself.
ModemType
If not present, sequence Class 2.0->Class2->Class1 is tried until supported
fax class is found. Buggy USR modems are immediately switched to
Class1. (Again, if you don't like it, just add "ModemType: Class2.0" entry
to your config.<modem>)
ModemFlowControl
Default value is changed to "XONXOFF" which is supported by any modem and
is activated after AT+FCLASS=2 and AT+FCLASS=2.0. BTW, software flow control
is quite enough due to the half-duplex nature of fax protocol.
ModemSendFillOrder
ModemRecvFillOrder
Now are correctly set for Class1, Class2, Class2.0. Special "Multitech"
case (the only modem known to me, which uses RecvFillOrder=LSB2MSB in Class2) is
(should be) handled properly. People who own Multitech, can you check if it
works with the patch applied? (just comment out ModemSendFillOrder &
ModemRecvFillOrder in your config and see if it still works).
Updated config templates
------------------------
For the modems I've tested. (Zyxel & USR)
Well, I should also say, that default config/Class* templates (those that
faxaddmodem script uses if it cannot identify the modem) are completely
broken -- no neccessary Modem* entries and absolutely useless Class*
ones. *No* unidentified Class2 modem will work with faxaddmodem-generated
config and Hylafax without my patches!
I have not changed these "template" because after my patches there is no
need in them -- above config defaults do the job. If the changes are
commited, you can simply wipe "templates" out :-)
Hope to hear from you soon,
Dmitry
Index: hylafax/faxd/Class1.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class1.c++,v
retrieving revision 1.3
diff -u -r1.3 Class1.c++
--- Class1.c++ 1999/08/23 11:19:31 1.3
+++ Class1.c++ 2000/06/05 10:09:59
@@ -396,8 +406,7 @@
}
/*
- * Receive an HDLC frame. The timeout is against
- * the receipt of the HDLC flags; the frame itself must
+ * Receive an HDLC frame. The frame itself must
* be received within 3 seconds (per the spec).
* If a carrier is received, but the complete frame
* is not received before the timeout, the receive
@@ -408,20 +417,22 @@
{
int c;
/*
- * Search for HDLC frame flags. The
- * timeout is to reception of the flags.
+ * The spec says that a frame that takes between
+ * 2.55 and 3.45 seconds to be received may be
+ * discarded; we also add some time for DCE
+ * to detect and strip flags.
*/
+ startTimeout(5000);
+ /*
+ * Strip HDLC frame flags. This is not needed,
+ * (according to the standard DCE does the job),
+ * be we leave this legacy code unchanged
+ * for sure - D.B.
+ */
do {
c = getModemChar(0);
} while (c != EOF && c != 0xff);
- stopTimeout("waiting for HDLC flags");
- if (c == 0xff) { // flags received
- /*
- * The spec says that a frame that takes between
- * 2.55 and 3.45 seconds to be received may be
- * discarded; we use 3.1 seconds as a compromise.
- */
- startTimeout(3100);
+ if (c == 0xff) { // address field received
do {
if (c == DLE) {
c = getModemChar(0);
@@ -430,8 +441,8 @@
}
frame.put(frameRev[c]);
} while ((c = getModemChar(0)) != EOF);
- stopTimeout("receiving HDLC frame data");
}
+ stopTimeout("receiving HDLC frame data");
if (wasTimeout()) {
abortReceive();
return (false);
@@ -638,8 +649,14 @@
frame.reset();
startTimeout(ms);
bool readPending = atCmd(rhCmd, AT_NOTHING);
- if (readPending && waitFor(AT_CONNECT,0))
- return recvRawFrame(frame); // NB: stops inherited timeout
+ if (readPending && waitFor(AT_CONNECT,0)){
+ stopTimeout("waiting for HDLC flags");
+ if (wasTimeout()){
+ abortReceive();
+ return (false);
+ }
+ return recvRawFrame(frame);
+ }
stopTimeout("waiting for v.21 carrier");
if (readPending && wasTimeout())
abortReceive();
Index: hylafax/faxd/Class1Send.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class1Send.c++,v
retrieving revision 1.3
diff -u -r1.3 Class1Send.c++
--- Class1Send.c++ 2000/05/15 13:23:43 1.3
+++ Class1Send.c++ 2000/06/05 10:10:20
@@ -103,9 +103,7 @@
time_t start = Sys::now();
HDLCFrame frame(conf.class1FrameOverhead);
- startTimeout(conf.t2Timer);
bool framerecvd = recvRawFrame(frame);
- stopTimeout("receiving id frame");
for (;;) {
if (framerecvd) {
/*
@@ -465,7 +471,16 @@
*/
params.br = curcap->br;
dcs = (dcs &~ DCS_SIGRATE) | curcap->sr;
- int t = 2;
+ /*
+ * Set the number of train attemps on the same
+ * modulation; having set it to 1 we immediately drop
+ * the speed if the training has been failed.
+ * This parameter is not specified by T.30
+ * (the algorith left implementation defined),
+ * so we choose the exact value according to our
+ * common sense.
+ */
+ int t = 1;
do {
protoTrace("SEND training at %s %s",
modulationNames[curcap->mod],
@@ -540,7 +555,7 @@
pause(conf.class1TrainingRecovery);
} while (--t > 0);
/*
- * Two attempts at the current speed failed, drop
+ * (t) attempts at the current speed failed, drop
* the signalling rate to the next lower rate supported
* by the local & remote sides and try again.
*/
@@ -846,6 +867,7 @@
return (false);
}
emsg = "No response to MPS or EOP repeated 3 tries";
+ protoTrace(emsg);
return (false);
}
Index: hylafax/faxd/HDLCFrame.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/HDLCFrame.c++,v
retrieving revision 1.2
diff -u -r1.2 HDLCFrame.c++
--- HDLCFrame.c++ 1999/06/13 07:41:04 1.2
+++ HDLCFrame.c++ 2000/06/05 10:10:45
@@ -105,10 +105,10 @@
HDLCFrame::getDataWord() const
{
u_int n = getFrameDataLength();
- u_int w = (n > 1) ? (*this)[3] : 0;
- if (n > 2) w = (w<<8)|(*this)[4];
- if (n > 3) w = (w<<8)|(*this)[5];
- if (n > 4) w = (w<<8)|(*this)[6];
+ u_int w = (n >= 1) ? (*this)[3] : 0;
+ if (n >= 2) w = (w<<8)|(*this)[4];
+ if (n >= 3) w = (w<<8)|(*this)[5];
+ if (n >= 4) w = (w<<8)|(*this)[6];
return w;
}
@@ -116,9 +116,9 @@
HDLCFrame::getDIS() const
{
u_int n = getFrameDataLength();
- u_int dis = (n > 1) ? (*this)[3] : 0;
- dis <<= 8; if (n > 2) dis |= (*this)[4];
- dis <<= 8; if (n > 3) dis |= (*this)[5];
+ u_int dis = (n >= 1) ? (*this)[3] : 0;
+ dis <<= 8; if (n >= 2) dis |= (*this)[4];
+ dis <<= 8; if (n >= 3) dis |= (*this)[5];
return dis;
}
@@ -126,9 +126,9 @@
HDLCFrame::getXINFO() const
{
u_int n = getFrameDataLength();
- u_int xinfo = (n > 4 && ((*this)[5] & 0x1)) ? (*this)[6] : 0;
- xinfo <<= 8; if (n > 5 && (xinfo & 0x100)) xinfo |= (*this)[7];
- xinfo <<= 8; if (n > 6 && (xinfo & 0x100)) xinfo |= (*this)[8];
- xinfo <<= 8; if (n > 7 && (xinfo & 0x100)) xinfo |= (*this)[9];
+ u_int xinfo = (n >= 4 && ((*this)[5] & 0x1)) ? (*this)[6] : 0;
+ xinfo <<= 8; if (n >= 5 && (xinfo & 0x100)) xinfo |= (*this)[7];
+ xinfo <<= 8; if (n >= 6 && (xinfo & 0x100)) xinfo |= (*this)[8];
+ xinfo <<= 8; if (n >= 7 && (xinfo & 0x100)) xinfo |= (*this)[9];
return xinfo;
}
Index: hylafax/faxd/Class20.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class20.c++,v
retrieving revision 1.2
diff -u -r1.2 Class20.c++
--- Class20.c++ 1999/06/13 07:41:01 1.2
+++ Class20.c++ 2000/06/05 10:10:23
@@ -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",
+ (const char*)s, "can not parse PPR");
+ return (false); // force termination
+ }
+ }
return (true);
case AT_EMPTYLINE:
case AT_TIMEOUT:
Index: hylafax/faxd/Class1Send.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class1Send.c++,v
retrieving revision 1.3
diff -u -r1.3 Class1Send.c++
--- Class1Send.c++ 2000/05/15 13:23:43 1.3
+++ Class1Send.c++ 2000/06/05 10:10:20
@@ -276,6 +274,7 @@
tracePPR("SEND recv", ppr);
switch (ppr) {
case FCF_RTP: // ack, continue after retraining
+ ignore:
params.br = (u_int) -1; // force retraining above
/* fall thru... */
case FCF_MCF: // ack confirmation
@@ -306,22 +305,29 @@
emsg = "Remote fax disconnected prematurely";
return (send_retry);
case FCF_RTN: // nak, retry after retraining
- if ((++ntrys % 2) == 0) {
- /*
- * Drop to a lower signalling rate and retry.
- */
- if (params.br == BR_2400) {
- emsg = "Unable to transmit page"
- " (NAK at all possible signalling rates)";
- return (send_retry);
- }
- --params.br;
- curcap = NULL; // force sendTraining to reselect
- }
- if (!sendTraining(params, 3, emsg))
- return (send_retry);
- morePages = true; // force continuation
- next = params; // avoid retraining above
+ switch( conf.rtnHandling ){
+ case RTN_IGNORE:
+ goto ignore; // ignore error and try to send next page
+ // after retraining
+ case RTN_GIVEUP:
+ emsg = "Unable to transmit page"
+ " (giving up after RTN)";
+ return (send_failed); // "over and out"
+ }
+ // case RTN_RETRANSMIT
+ if (++ntrys >= 3) {
+ emsg = "Unable to transmit page"
+ " (giving up after 3 attempts)";
+ return (send_retry);
+ }
+ if (params.br == BR_2400) {
+ emsg = "Unable to transmit page"
+ "(NAK at all possible signalling rates)";
+ return (send_retry);
+ }
+ next.br--;
+ curcap = NULL; // force sendTraining to reselect
+ morePages = true; // retransmit page
break;
case FCF_PIN: // nak, retry w/ operator intervention
emsg = "Unable to transmit page"
@@ -734,6 +749,12 @@
totdata = totdata+ts - (dp-data);
} else
dp = data;
+
+ /*
+ * correct broken Phase C (T.4) data if neccessary
+ */
+ correctPhaseCData(dp, &totdata, fillorder, params);
+
/*
* Send the page of data. This is slightly complicated
* by the fact that we may have to add zero-fill before the
Index: hylafax/faxd/Class20.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class20.c++,v
retrieving revision 1.2
diff -u -r1.2 Class20.c++
--- Class20.c++ 1999/06/13 07:41:01 1.2
+++ Class20.c++ 2000/06/05 10:10:23
@@ -131,7 +131,7 @@
bool rc = sendPageData(tif, pageChop);
if (!rc)
abortDataTransfer();
- else
+ else if( conf.class2SendRTC )
rc = sendRTC(params.is2D());
if (flowControl == FLOW_XONXOFF)
setXONXOFF(getInputFlow(), FLOW_XONXOFF, ACT_DRAIN);
Index: hylafax/faxd/Class2Recv.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class2Recv.c++,v
retrieving revision 1.2
diff -u -r1.2 Class2Recv.c++
--- Class2Recv.c++ 1999/06/13 07:41:01 1.2
+++ Class2Recv.c++ 2000/06/05 10:10:26
@@ -212,6 +212,12 @@
*/
if (hostDidCQ)
ppr = isQualityOK(params) ? PPR_MCF : PPR_RTN;
+#if 0
+ /*
+ * RTN debug code: always respond with RTN to sending facsimile
+ */
+ ppr = PPR_RTN;
+#endif
if (ppr & 1)
TIFFWriteDirectory(tif); // complete page write
else
Index: hylafax/faxd/Class2Send.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class2Send.c++,v
retrieving revision 1.4
diff -u -r1.4 Class2Send.c++
--- Class2Send.c++ 2000/05/15 13:23:43 1.4
+++ Class2Send.c++ 2000/06/05 10:10:28
@@ -250,6 +250,7 @@
case PPR_MCF: // page good
case PPR_PIP: // page good, interrupt requested
case PPR_RTP: // page good, retrain requested
+ ignore:
countPage(); // bump page count
notifyPageSent(tif);// update server
if (pph[2] == 'Z')
@@ -276,6 +277,15 @@
transferOK = true;
break;
case PPR_RTN: // page bad, retrain requested
+ switch( conf.rtnHandling ){
+ case RTN_IGNORE:
+ goto ignore; // ignore error and trying to send next page
+ case RTN_GIVEUP:
+ emsg = "Unable to transmit page"
+ " (giving up after RTN)";
+ goto failed; // "over and out"
+ }
+ // case RTN_RETRANSMIT
if (++ntrys >= 3) {
emsg = "Unable to transmit page"
" (giving up after 3 attempts)";
@@ -387,6 +397,12 @@
totdata = totdata+ts - (dp-data);
} else
dp = data;
+
+ /*
+ * correct broken Phase C (T.4) data if necessary
+ */
+ correctPhaseCData(dp, &totdata, fillorder, params);
+
beginTimedTransfer();
rc = putModemDLEData(dp, (u_int) totdata, bitrev, getDataTimeout());
endTimedTransfer();
Index: hylafax/faxd/FaxModem.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/FaxModem.c++,v
retrieving revision 1.3
diff -u -r1.3 FaxModem.c++
--- FaxModem.c++ 2000/05/15 13:23:44 1.3
+++ FaxModem.c++ 2000/06/05 10:10:39
@@ -634,4 +633,188 @@
{
if (curreq)
server.notifyPageSent(*curreq, TIFFFileName(tif));
+}
+
+/*
+ * Phase C data correction
+ */
+
+#include "G3Decoder.h"
+#include "G3Encoder.h"
+#include "StackBuffer.h"
+#include "Class2Params.h"
+
+class MemoryDecoder : public G3Decoder {
+private:
+ u_char* bp;
+ u_int width;
+ u_int byteWidth;
+ u_long cc;
+
+ u_int fillorder;
+ bool is2D;
+
+ u_char* endOfData; // used by cutExtraRTC
+
+ tiff_runlen_t*
+ runs;
+ u_char* rowBuf;
+
+ int decodeNextByte();
+public:
+ MemoryDecoder(u_char* data, u_int wid, u_long n,
+ u_int fillorder, bool twoDim);
+ ~MemoryDecoder();
+ u_char* current() { return bp; }
+ void fixFirstEOL();
+ u_char* cutExtraRTC();
+};
+
+MemoryDecoder::MemoryDecoder(u_char* data, u_int wid, u_long n,
+ u_int order, bool twoDim)
+{
+ bp = data;
+ width = wid;
+ byteWidth = howmany(width, 8);
+ cc = n;
+
+ fillorder = order;
+ is2D = twoDim;
+
+ runs = new tiff_runlen_t[2*width]; // run arrays for cur+ref rows
+ rowBuf = new u_char[byteWidth];
+ setupDecoder(fillorder, is2D);
+ setRuns(runs, runs+width, width);
+}
+MemoryDecoder::~MemoryDecoder()
+{
+ delete rowBuf;
+ delete runs;
+}
+
+int
+MemoryDecoder::decodeNextByte()
+{
+ if (cc == 0)
+ raiseRTC(); // XXX don't need to recognize EOF
+ cc--;
+ return (*bp++);
+}
+
+#ifdef roundup
+#undef roundup
+#endif
+#define roundup(a,b) ((((a)+((b)-1))/(b))*(b))
+
+/*
+ * TIFF Class F specs say:
+ *
+ * "As illustrated in FIGURE 1/T.4 in Recommendation T.4 (the Red
+ * Book, page 20), facsimile documents begin with an EOL (which in
+ * Class F is byte-aligned)..."
+ *
+ * This is wrong! "Byte-aligned" first EOL means extra zero bits
+ * which are not allowed by T.4. Reencode first row to fix this
+ * "byte-alignment".
+ */
+void MemoryDecoder::fixFirstEOL()
+{
+ fxStackBuffer result;
+ G3Encoder enc(result);
+ enc.setupEncoder(fillorder, is2D);
+
+ memset(rowBuf, 0, byteWidth*sizeof(u_char)); // clear row to white
+ if(!RTCraised()) {
+ u_char* start = current();
+ (void)decodeRow(rowBuf, width);
+ /*
+ * syncronize to the next EOL and calculate pointer to it
+ * (see detailed explanation of look_ahead in TagLine.c++)
+ */
+ (void)isNextRow1D();
+ u_int look_ahead = roundup(getPendingBits(),8) / 8;
+ u_int decoded = current() - look_ahead - start;
+
+ enc.encode(rowBuf, width, 1);
+ u_int encoded = result.getLength();
+
+ while( encoded < decoded ){
+ result.put((char) 0);
+ encoded++;
+ }
+ if( encoded == decoded ){
+ memcpy(start, (const char*)result, encoded);
+ }
+ }
+}
+
+
+/*
+ * TIFF Class F specs say:
+ *
+ * "Aside from EOL's, TIFF Class F files contain only image data. This
+ * means that the Return To Control sequence (RTC) is specifically
+ * prohibited..."
+ *
+ * Nethertheless Ghostscript and possibly other TIFF Class F writers
+ * append RTC or single EOL to the last encoded line. Remove them.
+ */
+u_char* MemoryDecoder::cutExtraRTC()
+{
+ u_char* start = current();
+
+ /*
+ * We expect RTC near the end of data and thus
+ * do not check all image to save processing time.
+ * It's safe because we will resync on the first
+ * encountered EOL.
+ *
+ * NB: We expect G3Decoder::data==0 and
+ * G3Decoder::bit==0 (no data in the accumulator).
+ * As we cannot explicitly clear the accumulator
+ * (bit and data are private), cutExtraRTC()
+ * should be called immediately after
+ * MemoryDecoder() constructing.
+ */
+ const u_long CheckArea = 20;
+ if( cc > CheckArea ){
+ bp += (cc-CheckArea);
+ cc = CheckArea;
+ }
+
+ endOfData = NULL;
+ if(!RTCraised()) {
+ /*
+ * syncronize to the next EOL and calculate pointer to it
+ * (see detailed explanation of look_ahead in TagLine.c++)
+ */
+ (void)isNextRow1D();
+ u_int look_ahead = roundup(getPendingBits(),8) / 8;
+ endOfData = current() - look_ahead;
+ for (;;) {
+ if( decodeRow(NULL, width) ){
+ /*
+ * endOfData is now after last good row. Thus we correctly handle
+ * RTC, single EOL in the end, or no RTC/EOL at all
+ */
+ endOfData = current();
+ }
+ }
+ }
+ return endOfData;
+}
+
+void
+FaxModem::correctPhaseCData(u_char* buf, u_long* pBufSize,
+ u_int fillorder, const Class2Params& params)
+{
+ MemoryDecoder dec1(buf, params.pageWidth(), *pBufSize, fillorder, params.is2D());
+ dec1.fixFirstEOL();
+ /*
+ * We have to construct new decoder. See comments to cutExtraRTC().
+ */
+ MemoryDecoder dec2(buf, params.pageWidth(), *pBufSize, fillorder, params.is2D());
+ u_char* endOfData = dec2.cutExtraRTC();
+ if( endOfData )
+ *pBufSize = endOfData - buf;
}
Index: hylafax/faxd/FaxModem.h
===================================================================
RCS file: /cvsroot/hylafax/faxd/FaxModem.h,v
retrieving revision 1.3
diff -u -r1.3 FaxModem.h
--- FaxModem.h 2000/05/15 13:23:44 1.3
+++ FaxModem.h 2000/06/05 10:10:42
@@ -40,6 +40,10 @@
class FaxFont;
class FaxServer;
+// NB: these would be enums in the FaxModem class
+// if there were a portable way to refer to them!
+typedef unsigned int RTNHandling; // RTN signal handling method
+
/*
* This is an abstract class that defines the interface to
* the set of modem drivers. Real drivers are derived from
@@ -133,7 +139,18 @@
bool setupTagLineSlop(const Class2Params&);
u_int getTagLineSlop() const;
u_char* imageTagLine(u_char* buf, u_int fillorder, const Class2Params&);
+/*
+ * Correct if neccessary Phase C (T.4) data (remove extra RTC etc.)
+ */
+ void correctPhaseCData(u_char* buf, u_long* pBufSize,
+ u_int fillorder, const Class2Params& params);
public:
+ enum {
+ RTN_RETRANSMIT = 0, // retransmit page after RTN until MCF/MPS
+ RTN_GIVEUP = 1, // immediately abort
+ RTN_IGNORE = 2, // ignore error and send next page
+ };
+
virtual ~FaxModem();
bool isFaxModem() const;
Index: hylafax/faxd/G3Encoder.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/G3Encoder.c++,v
retrieving revision 1.2
diff -u -r1.2 G3Encoder.c++
--- G3Encoder.c++ 1999/06/13 07:41:03 1.2
+++ G3Encoder.c++ 2000/06/05 10:10:44
@@ -71,10 +71,13 @@
G3Encoder::encode(const void* vp, u_int w, u_int h)
{
u_int rowbytes = howmany(w, 8);
+ bool firstEOL = true;
while (h-- > 0) {
- if (bit != 4) // byte-align EOL
- putBits(0, (bit < 4) ? bit+4 : bit-4);
+ if( firstEOL ) // according to T.4 first EOL
+ firstEOL = false; // should not be aligned
+ else if (bit != 4)
+ putBits(0, (bit < 4) ? bit+4 : bit-4); // byte-align other EOLs
if (is2D)
putBits((EOL<<1)|1, 12+1);
else
Index: hylafax/faxd/ModemConfig.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/ModemConfig.c++,v
retrieving revision 1.4
diff -u -r1.4 ModemConfig.c++
--- ModemConfig.c++ 2000/05/11 15:32:41 1.4
+++ ModemConfig.c++ 2000/06/05 10:10:48
@@ -213,6 +213,7 @@
class2SendRTC = false; // default per Class 2 spec
setVolumeCmds("ATM0 ATL0M1 ATL1M1 ATL2M1 ATL3M1");
recvDataFormat = DF_ALL; // default to no transcoding
+ rtnHandling = FaxModem::RTN_RETRANSMIT; // retransmit until MCF/MPS
}
void
@@ -462,6 +463,37 @@
return (df);
}
+bool
+ModemConfig::findRTNHandling(const char* cp, RTNHandling& rh)
+{
+ static const struct {
+ const char* name;
+ RTNHandling rh;
+ } rhnames[] = {
+ { "RETRANSMIT", FaxModem::RTN_RETRANSMIT },
+ { "GIVEUP", FaxModem::RTN_GIVEUP },
+ { "IGNORE", FaxModem::RTN_IGNORE },
+ { "H_POLLACK", FaxModem::RTN_IGNORE }, // inventor's name as an alias :-)
+ };
+ for (u_int i = 0; i < N(rhnames); i++)
+ if (valeq(cp, rhnames[i].name)) {
+ rh = rhnames[i].rh;
+ return (true);
+ }
+ return (false);
+}
+
+u_int
+ModemConfig::getRTNHandling(const char* cp)
+{
+ RTNHandling rh;
+ if (!findRTNHandling(cp, rh)) {
+ configError("Unknown RTN handling method \"%s\", using RETRANSMIT", cp);
+ rh = FaxModem::RTN_RETRANSMIT; // default
+ }
+ return (rh);
+}
+
void
ModemConfig::parseCID(const char* rbuf, CallerID& cid) const
{
@@ -500,6 +532,8 @@
minSpeed = getSpeed(value);
else if (streq(tag, "recvdataformat"))
recvDataFormat = getDataFormat(value);
+ else if (streq(tag, "rtnhandlingmethod"))
+ rtnHandling = getRTNHandling(value);
else
return (false);
return (true);
Index: hylafax/faxd/ModemConfig.h
===================================================================
RCS file: /cvsroot/hylafax/faxd/ModemConfig.h,v
retrieving revision 1.2
diff -u -r1.2 ModemConfig.h
--- ModemConfig.h 1999/06/13 07:41:04 1.2
+++ ModemConfig.h 2000/06/05 10:10:50
@@ -39,11 +39,13 @@
void setVolumeCmds(const fxStr& value);
u_int getSpeed(const char* value);
u_int getDataFormat(const char* value);
+ u_int getRTNHandling(const char* cp);
static bool findRate(const char*, BaudRate&);
static bool findATResponse(const char*, ATResponse&);
static bool findFlow(const char*, FlowControl&);
static bool findDataFormat(const char*, u_int&);
+ static bool findRTNHandling(const char*, RTNHandling&);
protected:
ModemConfig();
@@ -170,6 +172,8 @@
fxStr tagLineFontFile; // font file for imaging tag lines
u_int recvDataFormat; // received facsimile data format
+ RTNHandling rtnHandling; // RTN signal handling method
+
virtual ~ModemConfig();
void parseCID(const char*, CallerID&) const;
Index: hylafax/man/config.4f
===================================================================
RCS file: /cvsroot/hylafax/man/config.4f,v
retrieving revision 1.3
diff -u -r1.3 config.4f
--- config.4f 1999/08/18 09:35:11 1.3
+++ config.4f 2000/06/05 10:11:20
@@ -174,6 +174,7 @@
RingFax string \- distinctive ring fax call identifier
RingsBeforeAnswer integer \s-10\s+1 rings to wait before answering phone
RingVoice string \- distinctive ring voice call identifier
+RTNHandlingMethod string \s-1Retransmit\s+1 RTN signal handling method
SendFaxCmd\(dg string \s-1bin/faxsend\s+1 fax transmit command script
SendPageCmd\(dg string \s-1bin/pagesend\s+1 pager transmit command script
SendUUCPCmd\(dg string \s-1bin/uucpsend\s+1 \s-1UUCP\s+1 transmit command script
@@ -304,6 +305,7 @@
Class2PTSCmd string \s-1AT+FPS\s+1 Class 2.0: command to set received page status
Class2RecvDataTrigger string \s-1``\e22''\s+1 Class 2.0: character to send to trigger recv
Class2RELCmd string \- Class 2.0: command to enable byte-aligned \s-1EOL\s+1 codes
+Class2SendRTC boolean \s-1No\s+1 Class 2.0: append \s-1RTC\s+1 to page data on transmit
Class2SFLOCmd string \s-1AT+FLO=1\s+1 Class 2.0: command to set software flow control
Class2SPLCmd string \s-1AT+FSP\s+1 Class 2.0: command to set polling request
Class2TBCCmd string \s-1AT+FPP=0\s+1 Class 2.0: command to enable stream mode
@@ -975,6 +977,29 @@
and
.BR RingFax .
.TP
+.B RTNHandlingMethod
+Specifies how to react to RTN signal, received from the remote;
+one of ``\s-1Retransmit\s+1'', ``\s-1Giveup\s+1'' and
+``\s-1Ignore\s+1''. ``\s-1Retransmit\s+1'' assumes that the
+page is not sent succesfully if RTN signal has been received.
+Hylafax will made up to 2 additional attempts to send the page,
+decreasing signalling rate and retraining. If RTN is still there,
+it will place up to 2 additional calls. So if the remote always respond with
+RTN, the page will be send 9 times. Although this algorithm comply with
+T.30 specs and was originally implemented by Sam Leffler as the only
+possible choice, real fax machines behave completely different. There is a
+non-written rule among fax developers, that RTN means ``over and out'' -- hang
+up immediately and never try to send the same page to the same destination
+again. That is because RTN usually indicates problems with flow control,
+incorrectly encoded T.4 data, incompatibility between local and remote
+equipment etc., but very rarely is caused by the real noise on the line.
+This ``over and out'' behaviour can be activated by ``Giveup'' value.
+There is also third option, not so radical as ``Giveup''. Yes, we will never
+retransmit the page, but we can try to send the next page, and let the
+remote to decide what to do (accept our decision or hang up). Thus one page will
+(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 SendFaxCmd\(dg
The command to use to process outbound facsimile jobs; see
.IR faxsend (1M).
@@ -2091,7 +2121,8 @@
.B Class2SendRTC
Whether or not to append an explicit ``Return To Control'' (\s-1RTC\s+1)
signal to the page data when transmitting.
-The Class 2 spec (i.e. SP-2388-A) states the modem will append
+The Class 2 and Class 2.0 specs (i.e. SP-2388-A and TIA/EIA-592) state
+that the modem will append
.SM RTC
when it receives the post-page message command from the host; this
parameter is provided in case the modem does not correctly implement
Index: hylafax/faxd/Class0.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class0.c++,v
retrieving revision 1.2
diff -u -r1.2 Class0.c++
--- Class0.c++ 1999/06/13 07:40:59 1.2
+++ Class0.c++ 2000/06/05 10:09:55
@@ -34,6 +34,9 @@
Class0Modem::Class0Modem(ModemServer& s, const ModemConfig& c)
: ClassModem(s, c)
{
+ mfrQueryCmd = "ATI3";
+ modelQueryCmd = "ATI0";
+ revQueryCmd = ""; // I know no standard way - D.B.
}
Class0Modem::~Class0Modem()
Index: hylafax/faxd/Class1.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class1.c++,v
retrieving revision 1.3
diff -u -r1.3 Class1.c++
--- Class1.c++ 1999/08/23 11:19:31 1.3
+++ Class1.c++ 2000/06/05 10:09:59
@@ -177,6 +177,16 @@
break;
}
/*
+ * Class1 defaults for send & receive bit order
+ */
+ sendFillOrder = (conf.sendFillOrder != 0)?
+ conf.sendFillOrder :
+ FILLORDER_LSB2MSB;
+ recvFillOrder = (conf.recvFillOrder != 0)?
+ conf.recvFillOrder :
+ FILLORDER_LSB2MSB;
+
+ /*
* T.30 specifies that HDCL frame data are in MSB bit
* order except for CIG/TSI data which have LSB bit order.
* We compose and interpret frame data in MSB bit order
Index: hylafax/faxd/Class1Send.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class1Send.c++,v
retrieving revision 1.3
diff -u -r1.3 Class1Send.c++
--- Class1Send.c++ 2000/05/15 13:23:43 1.3
+++ Class1Send.c++ 2000/06/05 10:10:20
@@ -698,7 +713,7 @@
uint16 fillorder;
TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
const u_char* bitrev =
- TIFFGetBitRevTable(conf.sendFillOrder != FILLORDER_LSB2MSB);
+ TIFFGetBitRevTable(sendFillOrder != FILLORDER_LSB2MSB);
/*
* Setup tag line processing.
*/
Index: hylafax/faxd/Class2.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class2.c++,v
retrieving revision 1.2
diff -u -r1.2 Class2.c++
--- Class2.c++ 1999/06/13 07:41:01 1.2
+++ Class2.c++ 2000/06/05 10:10:21
@@ -32,7 +32,6 @@
{
hangupCode[0] = '\0';
serviceType = 0; // must be set in derived class
- rtcRev = TIFFGetBitRevTable(conf.sendFillOrder == FILLORDER_LSB2MSB);
}
Class2Modem::~Class2Modem()
@@ -183,6 +182,28 @@
xmitWaitForXON = false;
else
xmitWaitForXON = conf.class2XmitWaitForXON;
+
+ /*
+ * Class2/2.0 defaults for send & receive bit order
+ */
+ sendFillOrder = (conf.sendFillOrder != 0)?
+ conf.sendFillOrder :
+ FILLORDER_LSB2MSB;
+ recvFillOrder = (conf.recvFillOrder != 0)?
+ conf.recvFillOrder :
+ (serviceType == SERVICE_CLASS20 || modemMfr.find(0, "MULTI-TECH") == 0)?
+ /*
+ * Multitech report the manufacturer as
+ * "Multi-Tech Sys" or "Multi-Tech Systems"
+ *
+ * it seems to be the only Class2 modem which
+ * does not clone the infamous Rockwell bug
+ * (which has become "standard" now)
+ */
+ FILLORDER_LSB2MSB :
+ FILLORDER_MSB2LSB;
+
+ rtcRev = TIFFGetBitRevTable(sendFillOrder == FILLORDER_LSB2MSB);
setupClass2Parameters(); // send parameters to the modem
return (true);
Index: hylafax/faxd/Class2Send.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/Class2Send.c++,v
retrieving revision 1.4
diff -u -r1.4 Class2Send.c++
--- Class2Send.c++ 2000/05/15 13:23:43 1.4
+++ Class2Send.c++ 2000/06/05 10:10:28
@@ -349,7 +359,7 @@
uint16 fillorder;
TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
const u_char* bitrev =
- TIFFGetBitRevTable(fillorder != conf.sendFillOrder);
+ TIFFGetBitRevTable(fillorder != sendFillOrder);
/*
* Setup tag line processing.
*/
Index: hylafax/faxd/ClassModem.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/ClassModem.c++,v
retrieving revision 1.3
diff -u -r1.3 ClassModem.c++
--- ClassModem.c++ 2000/05/29 07:47:18 1.3
+++ ClassModem.c++ 2000/06/05 10:10:34
@@ -130,8 +130,6 @@
// XXX: workaround yet another GCC bug (sigh)
const fxStr& flow = conf.getFlowCmd(conf.flowControl);
resetCmds = "AT"
- | stripAT(conf.softResetCmd)
- | "\nAT"
| stripAT(conf.resetCmds) // prepend to insure our needs
| stripAT(conf.echoOffCmd)
| stripAT(conf.verboseResultsCmd)
@@ -652,6 +650,7 @@
if (!setBaudRate(rate, iFlow, oFlow))
return (false);
flushModemInput();
+ (void) atCmd(conf.softResetCmd, AT_OK, conf.resetDelay);
return atCmd(resetCmds, AT_OK, ms);
}
Index: hylafax/faxd/CopyQuality.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/CopyQuality.c++,v
retrieving revision 1.5
diff -u -r1.5 CopyQuality.c++
--- CopyQuality.c++ 2000/05/11 14:19:38 1.5
+++ CopyQuality.c++ 2000/06/05 10:10:36
@@ -47,7 +47,7 @@
FaxModem::recvPageDLEData(TIFF* tif, bool checkQuality,
const Class2Params& params, fxStr& emsg)
{
- setupDecoder(conf.recvFillOrder, params.is2D());
+ setupDecoder(recvFillOrder, params.is2D());
u_int rowpixels = params.pageWidth(); // NB: assume rowpixels <= 2432
tiff_runlen_t runs[2*2432]; // run arrays for cur+ref rows
Index: hylafax/faxd/FaxModem.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/FaxModem.c++,v
retrieving revision 1.3
diff -u -r1.3 FaxModem.c++
--- FaxModem.c++ 2000/05/15 13:23:44 1.3
+++ FaxModem.c++ 2000/06/05 10:10:39
@@ -37,6 +37,8 @@
: ClassModem(s,c)
, server(s)
{
+ recvFillOrder = 0; // set later in the inherited class
+ sendFillOrder = 0; // set later in the inherited class
tagLineFont = NULL;
minsp = BR_2400;
curreq = NULL;
Index: hylafax/faxd/FaxModem.h
===================================================================
RCS file: /cvsroot/hylafax/faxd/FaxModem.h,v
retrieving revision 1.3
diff -u -r1.3 FaxModem.h
--- FaxModem.h 2000/05/15 13:23:44 1.3
+++ FaxModem.h 2000/06/05 10:10:42
@@ -84,6 +88,8 @@
NSF nsf; // received nonstandard facilities
// NB: remaining session state is below (params) or maintained by subclass
protected:
+ u_int recvFillOrder; // bit order of recvd data (ModemConfig & autodetected)
+ u_int sendFillOrder; // bit order of sent data (ModemConfig & autodetected)
// NB: these are defined protected for convenience (XXX)
Class2Params modemParams; // NOTE: these are masks of Class 2 codes
u_int minsp; // minimum required signalling rate
Index: hylafax/faxd/FaxServer.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/FaxServer.c++,v
retrieving revision 1.3
diff -u -r1.3 FaxServer.c++
--- FaxServer.c++ 1999/08/23 11:19:32 1.3
+++ FaxServer.c++ 2000/06/05 10:10:43
@@ -28,6 +28,7 @@
#include "Sys.h"
#include "FaxServer.h"
+#include "Class0.h"
#include "Class1.h"
#include "Class2Ersatz.h"
#include "Class20.h"
@@ -116,16 +117,38 @@
{
fxStr h(type);
h.raisecase();
+ ClassModem* modem;
+ /*
+ * Don't use Class2.0 with USR modems if not explicitly
+ * specified in the config file (it doesn't work reliably) - D.B.
+ */
+ if( h == "UNKNOWN" ){
+ modem = new Class0Modem(*this, *this);
+ if( modem ){
+ bool buggyUSR = false;
+ if( modem->setupModem() ){
+ fxStr mnf = modem->getManufacturer();
+ mnf.raisecase();
+ u_int mnfLen = mnf.length();
+ if( mnf.find(0,"USROBOTICS") != mnfLen ){
+ modem->serverTrace("USR modem: disable Class 2.0 by default");
+ buggyUSR = true;
+ }
+ }
+ delete modem;
+ if( buggyUSR )
+ goto forceClass1;
+ }
+ }
/*
* Probe for modem using type, if specified; otherwise
* try Class 2.0, Class 2, Class 1, and then Class 0 types.
*/
- ClassModem* modem;
if (h == "CLASS2.0" || h == "UNKNOWN") {
modem = new Class20Modem(*this, *this);
if (modem) {
if (modem->setupModem())
- return modem;
+ return modem;
delete modem;
}
}
@@ -137,6 +160,7 @@
delete modem;
}
}
+ forceClass1:
if (h == "CLASS1" || h == "UNKNOWN") {
modem = new Class1Modem(*this, *this);
if (modem) {
Index: hylafax/faxd/ModemConfig.c++
===================================================================
RCS file: /cvsroot/hylafax/faxd/ModemConfig.c++,v
retrieving revision 1.4
diff -u -r1.4 ModemConfig.c++
--- ModemConfig.c++ 2000/05/11 15:32:41 1.4
+++ ModemConfig.c++ 2000/06/05 10:10:48
@@ -157,8 +157,8 @@
u_int ModemConfig::* p;
u_int def;
} fillorders[] = {
-{ "modemrecvfillorder", &ModemConfig::recvFillOrder, FILLORDER_LSB2MSB },
-{ "modemsendfillorder", &ModemConfig::sendFillOrder, FILLORDER_LSB2MSB },
+{ "modemrecvfillorder", &ModemConfig::recvFillOrder, 0 }, // undefined
+{ "modemsendfillorder", &ModemConfig::sendFillOrder, 0 }, // undefined
{ "modemframefillorder", &ModemConfig::frameFillOrder, FILLORDER_LSB2MSB },
};
static const struct {
@@ -205,7 +205,7 @@
for (i = N(numbers)-1; i >= 0; i--)
(*this).*numbers[i].p = numbers[i].def;
- flowControl = ClassModem::FLOW_NONE;// no flow control
+ flowControl = ClassModem::FLOW_XONXOFF;// software flow control
maxRate = ClassModem::BR19200; // reasonable for most modems
minSpeed = BR_2400; // minimum transmit speed
waitForConnect = false; // unique modem answer response
Index: hylafax/man/config.4f
===================================================================
RCS file: /cvsroot/hylafax/man/config.4f,v
retrieving revision 1.3
diff -u -r1.3 config.4f
--- config.4f 1999/08/18 09:35:11 1.3
+++ config.4f 2000/06/05 10:11:20
@@ -207,7 +208,7 @@
ModemDialCmd string \s-1ATDT%s\s+1 command for dialing (%s for number to dial)
ModemDialResponseTimeout integer \s-1180000\s+1 dialing command timeout (ms)
ModemEchoOffCmd string \s-1ATE0\s+1 command for disabling command echo
-ModemFlowControl string \s-1None\s+1 \s-1DTE-DCE\s+1 flow control scheme
+ModemFlowControl string \s-1XONXOFF\s+1 \s-1DTE-DCE\s+1 flow control scheme
ModemFrameFillOrder string \s-1LSB2MSB\s+1 bit order for \s-1HDLC\s+1 frames
ModemHardFlowCmd string \- command for setting hardware flow control between \s-1DTE\s+1 and \s-1DCE\s+1
ModemMinSpeed string \s-12400\s+1 minimum acceptable transmit speed
@@ -1511,6 +1536,11 @@
communication.
However, beware that many modems only support software
flow control when sending or receiving facsimile.
+.IP
+Note that modems usually support software flow control even
+if they have no explicit AT-command to activate it; in this case
+it is switched on when the modem enters fax mode, having
+AT+FCLASS=... from \s-1DTE\s+1.
.TP
.B ModemFrameFillOrder
The bit order to expect for received
Index: hylafax/config/usr-2.0
===================================================================
RCS file: /cvsroot/hylafax/config/usr-2.0,v
retrieving revision 1.2
diff -u -r1.2 usr-2.0
--- usr-2.0 1999/01/04 10:19:07 1.2
+++ usr-2.0 2000/06/04 07:37:30
@@ -78,3 +78,7 @@
# It is not necessary for the Courier modem.
#
Class2NRCmd: AT+FNR=1,1,1,0
+#
+# Modem violates the Class 2.0 specs and do not send RTC itself
+#
+Class2SendRTC: yes
Index: hylafax/config/zyxel-1496e
===================================================================
RCS file: /cvsroot/hylafax/config/zyxel-1496e,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 zyxel-1496e
--- zyxel-1496e 1998/10/12 20:47:48 1.1.1.1
+++ zyxel-1496e 2000/06/04 07:37:31
@@ -66,16 +66,9 @@
#
# Additional reset commands:
#
-# &B1 DTE-DCE rate is fixed at DTE setting
-# &N0 Auto-negotiate highest possible DCE-DCE link rate
-# &S0 DSR always on
-# *F0 Deny remote configuration
-# S18=2 Receive at 38400
-# S38.3=1 DCD on/off sequence follows UNIX standard; also
-# fix receiving baud rate at S18 value
-# S39=0 (avoid Class 2 compatibility hacks)
+# S38.3=1 DCD on/off sequence follows UNIX standard
#
-ModemResetCmds: AT&B1&N0&S0*F0S18=2S38.3=1S39=0
+ModemResetCmds: S38.3=1
#
# We normally append the "@" symbol to the dial string so that
# the modem will wait 5 seconds before attempting to connect
@@ -106,8 +99,17 @@
#
PagerSetupCmds: AT&K0&N15 # use V.22 at 1200 bps (PageNet)
#
-# Rev 6.1x firmware have a bug in the ECM support so
-# explicitly disable it's use. To re-enable its use just
-# comment out the following line.
+# ECM is not implemented in U1496 despite AT+FCC=? says
#
Class2DCCQueryCmd: "!(0,1),(0-5),(0-4),(0-2),(0,1),(0),(0),(0-7)"
+#
+# Quality Checking is not implemented in U1496 despite AT+FCQ=? says
+#
+Class2CQQueryCmd: "!(0),(0)"
+#
+# Disable unnecessary, not implemented and possibly dangerous commands
+#
+Class2BORCmd: "AT"
+Class2PIECmd: "AT"
+Class2PHCTOCmd: "AT"
+Class2TBCCmd: "AT"
Index: hylafax/config/zyxel-1496e-1
===================================================================
RCS file: /cvsroot/hylafax/config/zyxel-1496e-1,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 zyxel-1496e-1
--- zyxel-1496e-1 1998/10/12 20:47:48 1.1.1.1
+++ zyxel-1496e-1 2000/06/04 07:37:31
@@ -55,13 +55,9 @@
#
# Additional reset commands:
#
-# &B1 DTE-DCE rate is fixed at DTE setting
-# &N0 Auto-negotiate highest possible DCE-DCE link rate
-# &S0 DSR always on
-# *F0 Deny remote configuration
# S38.3=1 DCD on/off sequence follows UNIX standard
#
-ModemResetCmds: AT&B1&N0&S0*F0S38.3=1
+ModemResetCmds: S38.3=1
#
# We normally append the "@" symbol to the dial string so that
# the modem will wait 5 seconds before attempting to connect
Index: hylafax/config/zyxel-1496e-2.0
===================================================================
RCS file: /cvsroot/hylafax/config/zyxel-1496e-2.0,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 zyxel-1496e-2.0
--- zyxel-1496e-2.0 1998/10/12 20:47:48 1.1.1.1
+++ zyxel-1496e-2.0 2000/06/04 07:37:32
@@ -61,16 +61,9 @@
#
# Additional reset commands:
#
-# &B1 DTE-DCE rate is fixed at DTE setting
-# &N0 Auto-negotiate highest possible DCE-DCE link rate
-# &S0 DSR always on
-# *F0 Deny remote configuration
-# S18=2 Receive at 38400
-# S38.3=1 DCD on/off sequence follows UNIX standard; also
-# fix receiving baud rate at S18 value
-# S39=0 (avoid Class 2 compatibility hacks)
+# S38.3=1 DCD on/off sequence follows UNIX standard
#
-ModemResetCmds: AT&B1&N0&S0*F0S18=2S38.3=1S39=0
+ModemResetCmds: S38.3=1
#
ModemDialCmd: ATDT%s # no '@' 'cuz then busy not recognized
NoCarrierRetrys: 3 # retry 3 times on no carrier
@@ -85,8 +78,17 @@
#
PagerSetupCmds: AT&K0&N15 # use V.22 at 1200 bps (PageNet)
#
-# Rev 6.1x firmware have a bug in the ECM support so
-# explicitly disable it's use. To re-enable its use just
-# comment out the following line.
+# ECM is not implemented in U1496 despite AT+FCC=? says
#
Class2DCCQueryCmd: "!(0,1),(0-5),(0-4),(0-2),(0,1),(0),(0),(0-7)"
+#
+# Quality Checking is not implemented in U1496 despite AT+FCQ=? says
+#
+Class2CQQueryCmd: "!(0),(0)"
+#
+# Disable unnecessary, not implemented and possibly dangerous commands
+#
+Class2BORCmd: "AT"
+Class2PIECmd: "AT"
+Class2PHCTOCmd: "AT"
+Class2TBCCmd: "AT"