diff -r 630d2f34d719 -r 07a122eea281 telephonyserverplugins/multimodetsy/hayes/CALL.CPP --- a/telephonyserverplugins/multimodetsy/hayes/CALL.CPP Tue Aug 31 16:23:08 2010 +0300 +++ b/telephonyserverplugins/multimodetsy/hayes/CALL.CPP Wed Sep 01 12:40:21 2010 +0100 @@ -16,6 +16,7 @@ #include #include "CALL.H" // Header file for this source file #include "NOTIFY.H" +#include "FAX.H" #include "ATDIAL.H" #include "ATANSWER.H" #include "ATCONNCT.H" @@ -33,6 +34,8 @@ #include "set_cbst.h" // for CATSetCBST class #include "et_struct.h" +_LIT(KFaxServerName,"FaxSvr.dll"); + // // CAcquireEntry class @@ -2048,3 +2051,713 @@ ReqCompleted(aTsyReqHandle,KErrNone); return KErrNone; } + +// local function needed below + +LOCAL_C void SetFaxSessionSettings(RCall::TFaxSessionSettings& aTrg, const RCall::TFaxSessionSettings& aSrc) + { + aTrg.iMode=aSrc.iMode; + aTrg.iFaxRetrieveType=aSrc.iFaxRetrieveType; + aTrg.iFaxClass=aSrc.iFaxClass; + aTrg.iFaxId=aSrc.iFaxId; + aTrg.iMaxSpeed=aSrc.iMaxSpeed; + aTrg.iMinSpeed=aSrc.iMinSpeed; + aTrg.iPreferredECM=aSrc.iPreferredECM; + aTrg.iFaxOnDemandDelay=aSrc.iFaxOnDemandDelay; + aTrg.iTxResolution=aSrc.iTxResolution; + aTrg.iTxCompression=aSrc.iTxCompression; + aTrg.iTxPages=aSrc.iTxPages; + aTrg.iRxResolution=aSrc.iRxResolution; + aTrg.iRxResolution=aSrc.iRxResolution; + } + +// +// CCallMobileFax - fax call functionality +// At construction, phone init sequence may not have yet determined phone's capabilities so +// create object anyway and check in the function calls whether fax is supported by phone +// + +CCallMobileFax* CCallMobileFax::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName) + { + CCallMobileFax* faxCall=new(ELeave) CCallMobileFax(aATIO,aInit,aPhoneGlobals); + TCleanupItem newCallFaxHayesClose(CloseCall,faxCall); + CleanupStack::PushL(newCallFaxHayesClose); + faxCall->ConstructL(aName); + CleanupStack::Pop(); + return faxCall; + } + +CCallMobileFax::CCallMobileFax(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + : CCallMobile(aATIO,aInit,aPhoneGlobals),iFaxSession(NULL),iFax(NULL) + {} + +void CCallMobileFax::ConstructL(const TName& aName) + { + CCallHayes::ConstructL(aName); + iCallInfo.iLineOwnerName = KFaxLineName; + iDialFax=CATDialFax::NewL(iIo,this,iInit,iPhoneGlobals); + iConnectFax=CATConnectFax::NewL(iIo,this,iInit,iPhoneGlobals); + iAnswerFax=CATAnswerFax::NewL(iIo,this,iInit,iPhoneGlobals); + iHangUpFax=CATHangUpFax::NewL(iIo,this,iInit,iPhoneGlobals); + iFaxSettings.iMode = RCall::ETransmit; + iFaxSettings.iFaxRetrieveType = RCall::EFaxOnDemand; + iFaxSettings.iFaxClass = EClassAuto; + iFaxSettings.iMaxSpeed = 9600; + iFaxSettings.iMinSpeed = 2400; + iFaxSettings.iPreferredECM = EFalse; + iFaxSettings.iFaxOnDemandDelay = 20; + iFaxSettings.iTxResolution = EFaxNormal; + iFaxSettings.iTxCompression = EModifiedHuffman; + iFaxSettings.iTxPages = 0; + iFaxSettings.iRxResolution = EFaxNormal; + iFaxSettings.iRxCompression = EModifiedHuffman; + iFaxCompletion = new (ELeave) CFaxCompletion(); + iFaxProgress=CreateFaxProgressChunk(); + if(iFaxProgress==NULL) + User::Leave(KErrEtelFaxChunkNotCreated); + } + +CCallMobileFax::~CCallMobileFax() +// +// Removes itself from array of calls in CLineMobileData +// + { + __ASSERT_DEBUG(iFaxSession==NULL,Panic(EFaxServerNotNull)); + DeleteFaxProgressChunk(); // This deallocates the memory pointed to by iFaxProgress + delete iDialFax; + delete iConnectFax; + delete iAnswerFax; + delete iHangUpFax; + delete iFaxCompletion; + delete iFileHandles; + } + +void CCallMobileFax::CollateCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps) + { + *aCallCaps = RCall::KCapsFax; + if (ValidateFaxClass(iFaxSettings.iFaxClass)==KErrNone + && (!(REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened==TRUE && iFax==NULL)) + && iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent) + // check that fax class is OK and that no other fax call has opened a fax object + { + TCallOwnership owner = CheckOwnership(aTsyReqHandle); + if (ValidateRequest(aTsyReqHandle,RCall::EStatusIdle)==KErrNone) + *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect); + TInt ret=KErrNone; + if (owner==CCallBase::EOwnedFalse) // call owned by another client + ret=KErrEtelNotCallOwner; + else + { + if (!iIsForIncomingCall) + { + if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) + ret=KErrEtelAnswerAlreadyOutstanding; + } + else + ret=KErrEtelAnswerAlreadyOutstanding; + } + if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)) + *aCallCaps |= RCall::KCapsAnswer; + if (owner==CCallBase::EOwnedTrue && iCallInfo.iMobileStatus==RMobileCall::EStatusConnected) + { + *aCallCaps |= RCall::KCapsHangUp; + } + } + } + +TInt CCallMobileFax::OpenFax(TDesC* aTelNumber,TFaxMode aFaxMode) +// +// Open CETelFaxHayes object with desired settings +// + { + TFaxServerSessionSettings faxSettings; + faxSettings.iPhoneNumber.Copy(*aTelNumber); + faxSettings.iLogging = ETrue; + TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameFaxInitString),faxSettings.iFaxInitString); + if (!ret) + { + ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameCsyName),faxSettings.iPortDriverName); + } + if (!ret) + { + ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNamePortName),faxSettings.iCommPortName); + } + if (ret) + return ret; + if(faxSettings.iFaxInitString.Length()==0) + faxSettings.iFaxInitString=KAT2Command; + faxSettings.iMode = aFaxMode; + faxSettings.iFaxClass = iFaxSettings.iFaxClass; + faxSettings.iFaxId = iFaxSettings.iFaxId; + faxSettings.iMaxSpeed = iFaxSettings.iMaxSpeed; + faxSettings.iMinSpeed = iFaxSettings.iMinSpeed; + faxSettings.iPreferredECM = iFaxSettings.iPreferredECM; + faxSettings.iFaxOnDemandDelay = iFaxSettings.iFaxOnDemandDelay; + faxSettings.iTxResolution = iFaxSettings.iTxResolution; + faxSettings.iTxCompression = iFaxSettings.iTxCompression; + faxSettings.iTxPages = iFaxSettings.iTxPages; + faxSettings.iRxResolution = iFaxSettings.iRxResolution; + faxSettings.iRxCompression = iFaxSettings.iRxCompression; + return iFaxSession->FxOpen(faxSettings,iFaxProgress); + } + +TInt CCallMobileFax::ValidateFaxClass(TFaxClass& aFaxClass) + { + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & KFaxCaps) == 0) + { + return KErrNotSupported; + } + switch (aFaxClass) + { + case EClassAuto: // TSY decides what class "AUTO" refers to! + { + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwoPointZero)) + aFaxClass = EClass2point0; + else if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwo)) + aFaxClass = EClass2; + else if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassOne)) + aFaxClass = EClass1; + break; + } + case EClass1: + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassOne)==0) + return KErrEtelWrongModemType; + break; + case EClass1point0: + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassOnePointZero)==0) + return KErrEtelWrongModemType; + break; + case EClass2: + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwo)==0) + return KErrEtelWrongModemType; + break; + case EClass2point0: + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwoPointZero)==0) + return KErrEtelWrongModemType; + break; + case EClass2point1: + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & RPhone::KCapsFaxClassTwoPointOne)==0) + return KErrEtelWrongModemType; + break; + default: + return KErrEtelWrongModemType; + } + return KErrNone; + } + +typedef CFaxSession* (*TFaxServerEntry)(); +void CCallMobileFax::GetFaxBaseL() + { + __ASSERT_DEBUG(iFaxCompletion,Panic(EFaxCompletionPtrNull)); + RFs fs; + (void)User::LeaveIfError(fs.Connect()); + + TInt r=iFaxServerLib.Load(KFaxServerName); + if (r==KErrNone) + { + // Check the Uid2 +#if defined (_UNICODE) + if(iFaxServerLib.Type()[1]!=TUid::Uid(KUidUnicodeDynamicFaxServer)) + r = KErrBadLibraryEntryPoint; +#else + if(iFaxServerLib.Type()[1]!=TUid::Uid(KUidDynamicFaxServer)) + r = KErrBadLibraryEntryPoint; +#endif + if (r==KErrNone) + { + TFaxServerEntry libEntry=(TFaxServerEntry)iFaxServerLib.Lookup(1); + if (libEntry!=NULL) + { + TRAP(r,iFaxSession=(*libEntry)()); // libEntry may leave. + if (r==KErrNone) + { + LOGTEXT(_L8("Loaded Fax Server")); + iFaxSession->SetCallBack(iFaxCompletion); + } + else + iFaxServerLib.Close(); + } + else + { + r = KErrBadLibraryEntryPoint; + iFaxServerLib.Close(); + } + } + else + iFaxServerLib.Close(); + } + fs.Close(); + (void)User::LeaveIfError(r); + } + +TInt CCallMobileFax::FaxConnectHandler(const TTsyReqHandle aTsyReqHandle) + { + TInt ret = ValidateFaxClass(iFaxSettings.iFaxClass); + if (ret!=KErrNone) + { + (void)SetUnowned(); + ReqCompleted(aTsyReqHandle,ret); + return ret; + } + if (REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened==TRUE && iFax==NULL) + { + (void)SetUnowned(); + ReqCompleted(aTsyReqHandle,KErrEtelNotFaxOwner); + return ret; + } + + TRAPD(res,GetFaxBaseL()); + if (res!=KErrNone) + { + (void)SetUnowned(); + ReqCompleted(aTsyReqHandle,res); + } + iPhoneGlobals->iEventSignalActive = EFalse; + return res; + } + +void CCallMobileFax::FaxDial(const TTsyReqHandle aTsyReqHandle,TDesC* aTelNumber) +// +// Called once any initialising has been done. Checks here that modem supports fax, +// and that no other CCallHayes has opened a fax object +// + { + if (FaxConnectHandler(aTsyReqHandle)!=KErrNone) // ReqCompleted is called inside FaxConnectHandler + // if there is an error + return; + TFaxMode faxMode; + if (iFaxSettings.iMode==RCall::ETransmit) + { + faxMode = EDialAndTransmit; + } + else // we're receiving + { + if (iFaxSettings.iFaxRetrieveType==RCall::EFaxPoll) + faxMode = EDialAndReceivePoll; + else + faxMode = EDialAndReceiveFaxBack; + } + TInt res = OpenFax(aTelNumber,faxMode); + if (res!=KErrNone) // make sure cleaned up. + { + ReqCompleted(aTsyReqHandle,res); + return; + } + ChangeLineStatus(RCall::EStatusDialling); + // EStatusDialling always results in KErrNone return + (void) ChangeCallStatus(RMobileCall::EStatusDialling); + iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunConnecting); + iFaxCompletion->Configure(aTsyReqHandle,this); + iIo->Cancel(); + iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessDenied; // so CATIO won't queue a read + + if (faxMode == EDialAndTransmit) + { + LOGTEXT(_L8("About to call CETelFaxBase::TxConnect")); + //this transfers ownership of the file handles object to the fax session object. + iFaxSession->SetFaxHeaderFile(iFileHandles); + //we now aren't resonsible for its deletion. + iFileHandles = NULL; + iFaxSession->TxConnect(); + } + else + { + LOGTEXT(_L8("About to call CETelFaxBase::RxConnect")); + iFaxSession->RxConnect(); + } + } + +TInt CCallMobileFax::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber) +// +// Dial a fax call +// Check that call is not owned by another client, and line is idle +// + { + TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle); + if (ret==KErrNone) + { + (void)SetOwnership(aTsyReqHandle); + SetCallParams(aCallParams); + LOGTEXT(_L8("FaxCall:\tSubmitting Dial Command")); + iDialFax->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo); + } + else + ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + +void CCallMobileFax::FaxCancelCommand(const TTsyReqHandle aTsyReqHandle) +// +// Cancels the fax session (for ConnectCancel and AnswerCancel as well) +// + { + LOGTEXT(_L8("FaxCall:\tCancel Fax call and Unload module")); + if(!iFaxSession) // if iFaxSession is NULL + { // then CleanUpFaxServer has already been called + LOGTEXT(_L8("FaxCall:\tModule already unloaded, completing...")); + ReqCompleted(aTsyReqHandle,KErrCancel); // so return without further processing + return; + } + + LOGTEXT(_L8("FaxCall:\tClosing down fax server module")); + iFaxSession->Cancel(); + CleanUpFaxServer(); + iIo->Read(); + SetToIdle(); + ReqCompleted(aTsyReqHandle,KErrCancel); + } + +TInt CCallMobileFax::DialCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT2(_L8("FaxCall:\tDialCancel(%d) called"),aTsyReqHandle); + iDialFax->CancelCommand(aTsyReqHandle); + return KErrNone; + } + +void CCallMobileFax::FaxConnect(const TTsyReqHandle aTsyReqHandle) +// +// Called once any initialising has been done. Checks here that modem supports fax. +// + { + if (FaxConnectHandler(aTsyReqHandle)!=KErrNone) + return; + TFaxMode faxMode; + if (iFaxSettings.iMode==RCall::ETransmit) + faxMode = EImmediateTransmit; + else + faxMode = EImmediateReceive; + TBuf<1> null; + null.Zero(); + TInt res = OpenFax(&null,faxMode); + if (res!=KErrNone) + { + ReqCompleted(aTsyReqHandle,res); + return; + } + ChangeLineStatus(RCall::EStatusConnecting); + // EStatusConnecting always returns KErrNone + (void)ChangeCallStatus(RMobileCall::EStatusConnecting); + iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunConnecting); + iFaxCompletion->Configure(aTsyReqHandle,this); + iIo->Cancel(); + iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessDenied; // so CATIO won't queue a read + if (faxMode == EImmediateTransmit) + iFaxSession->TxConnect(); + else + iFaxSession->RxConnect(); + } + +TInt CCallMobileFax::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) +// +// Immediate connect to a fax call +// Check that call is not owned by another client, and line is idle +// + { + TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle); + if (ret==KErrNone) + { + (void)SetOwnership(aTsyReqHandle); + SetCallParams(aCallParams); + LOGTEXT(_L8("FaxCall:\tSubmitting Connect Command")); + iConnectFax->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); + } + else + ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + +TInt CCallMobileFax::ConnectCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT2(_L8("FaxCall:\tConnectCancel(%d) called"),aTsyReqHandle); + iConnectFax->CancelCommand(aTsyReqHandle); + return KErrNone; + } + +void CCallMobileFax::FaxAnswer(const TTsyReqHandle aTsyReqHandle) + { + if (FaxConnectHandler(aTsyReqHandle)!=KErrNone) + return; + TFaxMode faxMode; + if (iFaxSettings.iMode==RCall::ETransmit) + faxMode = EWaitForRingAndTransmit; + else + faxMode = EWaitForRingAndReceive; + TBuf<1> null; + null.Zero(); + TInt res = OpenFax(&null,faxMode); + if (res!=KErrNone) + { + ReqCompleted(aTsyReqHandle,res); + return; + } + LOGTEXT(_L8("FaxCall:\tAnswering Fax call")); + ChangeLineStatus(RCall::EStatusAnswering); + // EStatusAnswering always results in KerrNone return + (void)ChangeCallStatus(RMobileCall::EStatusAnswering); + CPhoneHayes* phone=STATIC_CAST(CPhoneHayes*,Owner()->Owner()); + phone->StopRingCounter(); // RING should no longer come in + iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunConnecting); + iFaxCompletion->Configure(aTsyReqHandle,this); + iIo->Cancel(); + iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessDenied; // so CATIO won't queue a read + if (faxMode == EWaitForRingAndTransmit) + iFaxSession->TxConnect(); + else + iFaxSession->RxConnect(); + } + +TInt CCallMobileFax::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams) +// +// Answer a fax call +// + { + TInt ret=KErrNone; + CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle); + if (owned==CCallBase::EOwnedFalse) // call owned by another client + { + ret=KErrEtelNotCallOwner; + } + else if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer()) + ret=KErrEtelAnswerAlreadyOutstanding; + + if (ret==KErrNone) + { + CLineHayes* line = STATIC_CAST(CLineHayes*,Owner()); + CPhoneHayes* phone=STATIC_CAST(CPhoneHayes*,line->Owner()); + phone->CancelOtherRingingCall(line); + line->FreePreAllocCallIfNecessary(); + SetCallParams(aCallParams); + if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging) + { + LOGTEXT(_L8("FaxCall:\tSubmitting Answer Command")); + iAnswerFax->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); + } + else // This call is now a client-designated Incoming Call object. + { + iIsForIncomingCall=ETrue; + iAnswerTsyReqHandle = aTsyReqHandle; + } + return KErrNone; + } + ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + +TInt CCallMobileFax::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle) +// +// Cancel the answer command if possible +// + { + LOGTEXT2(_L8("FaxCall:\tAnswerCancel(%d) called"),aTsyReqHandle); + if (iIsForIncomingCall) + { + iIsForIncomingCall=EFalse; + ReqCompleted(aTsyReqHandle,KErrCancel); + } + else + iAnswerFax->CancelCommand(aTsyReqHandle); + return KErrNone; + } + +void CCallMobileFax::AnswerImmediately() + { + (void)SetOwnership(iAnswerTsyReqHandle); + // EStatusRinging always results in KErrNone return + (void)ChangeCallStatus(RMobileCall::EStatusRinging);// new 14/1/99 + iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred); + iIsForIncomingCall=EFalse; + LOGTEXT(_L8("FaxCall:\tSubmitting Answer command")); + iAnswerFax->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo); + } + +void CCallMobileFax::FaxHangUp(const TTsyReqHandle aTsyReqHandle) +// +// Fax server reconfigures port so no need to here. +// + { + if (iFaxSession) + { + // EStatusDisconnecting always results in KErrNone return + (void)ChangeCallStatus(RMobileCall::EStatusDisconnecting); + ChangeLineStatus(RCall::EStatusHangingUp); + iPhoneGlobals->iNotificationStore->CheckNotification(this,EBegunHangingUp); + CleanUpFaxServer(); + iIo->Read(); + SetToIdle(); + } + ReqCompleted(aTsyReqHandle,KErrNone); + } + +TInt CCallMobileFax::HangUp(const TTsyReqHandle aTsyReqHandle) +// +// Terminate a fax call. Checks fax capability, call ownership and line status. +// + { + if ((iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags & KFaxCaps) == 0) + { + ReqCompleted(aTsyReqHandle,KErrNotSupported); + return KErrNone; + } + if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse) + { + ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner); + return KErrNone; + } + if (iPhoneGlobals->iPhoneStatus.iLineStatus != RCall::EStatusConnected) + { + ReqCompleted(aTsyReqHandle,KErrNone); + return KErrNone; + } + LOGTEXT(_L8("FaxCall:\tHanging up")); + iHangUpFax->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo); + return KErrNone; + } + +TInt CCallMobileFax::HangUpCancel(const TTsyReqHandle aTsyReqHandle) + { + iHangUpFax->CancelCommand(aTsyReqHandle); + return KErrNone; + } + +TInt CCallMobileFax::RelinquishOwnership() +// +// Called by server to tell TSY to either pass ownership on to another interested client +// or hang up immediately +// + { + LOGTEXT(_L8("FaxCall:\tRelinquish Ownership")); + if(iList->iAcquireList.IsEmpty()) + { + if (iDialFax->IsPreConnectInProgress() || + iConnectFax->IsPreConnectInProgress() || + iAnswerFax->IsPreConnectInProgress()) // fax server has not yet been started + { + iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan; + return KErrNone; + } + (void)SetUnowned(); + TInt ret = KErrNone; + if (iCallInfo.iMobileStatus==RMobileCall::EStatusDialling || + iCallInfo.iMobileStatus==RMobileCall::EStatusConnecting || + iCallInfo.iMobileStatus==RMobileCall::EStatusAnswering || + iCallInfo.iMobileStatus==RMobileCall::EStatusConnected || + iCallInfo.iMobileStatus==RMobileCall::EStatusDisconnecting + ) + { + LOGTEXT(_L8("FaxCall:\tHanging up")); + ChangeLineStatus(RCall::EStatusHangingUp); + // EStatusDisconnecting always results in KErrNone return + (void)ChangeCallStatus(RMobileCall::EStatusDisconnecting); + CleanUpFaxServer(); + ChangeLineStatus(RCall::EStatusIdle); + // EStatusIdle always results in KErrNone return + (void)ChangeCallStatus(RMobileCall::EStatusIdle); + iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeIdle; + iIo->Cancel(); + TCommConfig aConfigPckg; + TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeInit); + if (ret==KErrNone) + ret = iIo->ConfigurePort(aConfigPckg); + if (ret) + iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised; + else + iIo->Read(); // should a read be queued in this case? + } + RelinquishOwnershipCompleted(ret); + return KErrNone; + } + CAcquireEntry* entry=iList->iAcquireList.First(); + if (entry) + { + (void)SetOwnership(entry->iTsyReqHandle); + ReqCompleted(entry->iTsyReqHandle,KErrNone); + iList->Remove(entry); + } + RelinquishOwnershipCompleted(KErrNone); + return KErrNone; + } + +TInt CCallMobileFax::GetFaxSettings(const TTsyReqHandle aTsyReqHandle,RCall::TFaxSessionSettings* aSettings) +// +// Which are stored privately in CCallMobileFax +// + { + LOGTEXT(_L8("FaxCall:\tGetting fax settings")); + SetFaxSessionSettings(*aSettings,iFaxSettings); + ReqCompleted(aTsyReqHandle,KErrNone); + return KErrNone; + } + +TInt CCallMobileFax::SetFaxSettings(const TTsyReqHandle aTsyReqHandle,const RCall::TFaxSessionSettings* aSettings) + { + LOGTEXT(_L8("FaxCall:\tSetting fax settings")); + TUint phoneCaps = iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags; + if (aSettings->iFaxClass==EClass1 && (phoneCaps&RPhone::KCapsFaxClassOne) || + aSettings->iFaxClass==EClass2 && (phoneCaps&RPhone::KCapsFaxClassTwo) || + aSettings->iFaxClass==EClass2point0 && (phoneCaps&RPhone::KCapsFaxClassTwoPointZero) || + aSettings->iFaxClass==EClass1point0 && (phoneCaps&RPhone::KCapsFaxClassOnePointZero) || + aSettings->iFaxClass==EClass2point1 && (phoneCaps&RPhone::KCapsFaxClassTwoPointOne) || + aSettings->iFaxClass==EClassAuto) + { + SetFaxSessionSettings(iFaxSettings,*aSettings); + ReqCompleted(aTsyReqHandle,KErrNone); + } + else if (iPhoneGlobals->iPhoneStatus.iInitStatus!=EPhoneInitialised) + ReqCompleted(aTsyReqHandle,KErrEtelUnknownModemCapability); + else + ReqCompleted(aTsyReqHandle,KErrNotSupported); + return KErrNone; + } + +TInt CCallMobileFax::SetFaxSharedHeaderFile(const TTsyReqHandle aTsyReqHandle, CFaxSharedFileHandles* aFaxSharedFileHandles) + { + //if we already own an object delete and re-point to new one. + if(iFileHandles) + { + delete iFileHandles; + iFileHandles = NULL; + } + iFileHandles = aFaxSharedFileHandles; + + ReqCompleted(aTsyReqHandle,KErrNone); + return KErrNone; + } + +CTelObject* CCallMobileFax::OpenNewObjectByNameL(const TDesC& /*aName*/) +// +// Only want one CFaxHayes object to be opened per phone. +// Previously only the connected call could open a CFaxHayes object, so it was easy to check +// whether one had already been opened. Now a fax call can open a fax object at any time +// making it less clear how to check that no other call has opened one. +// + { + if (iPhoneGlobals->iPhoneStatus.iLineStatus != GetCoreCallStatus()) + { // ie another fax call is in progress so this call cannot open a fax object + User::Leave(KErrEtelNotCallOwner); + } + TBool& faxOpened = REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened; + if (faxOpened==TRUE) + { + User::Leave(KErrAlreadyExists); + } + faxOpened=ETrue; + iFax = CFaxHayes::NewL(this,iPhoneGlobals); + return iFax; + } + +void CCallMobileFax::RemoveFax(CFaxHayes* aFaxHayes) + { + if (iFax == aFaxHayes) + iFax=NULL; + REINTERPRET_CAST(CLineMobileFax*,Owner())->iFaxOpened=EFalse; + } + +void CCallMobileFax::CleanUpFaxServer() + { + LOGTEXT(_L8("Closing down Fax Server")); + (void)iFaxSession->FxClose(); + iFaxServerLib.Close(); + iFaxSession = NULL; + iPhoneGlobals->iPhoneStatus.iPortAccess = EPortAccessAllowed; + iPhoneGlobals->iEventSignalActive = EFalse; + }