diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/multimodetsy/hayes/ATHANGUP.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyserverplugins/multimodetsy/hayes/ATHANGUP.CPP Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,539 @@ +// 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: +// Hang Up Command +// +// + +#include +#include +#include "ATHANGUP.H" +#include "mSLOGGER.H" +#include "PHONE.H" +#include "CALL.H" +#include "ATNOCARR.H" +#include "NOTIFY.H" +#include "ATIO.H" + +const TInt KTimeOut=3; // seconds + +// +// CATHangUpVoice +// +CATHangUpVoice* CATHangUpVoice::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + { + CATHangUpVoice* hangup=new(ELeave) CATHangUpVoice(aIo, aTelObject, aInit, aPhoneGlobals); + CleanupStack::PushL(hangup); + hangup->ConstructL(); + CleanupStack::Pop(); + return hangup; + } + +CATHangUpVoice::CATHangUpVoice(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + : CATCallAlterCommands(aIo,aTelObject,aInit,aPhoneGlobals) + {} + +CATHangUpVoice::~CATHangUpVoice() + { + iIo->RemoveExpectStrings(this); + } + +void CATHangUpVoice::ExecuteCommand(TTsyReqHandle aTsyReqHandle, TAny* aParams,TCallInfoTSY* aCallInfo) +// +// Overloaded function ensures a hang up does not begin an initialise sequence +// + { + iCallInfo = aCallInfo; + Start(aTsyReqHandle,aParams); + } + +void CATHangUpVoice::Start(TTsyReqHandle aTsyReqHandle,TAny* aParams) + { + LOGTEXT(_L8("Starting ATH Hang Up Voice Call Command")); + iReqHandle=aTsyReqHandle; + ChangeLineStatus(RCall::EStatusHangingUp); + // Setting to EStatusDialling always returns KErrNone + (void)ChangeCallStatus(RMobileCall::EStatusDisconnecting); + // must change status before calling + // CheckNotification as the actual current status + // is written back with the notify completion. + // to prevent any completion of reqs synchronously when relinquishing ownership + // the server will cancel any completion of notifications such as call status change once + // this function has completed. + if (iCallInfo->iClientPanicOccurred==ENoPanicOccurred) + iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunHangingUp); + __ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL, Panic(EGeneral)); + CATCallAlterCommands::Start(aTsyReqHandle,aParams); + REINTERPRET_CAST(CCallHayes*,iTelObject)->iWaitForNoCarrier->StopWait(); + iIo->Cancel(); + TCommConfig aConfigPckg; + TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeHangUp); + if (ret==KErrNone) + ret = iIo->ConfigurePort(aConfigPckg); + if (ret!=KErrNone) + { + Complete(ret,EReadCompletion); // EReadCompletion so another Read will not be queued + } + else + { + // No need to drop DTR on voice calls + Write(KHangUpCommand(),1); + iState=EATHangupWaitForWriteComplete; + } + } + +void CATHangUpVoice::Stop(TTsyReqHandle aTsyReqHandle) +// +// Cancel the hang up (most often called from FlushReqs during a shutdown) +// + { + __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle)); + LOGTEXT(_L8("Cancelling HangUp")); + iIo->WriteAndTimerCancel(this); + iIo->SetTimeOut(this,KOneSecondPause); + iState=EHangUpCancelling; + } + + +void CATHangUpVoice::EventSignal(TEventSource aSource) + { + if (aSource==ETimeOutCompletion && iState!=EATHangupReadCompleted + && iState!=EHangUpCancelling) + { + LOGTEXT(_L8("Timeout Error during Hang Up")); + Complete(KErrNone,aSource); // complete with KErrNone for hangup + return; + } + + switch(iState) + { + case EATHangupWaitForWriteComplete: + StandardWriteCompletionHandler(aSource,KTimeOut); + if (!iNoCarrierExpectString) + iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString); + iIo->Read(); + iState=EATHangupReadCompleted; + break; + +// case EATHangupReadCompleted: +// __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); +// { +// TInt ret=ValidateHangUpExpectString(); +// if (ret) +// { +// Complete(ret,aSource); +// break; +// } +// RemoveStdExpectStrings(); +// iState=EATHangupReadCompleted; +// } +// break; + + case EATHangupReadCompleted: + __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); + if (aSource==ETimeOutCompletion) + Complete(KErrNone,aSource); + else + { + TInt ret=ValidateHangUpExpectString(); + Complete(ret,aSource); + } + break; + + case EHangUpCancelling: + if (aSource==EWriteCompletion) + { + iIo->SetTimeOut(this,KOneSecondPause); + } + if (aSource==EReadCompletion || aSource==ETimeOutCompletion) + { + LOGTEXT(_L8("Hang up cancelled")); + iIo->WriteAndTimerCancel(this); + iIo->RemoveExpectStrings(this); + iOKExpectString=NULL; + iErrorExpectString=NULL; + REINTERPRET_CAST(CCallHayes*,iTelObject)->SetToIdle(); + iTelObject->ReqCompleted(iReqHandle,KErrCancel); + } + break; + + default: + ; + } + } + +TInt CATHangUpVoice::ValidateHangUpExpectString() + { + CCommChatString* foundChatString = iIo->FoundChatString(); + if (foundChatString == iNoCarrierExpectString) + { + LOGTEXT(_L8("Modem returned NO CARRIER in response to hang up command")); + return KErrNone; + } + if (foundChatString == iOKExpectString) + { + return KErrNone; + } + LOGTEXT(_L8("Hang up command\tunexpected match!")); + return KErrGeneral; + } + + +void CATHangUpVoice::Complete(TInt aError,TEventSource aSource) + { + iIo->RemoveExpectStrings(this); + iNoCarrierExpectString=NULL; + REINTERPRET_CAST(CCallHayes*,iTelObject)->SetToIdle(); + iIo->Cancel(); + TCommConfig aConfigPckg; + aError = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeInit); + if (aError==KErrNone) + aError = iIo->ConfigurePort(aConfigPckg); + if((aSource==EWriteCompletion)||(aSource==ETimeOutCompletion)) + iIo->Read(); + CATCommands::Complete(aError,aSource); + if (iCallInfo->iClientPanicOccurred==ENoPanicOccurred) + { + iTelObject->ReqCompleted(iReqHandle, aError); + } + else + { + iComplete = CCompleteRelinquish::New(iTelObject); + iComplete->SetWhichCompletion(iCallInfo->iClientPanicOccurred); + iComplete->Call(); // calls the AysncOneShot Relinquish completion function + iCallInfo->iClientPanicOccurred = ENoPanicOccurred; + } + iState=EATNotInProgress; + } + + +// +// +// Hang Up Data Call +// +CATHangUpData* CATHangUpData::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + { + CATHangUpData* hangup=new(ELeave) CATHangUpData(aIo, aTelObject, aInit, aPhoneGlobals); + CleanupStack::PushL(hangup); + hangup->ConstructL(); + CleanupStack::Pop(); + return hangup; + } + +CATHangUpData::CATHangUpData(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + : CATCallAlterCommands(aIo,aTelObject,aInit,aPhoneGlobals) + {} + +CATHangUpData::~CATHangUpData() + { + iIo->RemoveExpectStrings(this); + } + +void CATHangUpData::ExecuteCommand(TTsyReqHandle aTsyReqHandle, TAny* aParams,TCallInfoTSY* aCallInfo) +// +// Overloaded function ensures a hang up does not begin an initialise sequence +// + { + iCallInfo = aCallInfo; + Start(aTsyReqHandle,aParams); + } + +void CATHangUpData::Start(TTsyReqHandle aTsyReqHandle,TAny* aParams) + { + LOGTEXT(_L8("Starting ATH Hang Up Command")); + iReqHandle=aTsyReqHandle; + ChangeLineStatus(RCall::EStatusHangingUp); + // Always returns KErrNone for EStatusDisconnecting + (void)ChangeCallStatus(RMobileCall::EStatusDisconnecting); + // must change status before calling + // CheckNotification as the actual current status + // is written back with the notify completion. + // to prevent any completion of reqs synchronously when relinquishing ownership + // the server will cancel any completion of notifications such as call status change once + // this function has completed. + if (iCallInfo->iClientPanicOccurred==ENoPanicOccurred) + iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunHangingUp); + + __ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL, Panic(EGeneral)); + CATCallAlterCommands::Start(aTsyReqHandle,aParams); + REINTERPRET_CAST(CCallHayes*,iTelObject)->iWaitForNoCarrier->StopWait(); + iIo->Cancel(); + TCommConfig aConfigPckg; + TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeHangUp); + if (ret==KErrNone) + ret = iIo->ConfigurePort(aConfigPckg); + if (ret!=KErrNone) + { + Complete(ret,EReadCompletion); // EReadCompletion so another Read will not be queued + } + else + { + iIo->DropDtr(); + iIo->SetTimeOut(this, KDTRLowPeriod); + iState=EDTRDropped; + } + } + +void CATHangUpData::ValidateHangUpExpectStringL() + { + CCommChatString* foundChatString = iIo->FoundChatString(); + if (foundChatString == iNoCarrierExpectString) + { + LOGTEXT(_L8("Modem returned NO CARRIER in response to hang up command")); + } + else if (foundChatString != iOKExpectString) + { + LOGTEXT(_L8("Modem returned unknown response to hang up command")); + User::Leave(KErrGeneral); + } + } + +void CATHangUpData::Stop(TTsyReqHandle aTsyReqHandle) +// +// Cancel the hang up (most often called from FlushReqs during a shutdown) +// + { + __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle)); + LOGTEXT(_L8("Cancelling HangUp")); + iIo->WriteAndTimerCancel(this); + iIo->SetTimeOut(this,KOneSecondPause); + iState=EHangUpCancelling; + } + +void CATHangUpData::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus) + { + if (iState!=EATNotInProgress) + { + iIo->WriteAndTimerCancel(this); + iNoCarrierExpectString=NULL; + iErrorCode = aStatus; + // SetToIdle calls CATWaitForNoCarrier::StopWait() which removes expect strings - + // this would cause a panic if they hadn't been removed already in + // CATHangUpData::Start(), because CATIO assumes all the CompleteWithIOError + // functions that it calls do not remove them. It removes them itself in + // CATIO::SignalCommandsWithError(). + STATIC_CAST(CCallHayes*,iTelObject)->SetToIdle(); + User::After(KDeltaTimerDefaultGranularity); // wait for a clock tick and continue + if (iCallInfo->iClientPanicOccurred != ENoPanicOccurred) + { + iComplete = CCompleteRelinquish::New(iTelObject); + iComplete->SetWhichCompletion(iCallInfo->iClientPanicOccurred); + iComplete->Call(); + iCallInfo->iClientPanicOccurred = ENoPanicOccurred; + } + else + iTelObject->ReqCompleted(iReqHandle, KErrNone); + iState = EATNotInProgress; + } + } + +void CATHangUpData::EventSignal(TEventSource aSource) + { + if (aSource==ETimeOutCompletion && iState!=EDTRDropped && iState!=EWaitForDTRRaiseSettle + && iState!=EATEscapeSeqCompleted && iState!=EATHangupReadCompleted + && iState!=EWaitForDTRRaiseSettle && iState!=EHangUpCancelling) + { + LOGTEXT(_L8("Timeout Error during Hang Up")); + Complete(KErrNone,aSource); // complete with KErrNone for hangup + return; + } + if (iErrorCode!=KErrNone) + { + if (!iNoCarrierExpectString) + iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString); + iErrorCode=KErrNone; + } + + switch(iState) + { + case EDTRDropped: + __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected)); + iIo->Cancel(); + iIo->RaiseDTR(); + iIo->Read(); + iIo->SetTimeOut(this,KDTRHighSettle); + iState=EWaitForDTRRaiseSettle; + break; + + case EWaitForDTRRaiseSettle: + __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); + if (aSource!=ETimeOutCompletion) + { + TRAPD(ret,ValidateHangUpExpectStringL()); + Complete(ret,aSource); + } + else + { + RemoveStdExpectStrings(); + iIo->RemoveExpectString(iNoCarrierExpectString);// poss. problem as it removes CATWaitForNoCarrier's string too + iNoCarrierExpectString=NULL; + TBuf8 escapeChar; + TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameEscapeCharacter),escapeChar); + if (ret) + { + Complete(ret,aSource); + break; + } + iTxBuffer.Format(_L8("%S%S%S"),&escapeChar,&escapeChar,&escapeChar); + iIo->Write(this,iTxBuffer); + iIo->SetTimeOut(this,KTimeOut*1000); + iState=EATEscapeSeqWaitForWriteComplete; + } + break; + + case EATEscapeSeqWaitForWriteComplete: + if (!iNoCarrierExpectString) + iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString); + StandardWriteCompletionHandler(aSource,KTimeOut); + iState=EATEscapeSeqCompleted; + break; + + case EATEscapeSeqCompleted: + { + __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); + if (aSource!=ETimeOutCompletion) + { + TRAPD(ret,ValidateHangUpExpectStringL()); + if (iIo->FoundChatString()==iNoCarrierExpectString || ret!=KErrNone) + { + Complete(ret,aSource); + break; + } + } + RemoveStdExpectStrings(); + iIo->RemoveExpectString(iNoCarrierExpectString);// poss. problem as it removes CATWaitForNoCarrier's string too + iNoCarrierExpectString=NULL; + Write(KHangUpCommand(),KTimeOut); + iState=EATHangupWaitForWriteComplete; + } + break; + + case EATHangupWaitForWriteComplete: + StandardWriteCompletionHandler(aSource,KTimeOut); + if (!iNoCarrierExpectString) + iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString); + iState=EATHangupReadCompleted; + break; + + case EATHangupReadCompleted: + __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); + if (aSource!=ETimeOutCompletion) + { + TRAPD(ret,ValidateHangUpExpectStringL()); + Complete(ret,aSource); + } + else + { + Complete(KErrTimedOut,aSource); + } + break; + + case EHangUpCancelling: + if (aSource==EWriteCompletion) + { + iIo->SetTimeOut(this,KOneSecondPause); + } + if (aSource==EReadCompletion || aSource==ETimeOutCompletion) + { + LOGTEXT(_L8("Hang up cancelled")); + iIo->WriteAndTimerCancel(this); + iIo->RemoveExpectStrings(this); + iOKExpectString=NULL; + iErrorExpectString=NULL; + REINTERPRET_CAST(CCallHayes*,iTelObject)->SetToIdle(); + iTelObject->ReqCompleted(iReqHandle,KErrCancel); + } + break; + + default: + ; + } + } + +void CATHangUpData::Complete(TInt aError,TEventSource aSource) + { + RemoveStdExpectStrings(); + iIo->RemoveExpectStrings(this); + iNoCarrierExpectString=NULL; + REINTERPRET_CAST(CCallHayes*,iTelObject)->SetToIdle(); + iIo->Cancel(); + TCommConfig aConfigPckg; + aError = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeInit); + if (aError==KErrNone) + aError = iIo->ConfigurePort(aConfigPckg); + if (aSource==EWriteCompletion) + iIo->Read(); + CATCommands::Complete(aError,aSource); + if (iCallInfo->iClientPanicOccurred==ENoPanicOccurred) + { + iTelObject->ReqCompleted(iReqHandle, aError); + } + else + { + iComplete = CCompleteRelinquish::New(iTelObject); + iComplete->SetWhichCompletion(iCallInfo->iClientPanicOccurred); + iComplete->Call(); // calls the AysncOneShot Relinquish completion function + iCallInfo->iClientPanicOccurred = ENoPanicOccurred; + } + iState=EATNotInProgress; + } + +// +// CATHangUpFax +// + +CATHangUpFax* CATHangUpFax::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + { + CATHangUpFax* hangup=new(ELeave) CATHangUpFax(aIo, aTelObject, aInit,aPhoneGlobals); + CleanupStack::PushL(hangup); + hangup->ConstructL(); + CleanupStack::Pop(); + return hangup; + } + +CATHangUpFax::CATHangUpFax(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) + : CATCallAlterCommands(aIo,aTelObject,aInit,aPhoneGlobals) + {} + +CATHangUpFax::~CATHangUpFax() + {} + +void CATHangUpFax::Start(TTsyReqHandle aTsyReqHandle, TAny* /*aParams*/) +// +// When a fax call is terminated, modem is set to not initialised so that if a data call +// follows it will initialise the modem again. +// + { + LOGTEXT(_L8("Starting HangUp fax call")); + iReqHandle=aTsyReqHandle; + iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunHangingUp); + CCallMobileFax* faxCall = REINTERPRET_CAST(CCallMobileFax*,iTelObject); +// iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised; + faxCall->FaxHangUp(aTsyReqHandle); + } + +void CATHangUpFax::Stop(TTsyReqHandle aTsyReqHandle) +// +// Too late to stop hang up process here. Only hope is if escape sequence or init sequence +// had to be performed first +// + { + __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle)); + LOGTEXT(_L8("Too late to cancel Hang Up Command")); + } + +void CATHangUpFax::EventSignal(TEventSource /*aSource*/) + {} + +void CATHangUpFax::Complete(TInt /*aError*/,TEventSource /*aSource*/) + {}