--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fax/faxclientandserver/FAXSVR/CFAXMDRV.CPP Wed Sep 01 12:40:21 2010 +0100
@@ -0,0 +1,701 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "FAXSERV.H"
+#include "fax_reversebytes.h"
+#include "FONT8X16.DAT"
+#include "ZEROS.DAT"
+#include "FAXMDRV.H"
+#include "FAXMODEM.H"
+
+#include "FAXLOG.H"
+#include <et_phone.h>
+
+const TInt KLineReadTimeout=6; // < The time-out (in secs) for a line read
+const TInt KECMLineReadTimeout=132; // < The time-out (in secs) for a line read when using Error Correction Mode
+const TInt KSubsequentLineReadTimeout=10; // < The time-out (in secs) for a subsequent line read
+const TInt KSubsequentECMLineReadTimeout=140; // < The time-out (in secs) for a subsequent line read when using Error Correction Mode
+
+/********************************************************************/
+
+// we need to keep a local pointer to the current TDialstorModemPreferences in order to
+ // do whatever is required
+
+void CFaxModemDriver::ConstructL (TFaxServerSessionSettings * iFaxServerSessionSettings, RFax::TProgress & aProgress)
+{
+ iModem = CFaxModem::NewL (iFaxServerSessionSettings, aProgress);
+}
+/********************************************************************/
+
+
+CFaxModemDriver::CFaxModemDriver()
+ :CBase(), iSharedHandles(NULL)
+{
+}
+
+CFaxModemDriver::~CFaxModemDriver ()
+{
+ delete iModem;
+}
+/********************************************************************/
+
+// function to check that we don't send commands out when there's less than half a second
+// before the next RING comes in
+
+
+/**
+* function to check that we don't send commands out when there's less than half a second
+* before the next RING comes in.
+* This function has been modified by Dmitry Lyokhin for the sake of PIA-586KGE defect fix
+*
+* @param aCommand - contains the command to be sent to the modem.
+*
+* @see ExportL function
+*
+* @return number of symbols sent to the modem.
+*
+*
+*/
+TInt CFaxModemDriver::CheckCadenceExportL(const TDesC8 & aCommand)
+{
+
+
+ const TInt RingTimeout_Sec = 5; //-- 5 sec. waiting for 'RING' timeout
+ const TInt RingCadence_uSec = 3000000; //-- 3 sec. time span after 'RING' receiving during that commands
+ //-- can be sent to the modem
+
+ const TInt CmdSendDelay_uSec= 100000; //-- 100 ms delay between adjacent commands to the modem
+
+ TTime CurrentTime;
+
+ __FLOG_FAXSRV( _L8("-CFaxModemDriver::CheckCadenceExportL entering"));
+
+
+ //-- @note iCadence now is used like a flag. If its value is 0 (thai is set initially) we will
+ //-- try to wait for 'RING' indication i.e synchronize with incoming rings. Otherwise - no.
+ while( iCadence.Int64() == 0 )
+ {
+ if(iTimeOfLastRing.Int64() == 0)
+ {//-- we need to wait for 'RING' from the modem
+
+ __FLOG_FAXSRV( _L8("-CFaxModemDriver::CheckCadenceExportL waiting for RING"));
+
+ //-- wait for 'RING' from modem
+ if( iModem->GetMatchL (_L8 ("RING"), RingTimeout_Sec) == 0)
+ { //User::Leave(KFaxErrReceiveTimeout); //-- 'RING' waiting timeout, leaving
+
+ //-- There is no 'RING'indication, no we will not leave, instead of that
+ //-- disable sync. with incoming rings and pass on to sending commands to the modem straightforward.
+ iCadence = 1;
+ break;
+ }
+
+ iTimeOfLastRing.UniversalTime(); //-- note the time
+ }
+
+ //-- get current time and check if we are in time to send a command to the modem
+ CurrentTime.UniversalTime ();
+
+ if( CurrentTime < iTimeOfLastRing + TTimeIntervalMicroSeconds32(RingCadence_uSec) )
+ break; //-- send the command
+ else
+ { //-- wait for the next 'RING'
+ __FLOG_FAXSRV( _L8("-CFaxModemDriver::CheckCadenceExportL Resetting"));
+ iTimeOfLastRing = 0;
+ }
+ }
+
+ //-- I had to introduce this delay between sending adjacent commands to the modem because
+ //-- some modems (e.g. Nokia9210) lose data.
+ iModem->Silence(CmdSendDelay_uSec);
+
+ //-- send the command
+ return iModem->ExportL (aCommand);
+}
+
+/********************************************************************/
+
+// if we have called FaxInL with a dial request, it calls this routine
+ // to dial up a fax on demand service
+ //
+ // if not polling, we end with a colon to return to command mode and then
+ // we delay for whatever time has been requested by the user
+ // before returning, at which point FaxInL continues with ATA
+
+void CFaxModemDriver::DialFaxOnDemandL ()
+{
+ iModem->ExportL (_L8 ("ATD"));
+ iModem->ExportL (iFaxServerSessionSettings->iPhoneNumber);
+
+ if (iFaxServerSessionSettings->iMode & KFaxPoll)
+ iModem->TxcharL (Kreturn);
+ else
+ {
+ iModem->ExportL (_L8 (";"));
+ iModem->TxcharL (Kreturn);
+ if ((iModem->GetMatchL (_L8 ("OK"), KDialTimeout)) == 0)
+ User::Leave (KFaxErrNoDial);
+ iModem->Silence (CLK_TCK * iFaxServerSessionSettings->iFaxOnDemandDelay);
+ }
+}
+/********************************************************************/
+
+// now the routines to add a header line to the top of each fax page
+
+/********************************************************************/
+
+// we send four blank scan lines
+ // we create a line of text containing time and date,
+ // the Fax ID and Username,
+ // the page number and total number of pages,
+ // we digitize that, and send it out
+ // our font height is 16 so that means 20 scan lines
+ // are added to the top of each sent fax
+
+void CFaxModemDriver::SendFaxHeaderL ()
+{
+ TFaxHeaderInfo faxHeader;
+ TRawScanLine headline;
+ TRawScanLine fontline;
+ TBuf8 < KFaxT4MaxDesLength > encodedHeadLine;
+ TTime timeOfTransmission;
+ TBuf < 12 > timeText;
+
+ timeOfTransmission.HomeTime();
+ timeOfTransmission.FormatL (timeText, (_L ("%F%D%M%Y%H%T")));
+
+ iModem->iOurMessage.Format (_L8 ("Sending page header"));
+ iModem->ProgressUpdateL ();
+
+ for (TInt r = iModem->iProgress.iResolution ; r >= 0; r--)
+ {
+ for (TInt x = 0, y = 4 ; x < 4; x++)
+ {
+ iModem->iTransmitBuffer.Append (0x00);
+ if (iModem->iProgress.iCompression)
+ {
+ iModem->iTransmitBuffer.Append (Invert (0x00));
+ iModem->iTransmitBuffer.Append (Invert (0x34));
+ y = 5;
+ }
+ else
+ iModem->iTransmitBuffer.Append (Invert (0x14));
+ iModem->iTransmitBuffer.Append (Invert (0xD9));
+ iModem->iTransmitBuffer.Append (Invert (0xA8));
+ padLineL (y);
+ }
+ }
+
+ CFaxT4 * faxT4 =CFaxT4::NewLC();
+ faxT4->PageInitialize (iModem->iProgress.iResolution, iModem->iProgress.iCompression);
+ if(!iSharedHandles)
+ {
+ User::Leave(KErrBadHandle);
+ }
+ CFaxHeaderLines * faxheader = CFaxHeaderLines::NewLC (&iSharedHandles->File());
+
+ faxheader->ReadFaxHeaderInfoL (faxHeader);
+ for (TInt n = 0; n < 12; n++)
+ timeText[n] -= '0';
+
+ // Forces 2 digit day - 2 digit month - 4 digit year - 2 digit hour - 2 digit minute
+
+ for (TInt scanline = 0; scanline < faxHeader.iHeaderFontHeightInLines; scanline++)
+ {
+ faxheader->ReadRawHeaderLineL (scanline, headline);
+ faxheader->ReadRawFontLineL (scanline, fontline);
+ for (TInt fontByte = 0; fontByte < faxHeader.iHeaderFontWidthInBytes; fontByte++)
+ {
+ headline[((faxHeader.iOffsetToDay) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[0] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToDay + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[1] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToMonth) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[2] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToMonth + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[3] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToYear) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[4] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToYear + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[5] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToYear + 2) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[6] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToYear + 3) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[7] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToHour) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[8] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToHour + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[9] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToMinute) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[10] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToMinute + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[(timeText[11] * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+
+ // put the page info in
+
+
+ if (iModem->iProgress.iPage > 9)
+ headline[((faxHeader.iOffsetToCurrentPage) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[((iModem->iProgress.iPage / 10) * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToCurrentPage + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[((iModem->iProgress.iPage % 10) * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ if (iFaxServerSessionSettings->iTxPages > 9)
+ headline[((faxHeader.iOffsetToTotalPages) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[((iFaxServerSessionSettings->iTxPages / 10) * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ headline[((faxHeader.iOffsetToTotalPages + 1) * faxHeader.iHeaderFontWidthInBytes) + fontByte] = fontline[((iFaxServerSessionSettings->iTxPages % 10) * faxHeader.iHeaderFontWidthInBytes) + fontByte];
+ }
+
+ // we send the line once in normal resolution but twice in fine resolution
+
+ for (TInt r = iModem->iProgress.iResolution ; r >= 0; r--)
+ {
+ faxT4->EncodeScanLine (headline, encodedHeadLine);
+
+ // always add the extra null at the start for the initial eol
+
+ iModem->iTransmitBuffer.Append (Knul);
+
+ // and then invert and finally send the encoded line
+
+ const TUint8 *px = CONST_CAST (TUint8 *, encodedHeadLine.Ptr ());
+ const TUint8 *ex = px + encodedHeadLine.Length ();;
+ TUint8 thisChar;
+ TInt bytesSent = 0;
+ while (px < ex)
+ {
+ thisChar = Invert (*px++);
+ iModem->iTransmitBuffer.Append (thisChar);
+ if (thisChar == Kdle)
+ iModem->iTransmitBuffer.Append (Kdle);
+ iModem->SendTransmitBufferL ();
+ bytesSent++;
+ }
+ padLineL (bytesSent);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(faxheader);
+ CleanupStack::PopAndDestroy(faxT4);
+}
+
+/********************************************************************/
+
+// this function handles line padding out for minimum scan line times
+ // this feature should really only be needed on class 1 modems ...
+ // it takes a single integer parameter, which is the number of bytes sent
+
+void CFaxModemDriver::padLineL (TInt aByteCount)
+{
+ if (iFaxServerSessionSettings->iFaxClass == EClass1)
+ {
+ while (iMinlinelength > aByteCount)
+ {
+ aByteCount++;
+ iModem->iTransmitBuffer.Append (Knul);
+ iModem->SendTransmitBufferL ();
+ }
+ }
+}
+/********************************************************************/
+
+// rewritten to avoid using any AT commands August 1997 Andrew Margolis
+ // pointer arithmetic courtesy of Andrew Thoelke
+ // Though this doesn't use any AT command but it does need to know
+ // about the various modem classes ... GetFaxDataL is in the same boat
+
+// the client has buffered up lines to minimize interaction
+ // aData starts with a TInt containing the number of lines
+ // Each line follows, preceded with a TInt containing its length
+ // which must be copied as it might not be aligned on a 4-byte
+ // boundary
+
+TInt CFaxModemDriver::SendFaxDataL (const TDesC8 * aData)
+{
+ TUint8 thisChar;
+ TInt ticks;
+ TInt numberOfLines;
+ TInt lengthOfLine;
+
+ TUint8 *thisLine = CONST_CAST (TUint8 *, (*aData).Ptr ());
+ Mem::Copy (&numberOfLines, thisLine, sizeof (TInt));
+ thisLine += sizeof (TInt);
+
+ // buffering debug message
+
+ iModem->iOurMessage.Format (_L8 ("%u lines in buffer taking up %u bytes"), numberOfLines, (*aData).Length ());
+ iModem->ProgressUpdateL ();
+
+ while (numberOfLines--)
+ {
+ Mem::Copy (&lengthOfLine, thisLine, sizeof (TInt));
+ thisLine += sizeof (TInt);
+ iModem->iProgress.iLines++;
+
+ TInt bytesSent = 0;
+ const TUint8 *px = thisLine;
+ const TUint8 *ex = px + lengthOfLine;
+ while (px < ex)
+ {
+ thisChar = Invert (*px++);
+ iModem->iTransmitBuffer.Append (thisChar);
+ if (thisChar == Kdle)
+ iModem->iTransmitBuffer.Append (Kdle);
+ iModem->SendTransmitBufferL ();
+ bytesSent++;
+ }
+ padLineL (bytesSent);
+
+ // we must check for cancel commands from the modem in class 2.0 transmission
+
+ if (iFaxServerSessionSettings->iFaxClass == EClass2point0)
+ {
+ while (iModem->Rxstat () != 0)
+ {
+ ticks = CLK_TCK;
+ iModem->RxcharWaitL (ticks);
+ if (iModem->iReadone[0] == Kcan)
+ {
+ iModem->TxcharL (Kdle);
+ iModem->TxcharL (Ketx);
+ iModem->CommitTransmitBufferL ();
+ iModem->Xonoff ();
+ iModem->GetMatchL (_L8 ("OK"), 5);
+ return (KFaxErrModemDisconnect);
+ }
+ }
+ }
+ thisLine += lengthOfLine;
+ }
+ return (KErrNone);
+}
+/********************************************************************/
+ // This function takes a pointer to a binary data buffer.
+ // We are guaranteed that the buffer is big enough to take
+ // two entire scan lines up to KMaxT4Des in size.
+
+ // We call GetLineL to fill the buffer up with scan lines, and
+ // we keep a count of the number of lines received as an integer
+ // at the start of the buffer. We return when either we haven't
+ // enough room to guarantee another line, or when we have received
+ // a line of zero length, which means an end of page. The descriptor
+ // is set to the correct length on return
+
+ // So on return, aData starts with a TInt containing the number of lines
+ // Each line follows, preceded with a TInt containing its length
+ // which must be copied as it might not be aligned on a 4-byte
+ // boundary - a line of zero length indicates we have reached
+ // the end of the page
+
+void CFaxModemDriver::GetFaxDataL (TDes8 * aData)
+{
+ TUint8 *startData;
+ TUint8 *lineData;
+ const TUint8 *maxData;
+ TInt lineLength;
+ TInt numberOfLines = 0;
+
+ lineData = startData = CONST_CAST (TUint8 *, (*aData).Ptr ());
+ maxData = startData + (*aData).MaxLength () - KMaxT4Des - sizeof (TInt);
+
+ (*aData).SetMax ();
+ lineData += sizeof (TInt);
+
+ for (;;)
+ {
+ numberOfLines++;
+ lineLength = GetLineL (lineData);
+ Mem::Copy (lineData, &lineLength, sizeof (TInt));
+ lineData += sizeof (TInt);
+ lineData += lineLength;
+ if (lineData > maxData)
+ break;
+ if (lineLength == 0)
+ break;
+ }
+ Mem::Copy (startData, &numberOfLines, sizeof (TInt));
+ (*aData).SetLength (lineData - startData);
+
+ // buffering debug message
+
+ iModem->iOurMessage.Format (_L8 ("%u lines in buffer taking up %u bytes"), numberOfLines, (*aData).Length ());
+ iModem->ProgressUpdateL ();
+}
+/********************************************************************/
+// This function takes a pointer to a binary data buffer.
+ // We are guaranteed that the buffer is big enough to take
+ // an entire scan line up to KMaxT4Des in size.
+ // We receive the scan line, with a leave if we timeout.
+ // We return with the length of the scan line and the buffer has
+ // a space for this to be placed as an integer by the caller,
+ // followed by the scan line data. If the length of the scan line
+ // is zero, we have reached the end of the page
+
+TInt CFaxModemDriver::GetLineL (TUint8 * aFaxData)
+{
+ TUint8 *lineStart;
+ TUint8 *lineEnd;
+ TUint8 *currentByte;
+
+ lineStart = currentByte = (aFaxData + sizeof (TInt));
+ lineEnd = lineStart + KMaxT4Des;
+
+ TUint8 thisChar = 0;
+ TUint8 leading0s = 0;
+ TUint8 trailing0s = 0;
+ TInt nullcount = 0;
+
+ TInt ticks = CLK_TCK * KLineReadTimeout;
+ if (iModem->iProgress.iECM != 0)
+ ticks = CLK_TCK * KECMLineReadTimeout;
+
+ iModem->iProgress.iLines++;
+
+ TInt bol = 1;
+ TUint8 lastChar = 0xff;
+
+ // lastChar set to 0xff flags the entry to the function
+ // during iterations lastChar must be either 0 or 1
+ // we always come here just after detecting an EOL, and the character
+ // which contains the EOL bit is guaranteed to be re-readable
+ // lastChar set to 0xff indicates that's is not been read,
+ // so we re-read it, set its trailing0s, and put it in the buffer
+ // without bothering to do any dle checking (we already know it's ok)
+
+ for (;;)
+ {
+ if (lastChar == 0xff)
+ {
+ lastChar = 0;
+ thisChar = iModem->iReadone[0];
+ }
+ else
+ {
+ if ((iModem->RxcharWaitL (ticks)) == 0)
+ User::Leave (KFaxErrReceiveTimeout);
+ thisChar = iModem->iReadone[0];
+
+ // check if we have the character after a leading dle
+ // if we have unmark the last character as being a dle -
+ // dle etx is end of data
+ // dle dle is a shielded dle
+ // dle sub is two times dle for class 2.0 only
+ // dle and anything else we ignore
+
+ if (lastChar == Kdle)
+ {
+ lastChar = 0;
+
+ if (thisChar == Ketx)
+ {
+ iModem->iOurMessage.Format (_L8 ("<dle><etx> detected after %u lines"), iModem->iProgress.iLines);
+ iModem->ProgressUpdateL ();
+ return (0);
+ }
+
+ if (iFaxServerSessionSettings->iFaxClass == EClass2point0)
+ {
+ if (thisChar == 0x1a)
+ {
+ thisChar = Kdle;
+ *currentByte++ = Invert (thisChar); // invert class 2.0
+ if (currentByte == lineEnd)
+ {
+ return (KMaxT4Des);
+ }
+ trailing0s = 4;
+ }
+ }
+
+ if (thisChar != Kdle)
+ continue;
+ } // drop through only with a data dle
+
+ // if not a trailing dle
+ // check if this character is itself a leading dle
+ // drop through only if it isn't
+
+ else if (thisChar == Kdle)
+ {
+ lastChar = Kdle;
+ continue;
+ }
+ }
+
+ // if we've received six EOL codes already, ignore everything
+ // till dle etx arrives
+
+ if (bol == 6)
+ continue;
+
+ // have we a null ? if yes we ignore nulls if they come in
+ // anything more than pairs - if no, we zero nullcount and
+ // invert the byte back the right way for non-class 2 modems
+ // THIS LAST IS IMPORTANT
+
+ if (thisChar == Knul)
+ {
+ if (nullcount == 2)
+ continue;
+ else
+ nullcount++;
+ }
+ else
+ {
+ nullcount = 0;
+ if (iFaxServerSessionSettings->iFaxClass != EClass2)
+ thisChar = Invert (thisChar);
+ }
+
+ // count the leading zeros in this byte
+
+ leading0s = zerotable[thisChar][0];
+
+ // if the leading zeros in this byte and the trailing zeros in the
+ // previous byte total 11 or more we have ourselves an EOL
+ // so we write the data we have so far as an entire line
+ // we are guaranteed than an eol will span at least two bytes
+ // so the data we have must include the end of the last line
+ // if this is a nul we don't write anything yet as we haven't
+ // detected a proper eol code
+ // we don't write anything for consecutibe eols
+
+ if (((trailing0s + leading0s) > 10) && (thisChar != Knul))
+ {
+ bol++;
+ if ((bol == 1) && (currentByte != lineStart))
+ {
+ return (currentByte - lineStart);
+ }
+ if (iModem->iProgress.iECM == 0)
+ ticks = CLK_TCK * KSubsequentLineReadTimeout;
+ else
+ ticks = CLK_TCK * KSubsequentECMLineReadTimeout; // 11/1/01 AMC: ECM requires longer time-outs due to retries
+ }
+
+ // else if we had received an eol and this character is not nul
+ // we have ourselves a new line start
+
+ else
+ {
+ if (bol)
+ if (thisChar != Knul)
+ bol = 0;
+ }
+
+ // if we have a nul, add 8 to our trailing zero bits
+ // else count them by hand
+
+ if (thisChar == Knul)
+ trailing0s += 8;
+ else
+ trailing0s = zerotable[thisChar][1];
+
+ // ignore multiple eols
+
+ if (bol > 1)
+ continue;
+
+ // save everything else - we've already inverted the data if needed
+
+ *currentByte++ = thisChar;
+ if (currentByte == lineEnd)
+ {
+ return (KMaxT4Des);
+ }
+ }
+}
+/********************************************************************/
+
+TInt CFaxModemDriver::TxStartPageL ()
+{
+ iModem->iProgress.iPhase = EDataTransfer;
+ iModem->iProgress.iLines = 0;
+ iModem->iOurMessage.Format (_L8 ("About to send page %u"), ++iModem->iProgress.iPage);
+ iModem->ProgressUpdateL ();
+ iModem->Xonon ();
+
+ // for class 1 modems we start each page with a short burst of binary 1s
+
+ if (iFaxServerSessionSettings->iFaxClass == EClass1)
+ {
+ for (TInt x = (iActualFaxSpeed * 20 / 8); x; x--)
+ {
+ iModem->iTransmitBuffer.Append (0xff);
+ iModem->SendTransmitBufferL ();
+ }
+ iModem->CommitTransmitBufferL ();
+ }
+
+ // we're now in phase C so we start the page by sending the fax header
+
+ SendFaxHeaderL ();
+ return (KErrNone);
+}
+/********************************************************************/
+
+TInt CFaxModemDriver::RxStartPageL ()
+{
+ TUint8 thisChar, leading0s, trailing0s = 0;
+ TInt ticks = CLK_TCK * KLineReadTimeout;
+ if (iModem->iProgress.iECM != 0)
+ ticks = CLK_TCK * KECMLineReadTimeout; // ECM mode requires longer time-outs due to retries
+
+ iModem->iProgress.iPhase = EDataTransfer;
+ iModem->iProgress.iLines = 0;
+ iModem->iOurMessage.Format (_L8 ("Awaiting page %u"), ++iModem->iProgress.iPage);
+ iModem->ProgressUpdateL ();
+ trailing0s = 0;
+
+ // this function looks for the start of the received fax
+ // this is the first EOL code - we invert bytes for non-class 2 modems
+
+ for (;;)
+ {
+ if ((iModem->RxcharWaitL (ticks)) == 0)
+ return (KFaxErrReceiveTimeout);
+ thisChar = iModem->iReadone[0];
+ if (iFaxServerSessionSettings->iFaxClass != EClass2)
+ thisChar = Invert (thisChar);
+ leading0s = zerotable[thisChar][0];
+ if (((trailing0s + leading0s) > 10) && (thisChar != 0))
+ break;
+ if (thisChar == Knul)
+ trailing0s += 8;
+ else
+ trailing0s = zerotable[thisChar][1];
+ }
+
+ // we've found the first EOL - it's left in iModem->iReadone[0]
+
+ iModem->iOurMessage.Format (_L8 ("Receiving data .... "));
+ iModem->ProgressUpdateL ();
+ return (KErrNone);
+}
+/********************************************************************/
+
+TInt CFaxModemDriver::RxConnectL ()
+{
+ return (KFaxErrWrongModemType);
+}
+TInt CFaxModemDriver::RxPrePageL ()
+{
+ return (KFaxErrWrongModemType);
+}
+TInt CFaxModemDriver::RxPostPageL ()
+{
+ return (KFaxErrWrongModemType);
+}
+TInt CFaxModemDriver::TxConnectL ()
+{
+ return (KFaxErrWrongModemType);
+}
+TInt CFaxModemDriver::TxPrePageL ()
+{
+ return (KFaxErrWrongModemType);
+}
+TInt CFaxModemDriver::TxPostPageL ()
+{
+ return (KFaxErrWrongModemType);
+}
+/********************************************************************/
+
+
+
+