--- 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 <commsdattypesv1_1.h>
#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;
+ }