diff -r 000000000000 -r 3553901f7fa8 fax/faxclientandserver/FAXSVR/FAXSERV.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fax/faxclientandserver/FAXSVR/FAXSERV.CPP Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,500 @@ +// 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 "FAXMDRV.H" +#include "FAXMODEM.H" +#include + +#include "FAXLOG.H" + + +/*********************************************************************/ + +CFaxSession *CFaxSession::NewLC () + { + CFaxSession *self = new (ELeave) CFaxSession; + CleanupStack::PushL (self); + return self; + } + +CFaxSession *CFaxSession::NewL () + { + CFaxSession *self = NewLC (); + CleanupStack::Pop (); + return self; + } +/********************************************************************/ +CFaxSession::CFaxSession(void) + :CBase() +{ +} + +CFaxSession::~CFaxSession () + { + FxClose (); + delete iSharedFileHandles; + } + +void CFaxSession::SetCallBack(MFaxCompletionBase* aCompletionBase) + { + iCompletionBase = aCompletionBase; + } + +/********************************************************************/ + +// this kicks off the send or receive session by launching a separate high + // priority faxthread. A FxOpen must be paired with a call to FxClose + // as this is an EPOC32 requirement + // + // we are part of c32 here, so we cannot set a thread priority + // + // the heap and stack sizes set here (4K each) are pure guesswork + // we need a handle to this parent thread so that our child thread + // is able to signal back to us via a TRequestStatus + +TInt CFaxSession::FxOpen (TFaxServerSessionSettings & aSettings,RFax::TProgress* aProgress) +{ + + __FLOG_FAXSRV( _L8("CFaxSession::FxOpen entering")); + + ASSERT (iFaxRequest == NULL); + iFaxServerSessionSettings = aSettings; + +// Initialise the Progress Settings + iProgress = aProgress; + iProgress->iLastUpdateTime=0; + iProgress->iAnswerback.Zero(); + iProgress->iPhase = ENotYetStarted; + iProgress->iSpeed = 9600; + iProgress->iResolution = EFaxNormal; + iProgress->iCompression = EModifiedHuffman; + iProgress->iECM = 0; + iProgress->iPage = 0; + iProgress->iLines = 0; + + TRAPD (state, iFaxRequest = CFaxRequest::NewL (this)); + if (state == KErrNone) + { + iFaxRequest->iChildThread.Logon (iChildDeath); + iFaxRequest->iChildThread.Resume (); + User::WaitForRequest (iFaxRequest->iThreadStat); + CActiveScheduler::Add (iFaxRequest); + } + return (state); +} +/********************************************************************/ + +TInt CFaxSession::FxClose () +{ + __FLOG_FAXSRV( _L8("CFaxSession::FxClose entering")); + + if (iFaxRequest) + { + if (iFaxRequest->IsActive ()) + { + Cancel (); + } + iFaxRequest->FaxRequest (EFxClose); + User::WaitForRequest (iChildDeath); + delete iFaxRequest; + iFaxRequest = NULL; + } + if (!iAmDestructing) + { + iAmDestructing = ETrue; + delete this; + } + return (KErrNone); +} +/********************************************************************/ + +MFaxCompletionBase* CFaxSession::ReturnCompletionBase () +{ + return (iCompletionBase); +} + +/*******************************************************************/ + +void CFaxSession::RxConnect () +{ + iFaxRequest->FaxRequest (ERxConnect); +} +/********************************************************************/ + +void CFaxSession::RxFaxData (TDes8 & aData) +{ + iRxData = &aData; + iFaxRequest->FaxRequest (ERxFaxData); +} +/********************************************************************/ + +void CFaxSession::RxPostPage () +{ + iFaxRequest->FaxRequest (ERxPostPage); +} +/********************************************************************/ + +void CFaxSession::TxConnect () +{ + iFaxRequest->FaxRequest (ETxConnect); +} +/********************************************************************/ + +void CFaxSession::TxFaxData (const TDesC8 & aData) +{ + iTxData = &aData; + iFaxRequest->FaxRequest (ETxFaxData); +} +/********************************************************************/ + +void CFaxSession::TxPostPage () +{ + iFaxRequest->FaxRequest (ETxPostPage); +} + +void CFaxSession::Cancel () +{ + iFaxRequest->Cancel (); +} + +void CFaxSession::StartModemL () +{ + __FLOG_FAXSRV( _L8("CFaxSession::StartModemL entering")); + + if (iModemDriver != NULL) + return; + + if (iFaxServerSessionSettings.iFaxClass == EClass1) + iModemDriver = CFaxClass1::NewL (&iFaxServerSessionSettings,*iProgress); + else if (iFaxServerSessionSettings.iFaxClass == EClass2) + iModemDriver = CFaxClass2::NewL (&iFaxServerSessionSettings,*iProgress); + else if (iFaxServerSessionSettings.iFaxClass == EClass2point0) + iModemDriver = CFaxClass20::NewL (&iFaxServerSessionSettings,*iProgress); + else + User::Leave (KFaxCannotAutodetect); + + iModemDriver->iFaxServerSessionSettings = &iFaxServerSessionSettings; + iCompletionBase->GetCadenceAndTimeOfLastRing(iModemDriver->iCadence, iModemDriver->iTimeOfLastRing); +} + +void CFaxSession::SetFaxHeaderFile(CFaxSharedFileHandles* aSharedFileHandles) + { + //if we already have an object then delete it and use this one instead + if(iSharedFileHandles) + { + delete iSharedFileHandles; + iSharedFileHandles=NULL; + } + //we are now owners of this object and are responsible for its deletion. + iSharedFileHandles = aSharedFileHandles; + } + +/********************************************************************/ + +// the CFaxRequest class is our Fax Server Active Object + +/*********************************************************************/ + +CFaxSession::CFaxRequest::CFaxRequest () +:CActive (1) +{ +} +/********************************************************************/ + +CFaxSession::CFaxRequest *CFaxSession::CFaxRequest::NewLC (CFaxSession * aFaxSession) +{ + CFaxSession::CFaxRequest *self = new (ELeave) CFaxSession::CFaxRequest (); + CleanupStack::PushL (self); + self->ConstructL (aFaxSession); + return self; +} +/********************************************************************/ + +CFaxSession::CFaxRequest *CFaxSession::CFaxRequest::NewL (CFaxSession * aFaxSession) +{ + CFaxSession::CFaxRequest *self = NewLC (aFaxSession); + CleanupStack::Pop (); + return self; +} +/********************************************************************/ + +void CFaxSession::CFaxRequest::ConstructL (CFaxSession * aFaxSession) +{ + TInt stackSize = 0x1400; + _LIT(KFaxThread,"FaxServerThread"); + + iFaxSession = aFaxSession; + TInt res = iFaxSession->iParentThread.Duplicate (RThread ()); + if (res == KErrNone) + res = iChildThread.Create (KFaxThread, + FaxServerThread, + stackSize, + NULL, + iFaxSession, + EOwnerProcess); + if (res) + User::Leave (KFaxThreadError); +} +/********************************************************************/ + +CFaxSession::CFaxRequest::~CFaxRequest () +{ + iFaxSession->iParentThread.Close (); + iChildThread.Close (); +} +/********************************************************************/ + +// once we have our active object, we simply call its FaxRequest + // it re-activates the faxserver thread to process the request + // and sets the FaxRequest object active before returning + +void CFaxSession::CFaxRequest::FaxRequest (CFaxSession::TFaxThreadRequest aFaxThreadRequest) +{ + TRequestStatus *threadStatus = &iThreadStat; + iFaxThreadRequest = aFaxThreadRequest; + if (iFaxThreadRequest != EFxClose) + { + iStatus = KRequestPending; + SetActive (); + } + iChildThread.RequestComplete (threadStatus, aFaxThreadRequest); +} +/********************************************************************/ + +// here we request a cancel of a fax call + +void CFaxSession::CFaxRequest::DoCancel () +{ + iCancel = 1; + if (iFaxSession->iModemDriver) + { + if (iFaxSession->iModemDriver->iModem->iCancel == 0) + iFaxSession->iModemDriver->iModem->iCancel++; + } +} +/********************************************************************/ + +void CFaxSession::CFaxRequest::RunL () +{ + switch (iFaxThreadRequest) + { + case ERxConnect: + { + iFaxSession->ReturnCompletionBase()->RxConnectComplete (iStatus.Int ()); + break; + } + + case ERxFaxData: + { + iFaxSession->ReturnCompletionBase()->RxFaxDataComplete (iStatus.Int ()); + break; + } + + case ERxPostPage: + { + iFaxSession->ReturnCompletionBase()->RxPostPageComplete (iStatus.Int ()); + break; + } + + case ETxConnect: + { + iFaxSession->ReturnCompletionBase()->TxConnectComplete (iStatus.Int ()); + break; + } + + case ETxFaxData: + { + iFaxSession->ReturnCompletionBase()->TxFaxDataComplete (iStatus.Int ()); + break; + } + + case ETxPostPage: + { + iFaxSession->ReturnCompletionBase()->TxPostPageComplete (iStatus.Int ()); + break; + } + default:; + } +} +/********************************************************************/ +// this is a utility function which is the entry to our thread + // it isn't part of any class, but we pass the address + // of our CFaxModemDriver in so that we can check the + // session parameter and get back to the required function + // + // it also has the thread service request dispatcher + +TInt FaxServerThread (TAny * session) + { + TInt state=0; + TInt ret; + TBool terminateThread=EFalse; + CTrapCleanup *cleanup = CTrapCleanup::New (); + CFaxSession *faxsession = (CFaxSession *) session; + TRequestStatus *openStatus = &faxsession->iFaxRequest->iThreadStat; + faxsession->iParentThread.RequestComplete (openStatus, state); + + FOREVER + { + User::WaitForRequest (faxsession->iFaxRequest->iThreadStat); + state = ret = KErrNone; + + __FLOG_FAXSRV1( _L8("FaxServerThread: iThreadStat=%d"), faxsession->iFaxRequest->iThreadStat.Int ()); + + switch (faxsession->iFaxRequest->iThreadStat.Int ()) + { + case CFaxSession::ERxConnect: + TRAP (state, faxsession->StartModemL ()); + + if (state == KErrNone) + { + faxsession->iModemDriver->iModem->iCancel = faxsession->iFaxRequest->iCancel; + TRAP (state, ret = faxsession->iModemDriver->RxConnectL ()); + __FLOG_FAXSRV2(_L8("FaxServerThread state: ERxConnect returned ret=%d, state=%d"), ret, state); + } + break; + + case CFaxSession::ERxFaxData: + if(faxsession->iModemDriver) + { + TRAP (state, faxsession->iModemDriver->GetFaxDataL (faxsession->iRxData)); + __FLOG_FAXSRV2( _L8("FaxServerThread state: ERxFaxData returned ret=%d, state=%d"), ret, state); + } + else + __FLOG_FAXSRV( _L8("FaxServerThread state: ERxFaxData - faxsession->iModemDriver=NULL")); + break; + + case CFaxSession::ERxPostPage: + if(faxsession->iModemDriver) + { + TRAP (state, ret = faxsession->iModemDriver->RxPostPageL ()); + __FLOG_FAXSRV2( _L8("FaxServerThread: iModemDriver->RxPostPageL returned ret=%d, state=%d"), ret, state); + } + else + __FLOG_FAXSRV( _L8("FaxServerThread: iModemDriver->RxPostPageL - faxsession->iModemDriver = NULL")); + break; + + case CFaxSession::ETxConnect: + __FLOG_FAXSRV(_L8("FaxServerThread state: ETxConnect")); + TRAP (state, faxsession->StartModemL ()); //creates an instance of the appropriate + //modem driver (CFax1, CFax2, CFax2.0) + if (state == KErrNone) + { + faxsession->iModemDriver->iModem->iCancel = faxsession->iFaxRequest->iCancel; // added now + faxsession->iModemDriver->SetSharedFileHandles(faxsession->iSharedFileHandles); + TRAP (state, ret = faxsession->iModemDriver->TxConnectL ()); + } + break; + + case CFaxSession::ETxFaxData: + if(faxsession->iModemDriver) + { + TRAP (state, ret = faxsession->iModemDriver->SendFaxDataL (faxsession->iTxData)); + __FLOG_FAXSRV2(_L8("FaxServerThread state: ETxFaxData, state =%d, ret=%d"),state, ret); + } + else + __FLOG_FAXSRV(_L8("FaxServerThread state: ETxFaxData, faxsession->iModemDriver = NULL")); + break; + + case CFaxSession::ETxPostPage: + __FLOG_FAXSRV(_L8("FaxServerThread state: ETxPostPage")); + if(faxsession->iModemDriver) + { + TRAP (state, ret = faxsession->iModemDriver->TxPostPageL ()); + } + else + { + __FLOG_FAXSRV(_L8("FaxServerThread state: ETxPostPage, faxsession->iModemDriver = NULL")); + } + break; + + case CFaxSession::EFxClose: + __FLOG_FAXSRV(_L8("FaxServerThread state: EFxClose:")); + + delete faxsession->iModemDriver; + faxsession->iModemDriver = NULL; + terminateThread=ETrue; + state = KErrNone; + ret = KErrNone; + break; + + default: + state = KErrNone; + ret = KErrNone; + break; + } + if (state == KErrNone) + state = ret; + if (faxsession->iFaxRequest->iCancel) + { + + __FLOG_FAXSRV1(_L8("FaxServerThread: iCancel=%d"), faxsession->iFaxRequest->iCancel); + + state = KFaxCancelRequested; + delete faxsession->iModemDriver; + faxsession->iModemDriver = NULL; + } + if (faxsession->iFaxRequest->IsActive ()) + { + TRequestStatus *returnStatus = &faxsession->iFaxRequest->iStatus; + faxsession->iParentThread.RequestComplete (returnStatus, state); + } + if(terminateThread) + break; +// if (faxsession->iModemDriver == NULL) +// break; + } + delete cleanup; + return (state); +} +/*********************************************************************/ + +TFaxServerSessionSettings& TFaxServerSessionSettings::operator=(const TFaxServerSessionSettings& aSettings) + { + iPhoneNumber = aSettings.iPhoneNumber; + iLogging = aSettings.iLogging; + iFaxInitString = aSettings.iFaxInitString; + iMode = aSettings.iMode;; + iFaxClass = aSettings.iFaxClass; + iPortDriverName = aSettings.iPortDriverName; + iCommPortName = aSettings.iCommPortName; + iFaxId = aSettings.iFaxId; + iMaxSpeed = aSettings.iMaxSpeed; + iMinSpeed = aSettings.iMinSpeed; + iPreferredECM = aSettings.iPreferredECM; + iFaxOnDemandDelay = aSettings.iFaxOnDemandDelay; + iTxResolution = aSettings.iTxResolution; + iTxCompression = aSettings.iTxCompression; + iTxPages = aSettings.iTxPages; + iRxResolution = aSettings.iRxResolution; + iRxCompression = aSettings.iRxCompression; + return(*this); + } + +// +// First Ordinal Functions +// +extern "C" + { + IMPORT_C CFaxSession* LibEntry(void); // Force "Proper Name" export + } + +EXPORT_C CFaxSession* LibEntry() + { + return CFaxSession::NewL(); + } +