diff -r 17af172ffa5f -r 630d2f34d719 fax/faxclientandserver/FAXSVR/CFAXMODM.CPP --- a/fax/faxclientandserver/FAXSVR/CFAXMODM.CPP Thu Aug 19 11:03:36 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,985 +0,0 @@ -// 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: -// CFaxModem class implementation -// -// - -/** - @file -*/ - - -#include "FAXSERV.H" -#include -#include "FAXMODEM.H" - -#include "FAXLOG.H" - -// we embed this so that the session log tells us the version used - -#define FaxTransVersionString "FAX SERVER SESSION LOG (Release 033)" - -/********************************************************************/ - -CFaxModem::CFaxModem (RFax::TProgress & aProgress) -:iProgress (aProgress) - { - } -/********************************************************************/ - -CFaxModem *CFaxModem::NewLC (TFaxServerSessionSettings * aFaxServerSessionSettings, RFax::TProgress & aProgress) - { - CFaxModem *self = new (ELeave) CFaxModem (aProgress); - CleanupStack::PushL (self); - self->ConstructL (aFaxServerSessionSettings); - return self; - } -/********************************************************************/ - -CFaxModem *CFaxModem::NewL (TFaxServerSessionSettings * aFaxServerSessionSettings, RFax::TProgress & aProgress) - { - CFaxModem *self = NewLC (aFaxServerSessionSettings, aProgress); - CleanupStack::Pop (); - return self; - } -/********************************************************************/ - -void CFaxModem::ConstructL (TFaxServerSessionSettings * aFaxServerSessionSettings) - { - TInt r; -// TBufC < 24 > logname (_L ("C:\\SYSTEM\\FAXLOG.TXT")); -// RFsBase closefile; - - __FLOG_FAXSRV( _L8("CFaxModem::ConstructL entering")); - - iVerbose = 1; - -// we start off with our timer functions - - iStartTime.UniversalTime(); - -// work out the granularity of the clock - - TTimeIntervalMicroSeconds32 ourGranularity; - if (UserHal::TickPeriod (ourGranularity) == KErrNotSupported) - User::Leave (KErrNotSupported); - iGranularity = ourGranularity.Int (); - -// calibrate a 2 ms timing loop - see notes at start of cfaxTransfer::ExportL -// this is only used for class 1 when iTimingLoopDelay is true - - iCalls = 0; - TInt t; - t = clock () + iGranularity; - while (t > clock ()) - ; // wait for the clock to tick once - t = clock () + iGranularity; // reset target - while (t > clock ()) // wait for it to tick again - iCalls++; // this time counting calls to clock - iCalls *= (CLK_TCK / iGranularity); // work out calls per second - iCalls /= 500; // and work out calls per 2 ms - if (iCalls == 0) - iCalls++; - -#if defined (__WINS__) -#define PDD_NAME _L("ECDRV") -#define LDD_NAME _L("ECOMM") -#else -#define PDD_NAME _L("EUART1") -#define LDD_NAME _L("ECOMM") -#endif - - r = iFileSession.Connect (); // we may need the RFs link for PDD/LDD loading as well as the log - if (r) - User::Leave (KFaxFileSessionError); - iFileSessionOpen = ETrue; - - if (iVerbose) - { - - -//This is a log file that would normally only be created in debug builds, however due to the time critical nature of fax it is always generated -//to avoid timing differences between debug and release builds. -//With the introduction of platform security it not advisable to have a log file in a public directory so will now be created in the private dir -//of the fax server. - - //create log in private path of server - TFileName logfile; - TDriveUnit driveUnit(EDriveC); - TDriveName drive=driveUnit.Name(); - logfile.Insert(0, drive); - //append private path - TPath privatePath; - iFileSession.PrivatePath(privatePath); - logfile.Append(privatePath); - //append subdir & file name - logfile.Append(_L("fax\\FAXLOG.TXT")); - - //generate dir - TInt kerr(iFileSession.MkDirAll(logfile)); //the directory may not exist, So create one. - if(kerr != KErrAlreadyExists) - { - User::LeaveIfError(kerr); - } - r = iFile.Replace(iFileSession, logfile, EFileWrite | EFileShareAny); - if (r) - { - User::Leave (KFaxLogCreateError); - } - iFileOpen = ETrue; - - } -/* - r = User::LoadPhysicalDevice (PDD_NAME); - if ((r != KErrNone) && (r != KErrAlreadyExists)) - User::Leave (KFaxPDDError); - - r = User::LoadLogicalDevice (LDD_NAME); - if ((r != KErrNone) && (r != KErrAlreadyExists)) - User::Leave (KFaxLDDError); -*/ - - RCommServ s; - r = s.Connect (); - if (r) - User::Leave (KFaxCommsServerError); - - - r = s.LoadCommModule (aFaxServerSessionSettings->iPortDriverName); - if (r) - User::Leave (KFaxCommsPortError); - - r = iCommSession.Open (s, aFaxServerSessionSettings->iCommPortName, ECommShared); - if (r) - User::Leave (KFaxCannotOpenPort); - - iPortOpen = ETrue; - - iCommSession.Config (iRS232Settings); - - iRS232Settings ().iRate = EBps19200; - - iRS232Settings ().iHandshake = 0; - - iRS232Settings ().iTerminator[0] = Ketx; - iRS232Settings ().iTerminator[1] = Kxon; - iRS232Settings ().iTerminator[2] = Klinefeed; - iRS232Settings ().iTerminatorCount = 3; - - r = iCommSession.SetConfig (iRS232Settings); - if (r) - User::Leave (KFaxConfigError); - - iCommSession.SetSignals (KSignalDTR, 0); - iCommSession.SetSignals (KSignalRTS, 0); - - iCommSession.SetReceiveBufferLength (KBufSize); - iCommSession.ResetBuffers(); - - iTransmitBuffer.Zero (); - iSendone.Zero (); - SendL (iSendone); // activate port - switch on DTR/RTS - iSendone.SetMax (); // we send single characters via iSendone[0] - - TBuf8 < 20 > thisclass; - thisclass.SetMax (); - - iOurMessage.Format (_L8 (FaxTransVersionString)); - ProgressUpdateL (); - iOurMessage.Format (_L8 ("The clock ticks at %d Hz"), CLK_TCK / iGranularity); - ProgressUpdateL (); - iOurMessage.Format (_L8 ("Calibration of 2 ms timer at %u calls"), iCalls); - ProgressUpdateL (); - - Speed (EBps19200); - iOurMessage.Format (_L8 ("Initialising at 19200 bps ....")); - ProgressUpdateL (); - - -// added by JerryC from faxtrans cfaxmodm.cpp - - - Silence (CLK_TCK); - TxcharL (Kreturn); - Silence (); -// Silence (); -// Silence (); - // GetMatchL(_L8("OK"),3); - - -// while (iCommSession.QueryReceiveBuffer()!=0) GetMatch (_L8 ("OK"), 1); -// ExportL (_L8 ("AT+FCLASS=?\r")); -// GetMatchL (_L8 ("OK"), 3); - -// GetMatchL (_L8 ("OK"), 3); - - - //r = CLK_TCK; - //while (RxcharWaitL (r)); - -// the addition ends here - -// TxcharL (Kreturn); - - iModemSet = ETrue; - iTimingLoopDelay = EFalse; - - //-- Switch modem into command mode and clear its buffer. - SetModemCommandModeL(); - - if ((aFaxServerSessionSettings->iFaxClass) == (TFaxClass) EClassAuto) - { - ExportL (_L8 ("AT+FCLASS=?\r")); - if(0 == ImportL (thisclass, 2)) - { - User::Leave (KFaxErrWrongModemType); - } - - iOurMessage.Format (_L8 ("%S"), &thisclass); - ProgressUpdateL (); - if ((thisclass.FindF (_L8 ("ERROR"))) >= 0) - User::Leave (KFaxErrWrongModemType); - GetMatchL (_L8 ("OK"), 1); - - if ((thisclass.FindF (_L8 ("2.0"))) >= 0) - { - aFaxServerSessionSettings->iFaxClass = EClass2point0; - } - else if ((thisclass.FindF (_L8 ("2.1"))) >= 0) - { - aFaxServerSessionSettings->iFaxClass = EClass2point0; - } - else if ((thisclass.FindF (_L8 ("2"))) >= 0) - { - aFaxServerSessionSettings->iFaxClass = EClass2; - } - else if ((thisclass.FindF (_L8 ("1"))) >= 0) - { - aFaxServerSessionSettings->iFaxClass = EClass1; - } - else if ((thisclass.FindF (_L8 ("1.0"))) >= 0) - { - aFaxServerSessionSettings->iFaxClass = EClass1; - } - else - User::Leave (KFaxErrWrongModemType); - - User::Leave (KFaxOnlyJustAutoDetected); - } - - thisclass.Copy (_L8 ("AT+FCLASS=")); - if (aFaxServerSessionSettings->iFaxClass == EClass2point0) - { - thisclass.Append (_L8 ("2.0\r")); - } - else if (aFaxServerSessionSettings->iFaxClass == EClass2) - { - thisclass.Append (_L8 ("2\r")); - } - else if (aFaxServerSessionSettings->iFaxClass == EClass1) - { - thisclass.Append (_L8 ("1\r")); - iTimingLoopDelay = ETrue; - } - else - User::Leave (KFaxErrWrongModemType); - - Silence (); - ExportL (thisclass); - if ((GetMatchL (_L8 ("OK"), 1)) == 0) - User::Leave (KFaxErrWrongModemType); - - //Speed (EBps19200); - - if (aFaxServerSessionSettings->iFaxInitString.Length ()) - { - ExportL (aFaxServerSessionSettings->iFaxInitString); - ExportL (_L8 ("\r")); - //GetMatchL (_L8 ("OK"), 3); - } - else - { - ExportL (_L8 ("AT\r")); - } - if ((GetMatchL (_L8 ("OK"), 3)) == 0) - User::Leave (KFaxBadInitialization); - - __FLOG_FAXSRV( _L8("CFaxModem::ConstructL exiting")); - - } - -/********************************************************************/ - -CFaxModem::~CFaxModem () - { -// iOurMessage.Format (_L8 ("Entering CFaxModem Destructor")); -// ProgressUpdateL (); - - __FLOG_FAXSRV( _L8("CFaxModem::~CFaxModem")); - - iCancel = 2; - - if (iModemSet) - { - Xonoff (); - Dropdtr (); - - TRAPD(ret, SetModemCommandModeL()); //-- Switch modem into command mode and clear its buffer. - TRAP (ret, HangupProcedureL()); //-- Issue hung up commands - - Silence (); - } - - if (iPortOpen) - { - iCommSession.ResetBuffers (); - iCommSession.Close (); - } - - if (iFileOpen) - { - iFile.Close (); - } - - if (iFileSessionOpen) - iFileSession.Close (); - } - -/** -* Hang up. Senda 'ATH' command to the modem and sets Echo off, fax class = 0 -* -* @note This function can leave -*/ -void CFaxModem::HangupProcedureL() - { - ExportL (_L8 ("ATH\r")); - GetMatchL (_L8 ("OK"), 2); - ExportL (_L8 ("ATE0+FCLASS=0\r")); // Defect fix PBN-4ZLLX7, NM 23/07/01 - GetMatchL (_L8 ("OK"), 2); - ExportL (_L8 ("\r")); - } - - -/** -* Switch modem into command mode and clear its buffer. -* LYN-585JMR defect fix. By Dmitry Lyokhin. 11.03.02 -* -* @note This function can leave -*/ -void CFaxModem::SetModemCommandModeL(void) -{ - const TInt K_uS_ComWait=500000; //-- used in cleaning up buffer. 0.5 sec timeout. - - ExportL (_L8("+++")); //-- switch the modem to command mode - - //-- clear modem's buffer by reading data - while(iCommSession.QueryReceiveBuffer() > 0) - { - iCommSession.Read (iRecstat, K_uS_ComWait ,iReceiveBuffer); // read data from the serial port - User::WaitForRequest (iRecstat); - } - - Silence(); -} - -/********************************************************************/ -/* -TBool CFaxModem::CheckModemL (TFaxSettings * aFaxSettings) - { - TInt len = aFaxSettings->iDialStoreData.iModemInitString.Length (); - for (TInt attempt = 0; attempt < 3; attempt++) - { - ExportL (_L8 ("ATH\r")); - GetMatchL (_L8 ("OK"), 1); - if (len) - { - ExportL (aFaxSettings->iDialStoreData.iModemInitString); - ExportL (_L8 ("\r")); - GetMatchL (_L8 ("OK"), 1); - } - iOurMessage.Format (_L8 ("ATE0X0Q0V1M%uL%uS0=0S8=%u\r"), - (TUint) aFaxSettings->iDialStoreData.iSpeaker, - (TUint) aFaxSettings->iDialStoreData.iSpeakerVolume, - aFaxSettings->iDialStoreData.iPauseTime); - ExportL (iOurMessage); - if (GetMatchL (_L8 ("OK"), 1) != 0) - { - Silence (); // allow s-l-o-w modems to catch up with us - return (ETrue); - } - } - return (EFalse); - }*/ -/********************************************************************/ - - -/** -* -* @return number of microseconds elapsed since calling CFaxModem::ConstructL(). -* -*/ -TInt CFaxModem::clock () - { - TTime now; - now.UniversalTime (); - TInt64 runningTime = now.MicroSecondsFrom (iStartTime).Int64 (); - return I64LOW(runningTime); - } - -/********************************************************************/ - -/** -* Searches for a given substring in modem's answer. -* also calls ProgressUpdate(). -* -* @param aMatstring - sample string. -* @param aMattime - timeout in seconds. -* -* @see ImportL function -* -* @return 0 - given string (see param aMatstring) is found in modem answer. -* 1 - sample not found or answer timeout. -* -* @leave This function can leave -*/ -TInt CFaxModem::GetMatchL (const TDesC8 & aMatstring, TInt aMattime) - - { - TBuf8 < 64 > modemstring; - TBuf8 < 64 > copymodemstring; - modemstring.SetMax (); - - while (ImportL (modemstring, aMattime)) - { - copymodemstring.Copy (modemstring); - iOurMessage.Format (_L8 ("%S"), ©modemstring); - ProgressUpdateL (); - - if ((modemstring.FindF (aMatstring)) >= 0) - return (1); - - - } - ProgressUpdateL (); - return (0); - } - - -/********************************************************************/ -/** -* Gets textual answer from the modem. -* Calls SubImportL() and ProgressUpdateL(). -* -* @param aLine - ref. to the string descriptor that will accept data from modem if any. - will contain string in upper case without terminating 0x0d, 0x0a. -* @param aTimeout - Timeout in seconds. -* -* @see SubImport function -* -* @return 0 - if timeout occured or wrong input descriptor. Otherwise - -* number of characters in string descriptor. -* -* @note This function can leave -*/ -TInt CFaxModem::ImportL (TDes8 & aLine, TInt aTimeout) -{ - const TInt SubTimeout = 3; //-- modem response 3 seconds timeout - TInt linestate = 0; - TInt CurrTimeout; - - while( aTimeout > 0 ) - { - if (aTimeout <= SubTimeout) CurrTimeout = aTimeout; - else CurrTimeout = SubTimeout; - - linestate = SubImportL (aLine, CurrTimeout); - - if (linestate) - {//-- a response from modem received - __FLOG_FAXSRV2(_L8("mdm imp[%d]: %S"), aTimeout, &aLine); - - //-- look for '+CREG' or '+CGREG' answers from modem. - //-- if found, ignore them and continue waiting. - //-- these unwanted answers represent network registration status (unsolicited result code) - //-- and interfere with fax modem responses. For more information see mm.tsy and gprs.tsy - if ((aLine.FindF(_L8("REG"))) >= 0) - { - aLine.FillZ(); - aLine.Zero (); - } - else break; - - }//if (linestate) - - aTimeout -= SubTimeout; - - ProgressUpdateL (); - }// while - - if (!linestate) - { - __FLOG_FAXSRV2(_L8("mdm imp[%d]: %S"), aTimeout, &aLine); - } - - return (linestate); -} - - -/********************************************************************/ - -/** -* Gets textual answer from the modem. -* -* @param aLine - ref. to the string descriptor that will accept data from modem if any. -* will contain string in upper case without terminating 0x0d, 0x0a -* @param aTimeout - Timeout in seconds. -* -* @see RxcharWait function, iReadone -* -* @return 0 - if timeout occured or wrong input descriptor. Otherwise - -* number of characters in string descriptor -* -* @note This function can leave -*/ -TInt CFaxModem::SubImportL (TDes8 & aLine, TInt aTimeout) - - { - TInt i; - TInt8 k; - TInt t; - - if (aLine.MaxLength () == 0) - return (0); - aLine.FillZ (); - aLine.Zero (); - - t = aTimeout * CLK_TCK; - - do - { - if ((RxcharWaitL (t)) == 0) - return (0); - k = iReadone[0]; - } - - - while (k < 32); - - for (i = 0; i < aLine.MaxLength (); i++) - { - aLine.Append (k); - aLine.UpperCase (); - t = aTimeout * CLK_TCK; - if ((RxcharWaitL (t)) == 0) - return (0); - k = iReadone[0]; - if (k < 32) - break; - } - - if (k == 0x0d) - for (;;) - { - t = CLK_TCK; - if ((RxcharWaitL (t)) == 0) - break; - if (iReadone[0] == 0x0a) - break; - } - - return (i); - } -/********************************************************************/ - -/** -Sends a textual string to the modem with delay. - -@param aLine - const. ref. to the string descriptor to be sent to modem. - -@see SendL function - -@return number of symbols sent to modem. - -@note This function can leave -*/ -TInt CFaxModem::ExportL(const TDesC8& aLine) - { - __FLOG_FAXSRV1(_L8("mdm exp: %S"), &aLine); - - TInt i = 0; - - // we need to guarantee a delay here before sending characters - // lots of modems ignore commands that come in too quickly - // we need to wait for at least twice the clock granularity to ensure - // a decent wait interval as the clock may be just about to tick - - // example : - - // Silence ((iGranularity * 2) + 2); - - // BUT ... - - // on Protea, the clock ticks at 64 beats per second - // that's every 15 ms or to be precise every 15625 microseconds - // iGranularity actually does return this value of 15625 - // our maximum wait will be 30 ms (with a minumum of 15 ms) - // there's also a maximum 35 ms overhead on any timer call or active - // object or whatever - so we could have a delay here of up to 65 ms - - // with the time the modem takes to respond, this leads to too much - // unreliability as we have a strict 75 ms +/- 20% T.30 requirement - // for class 1 modems. (For class 2 and 2.0 modems this isn't a - // problem so we happily delay for iGranularity*2). - - // this applies also to WINS on the PC ticks 10 times per second - // this gives us a maximum delay of 200 ms, which is rather long - // so we resort to a timing loop we calibrate on first entry - - for (;;) - { - i = Rxstat (); - if (iTimingLoopDelay != EFalse) - { - for (TInt x = 0; x < iCalls; x++) - clock (); - } - else - { - Silence ((iGranularity * 2) + 2); - } - if (i == Rxstat ()) - break; - } - - if (aLine.Length()) - { -#ifdef _DEBUG - TRAPD(modemUnplugged, SendL(aLine)); - __FLOG_FAXSRV1(_L8("CFaxModem::ExportL SendL leave error code: %d"), modemUnplugged); -#else - TRAP_IGNORE(SendL(aLine)); -#endif - - iOurMessage.Format(_L8("%S"), &aLine); - i = iOurMessage.Length(); - if ((i != 0) && (iOurMessage[i - 1] == 0x0d)) - { - iOurMessage.Delete(i - 1, 1); - } - ProgressUpdateL(); - } - return i; - } -/********************************************************************/ - -void CFaxModem::Dropdtr () - { - - __FLOG_FAXSRV( _L8("CFaxModem::Dropdtr")); - - LowerDTR (); - Silence (CLK_TCK); - RaiseDTR (); - Silence (CLK_TCK); - } -/********************************************************************/ - - -/** -* Wait approximately 75 ms -*/ -void CFaxModem::Silence () - { - Silence (CLK_TCK / 13); // wait approx 75 milliseconds - } - -/********************************************************************/ - -/** -* Wait given number of microseconds -*/ -void CFaxModem::Silence (TInt ticks) const - { - User::After (ticks); // wait however long - } -/********************************************************************/ - -void CFaxModem::Speed (TBps aSpeed) - { - iRS232Settings ().iRate = aSpeed; - iCommSession.SetConfig (iRS232Settings); - } -/********************************************************************/ - -/** -* Turns on obeying XON, XOFF characters and CTS signal -*/ -void CFaxModem::Xonon () - { - iRS232Settings ().iHandshake = (KConfigObeyXoff | KConfigObeyCTS | KConfigWriteBufferedComplete); - iCommSession.SetConfig (iRS232Settings); - } -/********************************************************************/ - -/** -Turns off handshaking -*/ -void CFaxModem::Xonoff() - { - iSendone.Zero(); // sending a null descriptor -#ifdef _DEBUG - TRAPD(modemUnplugged, SendL(iSendone)); // waits till all pending transmits have gone - __FLOG_FAXSRV1(_L8("CFaxModem::Xonoff SendL leave error code: %d"), modemUnplugged); -#else - TRAP_IGNORE(SendL(iSendone)); // waits till all pending transmits have gone -#endif - - iSendone.SetMax(); // we send single characters via iSendone[0] - - iRS232Settings().iHandshake = 0; - iCommSession.SetConfig(iRS232Settings); - } -/********************************************************************/ - -void CFaxModem::LowerDTR() - { - iCommSession.SetSignals (0, KSignalDTR); // SetSignals(SetMask,ClearMask) ; - } -/********************************************************************/ - -void CFaxModem::RaiseDTR() - { - iCommSession.SetSignals (KSignalDTR, 0); // SetSignals(SetMask,ClearMask) ; - } -/********************************************************************/ - -/** -* @return 0 - if there are no data waiting in driver's input buffer and receiver's buffer to be read. -* otherwise - number of bytes to be read. -*/ -TInt CFaxModem::Rxstat (void) - { - if (iReceiveBuffer.Length () != 0) - return (1); - else - return (iCommSession.QueryReceiveBuffer ()); - } -/********************************************************************/ - -/** -* Does nothing. Just returns 0. -*/ -TInt CFaxModem::Txstat() - { - return 0; - } -/********************************************************************/ - -/** -* Sends 1 byte to modem. -* -* @param aChar -Byte to be sent. -* -* @note This function can leave. -* -* @see SendL() function -* -* @return none. -*/ -void CFaxModem::TxcharL (TUint8 aChar) - { - iSendone[0] = aChar; - SendL (iSendone); - } -/********************************************************************/ - - -// this routine amended July 1998 to offer infinite timeouts when sending data in fax ECM - -void CFaxModem::SendL(const TDesC8 & astring) - { - TTimeIntervalMicroSeconds32 timeout = CLK_TCK * 10; - if ((iProgress.iECM) && (iProgress.iPhase == EDataTransfer)) - { - iCommSession.Write(iTranstat, timeout, astring); - User::WaitForRequest(iTranstat); - if (iTranstat == KErrTimedOut) - { - TInt ticks = 1; - while (Rxstat() != 0) - { - RxcharWaitL(ticks); - if (iReadone[0] == Kcan) - User::Leave(KFaxErrModemDisconnect); - } - } - else if (iTranstat != KErrNone) - iCommSession.ResetBuffers(KCommResetTx); - } - else - { - iCommSession.Write(iTranstat, timeout, astring); - User::WaitForRequest(iTranstat); - if (iTranstat != KErrNone) - { - iCommSession.ResetBuffers(KCommResetTx); - if (iTranstat == KErrTimedOut) - User::Leave(KFaxTransmitterStalled); - } - } - } -/********************************************************************/ - -/** -* Transmits iTransmitBuffer by calling SendL. After sending sets buffer's -* length to zero. -* -* @note This function can leave. -* -* @see SendL() function -*/ -void CFaxModem::CommitTransmitBufferL () - { - SendL (iTransmitBuffer); - iTransmitBuffer.Zero (); - } -/********************************************************************/ - - -/** -* Reads 1 byte from serial port (or iReceiveBuffer) and puts it to iReadone buffer. -* -* @param atimeout - timeout in microseconds. -* -* @return 0 - timeout, -* 1 - byte read and put into iReadone -* -* @note This function can leave. See comments in CFAXMODM.CPP -* -*/ - -// this is our basic get char function with timeout - -// Note that this function *can* leave, despite not being named as an L -// function. This is because the leave is as a result of a user request -// to end the entire fax thread and could occur at any time. This -// function (to read a character) is used at some point by virtually -// every part of the fax system and consequently, were the normal -// convention to be followed, every function would have to be an L -// function - this destroys the whole point of having a separate -// nomenclature. Therefore, I declare that the possibility of a leave -// as a result of the user cancel request is henceforth regarded as an -// exception to the rule than a function which leaves must be called an -// L function. The new rule is that any fax session must be run inside -// a trap harness - not simply because the modem and port need tidying up. - -// Note to the note : The check for user cancel request has been moved to -// ProgressUpdate(). However, this function can still leave if the -// rx buffer overruns, in which case we use the standard iCancel flag to -// check if it is safe to leave and do so. The original note still applies -// but to be honest, I'm less happy about it now. - -TInt CFaxModem::RxcharWaitL (TInt & atimeout) - { - iReadone.Zero (); - if (atimeout == 0) - return (0); - if (iReceiveBuffer.Length () == 0) //iReceiveBuffer == Receive descriptor - { - for (;;) - { - TInt timeBegin = clock (); - iCommSession.Read (iRecstat, atimeout, iReceiveBuffer, KBufSize); // read data from the serial port - User::WaitForRequest (iRecstat); - if ((iRecstat == KErrCommsOverrun) && (iCancel == 0)) // check for overrun and user cancel request - { - iCancel = 2; - iCommSession.ResetBuffers (KCommResetRx); //Reset serial port buffers - User::Leave (KErrCommsOverrun); - } - - if ((iReceiveBuffer.Length () == 0) && (iRecstat == KErrTimedOut)) - { - if (iCommSession.QueryReceiveBuffer () != 0 ) - { - iCommSession.ReadOneOrMore (iRecstat, iReceiveBuffer); - User::WaitForRequest (iRecstat); - } - } - atimeout -= (clock () - timeBegin); //decrement timeout - - if (iReceiveBuffer.Length () != 0) - break; - if (atimeout > 0) - continue; - atimeout = 0; - return (0); - } - if (atimeout < 1) - atimeout = 1; - } - iReadone.Append (iReceiveBuffer[0]); - iReceiveBuffer.Delete (0, 1); - return (1); - } -/********************************************************************/ - -void CFaxModem::ProgressUpdateL () - { -// Commented out by AMC 13/3/00. Pending complete deletion. Not completely removed as removal of function from -// Base has not yet propagated down Device Drivers. Until the device drivers support it there's a chance it -// will have to be re-introduced. - -// UserHal::ResetAutoSwitchOffTimer (); // required to stop powerdown - if (iCancel == 1) - { - iCancel++; - User::Leave (KFaxCancelRequested); - } - - TTime now; - now.UniversalTime (); - - iProgress.iLastUpdateTime = now; - - if (iVerbose) - { - if (iOurMessage.Length ()) - { -#ifdef _DEBUG - // - // Write the log message also to the main log file... - // - TBuf8<256> temp; - - temp.Copy(iOurMessage); - __FLOG_FAXSRV1(_L8("ProgressUpdateL: %S"), &temp); -#endif - - TDateTime dateTime; - TBuf8 < 16 > datestamp; - dateTime = now.DateTime (); - datestamp.Format (_L8 ("%02d.%02d:%02d:%06d "), dateTime.Hour (), dateTime.Minute (), dateTime.Second (), dateTime.MicroSecond ()); - iOurMessage.Insert (0, datestamp); - iOurMessage.Append (13); - iOurMessage.Append (10); - - if (iFileOpen) - iFile.Write (iOurMessage); - - iOurMessage.Zero (); - } - } - } -/*********************************************************************/