--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/multimodetsy/hayes/ATANSWER.CPP Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,552 @@
+// 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 "ATANSWER.H"
+#include "mSLOGGER.H"
+#include "PHONE.H"
+#include "LINE.H"
+#include "CALL.H"
+#include "ATNOCARR.H"
+#include "NOTIFY.H"
+#include "ATIO.H"
+
+const TInt KWaitForVoiceConnect=4000;
+const TInt KWaitForTickleVoiceConnect=3000;
+_LIT8(KTickle,"AT+\r"); // To ensure off-line mode.
+
+//
+// CATAnswerVoice
+//
+CATAnswerVoice* CATAnswerVoice::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ {
+ CATAnswerVoice* answer=new(ELeave) CATAnswerVoice(aIo, aTelObject, aInit,aPhoneGlobals);
+ CleanupStack::PushL(answer);
+ answer->ConstructL();
+ CleanupStack::Pop();
+ return answer;
+ }
+
+CATAnswerVoice::CATAnswerVoice(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : CATVoiceCallConnectCommands(aIo,aTelObject,aInit,aPhoneGlobals)
+ {}
+
+CATAnswerVoice::~CATAnswerVoice()
+ {}
+
+void CATAnswerVoice::Start(TTsyReqHandle aTsyReqHandle, TAny* aParams)
+ {
+ LOGTEXT(_L8("Starting ATA Answer Voice Command"));
+ LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals());
+ iState=EATInitialising;
+ CATVoiceCallConnectCommands::Start(aTsyReqHandle,aParams);
+ }
+
+void CATAnswerVoice::Stop(TTsyReqHandle aTsyReqHandle)
+//
+// Attempts to halt the answering process by sending a carriage return.
+//
+ {
+ __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle));
+ __ASSERT_ALWAYS(iState!=EATNotInProgress,Panic(EATCommand_NotInProgress));
+ LOGTEXT(_L8("Cancelling Answer Voice Command"));
+ iIo->WriteAndTimerCancel(this);
+ if (iState!=EATInitialising) // the ATA has been sent
+ {
+ Write(KCarriageReturn(),1);
+ iPreConnectState=CATCallConnectCommands::ENotInProgress;
+ iState = EATCancellingWaitForWriteComplete;
+ }
+ else // the pre-ATA sequence is still in progress
+ {
+ AddStdExpectStrings();
+ iPreConnectState=CATCallConnectCommands::ECancelling;
+ iState = EATNotInProgress;
+ }
+ }
+
+void CATAnswerVoice::CompleteWithIOError(TEventSource aSource,TInt aStatus)
+ {
+ if (iState!=EATNotInProgress)
+ {
+ iState = EATNotInProgress;
+ CATCallConnectCommands::CompleteWithIOError(aSource,aStatus);
+ }
+ }
+
+void CATAnswerVoice::EventSignal(TEventSource aSource)
+ {
+ // handle bug in Nokia 8210 which does not respond OK when answering
+ // incoming voice calls
+ // assume timeout here means that the call has connected
+ if((aSource==ETimeOutCompletion)
+ &&(iState!=EATCancellingReadCompleted)&&(iState!=EATNotInProgress)
+ &&(iPreConnectState!=EATWaitForATCheckOK))
+ {
+ LOGTEXT(_L8("Timeout Error during Answer"));
+ iState = EATNotInProgress;
+ Complete(KErrTimedOut,aSource);
+ return;
+ }
+
+ if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted
+ && iPreConnectState!=CATCallConnectCommands::ENotInProgress)
+ {
+ CATCallConnectCommands::PreConnectEventSignal(aSource);
+ if (iPreConnectState==CATCallConnectCommands::ENotInProgress) // cancelled
+ iState=EATNotInProgress;
+ if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted)
+ return;
+ else
+ iState=EATSendAnswerCommand;
+ }
+
+ switch(iState)
+ {
+ case EATSendAnswerCommand:
+ {
+ ChangeLineStatus(RCall::EStatusAnswering);
+ // EStatusAnswering results in KErrNone return;
+ (void)ChangeCallStatus(RMobileCall::EStatusAnswering);
+ iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunConnecting);
+ TPtrC8 answerCommand(KAnswerCommand);
+ WriteExpectingResults(answerCommand,3);
+ iState=EATAnswerWaitForWriteComplete;
+ break;
+ }
+
+ case EATAnswerWaitForWriteComplete:
+ {
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals());
+ CPhoneHayes* phone=STATIC_CAST(CPhoneHayes*,iTelObject->Owner()->Owner());
+ phone->StopRingCounter(); // RING should no longer come in
+ AddStdExpectStrings();
+ iIo->SetTimeOut(this,KWaitForVoiceConnect); // Wait for Answer
+ iState=EATAnswerReadCompleted;
+ }
+ break;
+
+ case EATAnswerReadCompleted:
+ {
+ if (aSource==ETimeOutCompletion)
+ {
+ Complete(KErrNone,EReadCompletion);
+ return;
+ }
+ __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ TInt ret(ValidateExpectString());
+ if (ret)
+ {
+ Complete(ret,aSource);
+ break;
+ }
+ iIo->WriteAndTimerCancel(this);
+ // handle bug in Ericsson SH888 which does not report "NO CARRIER" when the
+ // call is dropped unless the modem is prodded following the ATA command
+ LOGTEXT(_L8("handle bug in Ericsson SH888 which does not report NO CARRIER when the"));
+ LOGTEXT(_L8("call is dropped unless the modem is prodded following the ATA command"));
+ iIo->Write(this,KTickle);
+ iIo->SetTimeOut(this);
+ iState=EATTickleWaitForWriteComplete;
+ }
+ break;
+
+
+ case EATTickleWaitForWriteComplete:
+ {
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ iIo->SetTimeOut(this,KWaitForTickleVoiceConnect);
+ iState=EATTickleReadCompleted;
+ }
+ break;
+
+ case EATTickleReadCompleted:
+ __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ RemoveStdExpectStrings();
+ Complete(KErrNone,aSource);
+ break;
+
+
+ case EATCancellingWaitForWriteComplete:
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ AddCommonExpectStrings();
+ iIo->SetTimeOut(this);
+ iState=EATCancellingReadCompleted;
+ break;
+
+ case EATCancellingReadCompleted:
+ {
+ iState = EATNotInProgress;
+ RemoveCommonExpectStrings();
+ if (aSource==EReadCompletion)
+ {
+ TInt ret(ValidateExpectString());
+ if (ret==KErrNone)
+ {
+ iIo->DropDtr(); // Has connected despite sending CR
+ iIo->SetTimeOut(this,KDTRLowPeriod);
+ iState=EDTRDropped;
+ return;
+ }
+ }
+ Complete(KErrCancel,aSource);
+ }
+ break;
+
+ 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==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected));
+ TPtrC8 hangUpCommand(KHangUpCommand);
+ Write(hangUpCommand,1);
+ iState=EATHangupWaitForWriteComplete;
+ }
+ break;
+
+ case EATHangupWaitForWriteComplete:
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ if (!iNoCarrierExpectString)
+ iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString);
+ StandardWriteCompletionHandler(aSource,2);
+ iState=EATHangupReadCompleted;
+ break;
+
+ case EATHangupReadCompleted:
+ __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected));
+ Complete(KErrCancel,aSource);
+ break;
+
+ case EATInitialising:
+ case EATNotInProgress:
+ default:
+ ;
+ }
+ }
+
+void CATAnswerVoice::Complete(TInt aError,TEventSource aSource)
+ {
+ CATVoiceCallConnectCommands::Complete(aError,aSource);
+ }
+
+
+
+//
+// CATAnswerData
+//
+CATAnswerData* CATAnswerData::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) {
+ CATAnswerData* answer=new(ELeave) CATAnswerData(aIo, aTelObject, aInit,aPhoneGlobals);
+ CleanupStack::PushL(answer);
+ answer->ConstructL();
+ CleanupStack::Pop();
+ return answer;
+ }
+
+CATAnswerData::CATAnswerData(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : CATDataCallConnectCommands(aIo,aTelObject,aInit,aPhoneGlobals)
+ {}
+
+CATAnswerData::~CATAnswerData()
+ {}
+
+void CATAnswerData::Start(TTsyReqHandle aTsyReqHandle, TAny* aParams)
+ {
+ LOGTEXT(_L8("Starting ATA Answer Command"));
+ LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals());
+ iState=EATInitialising;
+ CATDataCallConnectCommands::Start(aTsyReqHandle,aParams);
+ }
+
+void CATAnswerData::Stop(TTsyReqHandle aTsyReqHandle)
+//
+// Attempts to halt the answering process by sending a carriage return.
+//
+ {
+ __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle));
+ __ASSERT_ALWAYS(iState!=EATNotInProgress,Panic(EATCommand_NotInProgress));
+ LOGTEXT(_L8("Cancelling Answer Command"));
+ iIo->WriteAndTimerCancel(this);
+ if (iState!=EATInitialising) // the ATA has been sent
+ {
+ Write(KCarriageReturn(),1);
+ iPreConnectState=CATCallConnectCommands::ENotInProgress;
+ iState = EATCancellingWaitForWriteComplete;
+ }
+ else // the pre-ATA sequence is still in progress
+ {
+ AddStdExpectStrings();
+ iPreConnectState=CATCallConnectCommands::ECancelling;
+ iState = EATNotInProgress;
+ }
+ }
+
+TInt CATAnswerData::ValidateAnswerExpectString()
+ {
+ TInt ret(KErrUnknown);
+ if(iIo->FoundChatString()==iConnectExpectString)
+ ret=KErrNone;
+ else if(iIo->FoundChatString()==iNoCarrierExpectString)
+ ret=KErrEtelNoCarrier;
+ return ret;
+ }
+
+void CATAnswerData::CompleteWithIOError(TEventSource aSource,TInt aStatus)
+ {
+ if (iState!=EATNotInProgress)
+ {
+ iState = EATNotInProgress;
+ CATCallConnectCommands::CompleteWithIOError(aSource,aStatus);
+ }
+ }
+
+void CATAnswerData::EventSignal(TEventSource aSource)
+ {
+ if((aSource==ETimeOutCompletion)&&(iState!=EATSpeedReadCompleted)
+ &&(iState!=EATCancellingReadCompleted)&&(iState!=EATNotInProgress)
+ &&(iPreConnectState!=EATWaitForATCheckOK))
+ {
+ LOGTEXT(_L8("Timeout Error during Answer"));
+ iState = EATNotInProgress;
+ Complete(KErrTimedOut,aSource);
+ return;
+ }
+
+ if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted
+ && iPreConnectState!=CATCallConnectCommands::ENotInProgress)
+ {
+ CATCallConnectCommands::PreConnectEventSignal(aSource);
+ if (iPreConnectState==CATCallConnectCommands::ENotInProgress) // cancelled
+ iState=EATNotInProgress;
+ if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted)
+ return;
+ else
+ iState=EATSendAnswerCommand;
+ }
+
+ switch(iState)
+ {
+ case EATSendAnswerCommand:
+ {
+ ChangeLineStatus(RCall::EStatusAnswering);
+ // Don't bother checking return value. Setting to EStatusAnswering always returns KErrNone
+ (void)ChangeCallStatus(RMobileCall::EStatusAnswering);
+ iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunConnecting);
+ TPtrC8 answerCommand(KAnswerCommand);
+ WriteExpectingResults(answerCommand,3);
+ iState=EATAnswerWaitForWriteComplete;
+ break;
+ }
+
+ case EATAnswerWaitForWriteComplete:
+ {
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals());
+ CPhoneHayes* phone=STATIC_CAST(CPhoneHayes*,iTelObject->Owner()->Owner());
+ phone->StopRingCounter(); // RING should no longer come in
+ TInt ret=AddCommonExpectStrings();
+ if (ret!=KErrNone)
+ {
+ Complete(ret,aSource);
+ break;
+ }
+ iIo->SetTimeOut(this,(iPhoneGlobals->iPhoneStatus.iWaitForCarrierTime*1000)+KExtraWaitTime);
+ iState=EATAnswerReadCompleted;
+ }
+ break;
+
+ case EATAnswerReadCompleted:
+ {
+ __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ TInt ret=ValidateAnswerExpectString();
+ RemoveCommonExpectStrings();
+ if (ret!=KErrNone)
+ {
+ iState = EATNotInProgress;
+ Complete(ret,aSource);
+ break;
+ }
+ iIo->SetTimeOut(this,KTimeForExtraRxData);
+ iState=EATSpeedReadCompleted;
+ }
+ break;
+
+ case EATSpeedReadCompleted:
+ {
+ __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected));
+ TInt ret=ParseForBearerCapsResponse();
+ iState = EATNotInProgress;
+ if (ret!=KErrNone)
+ {
+ Complete(ret,aSource);
+ break;
+ }
+ ret=ParseForBearerSpeedResponse();
+ Complete(ret,aSource);
+ }
+ break;
+
+ case EATCancellingWaitForWriteComplete:
+ {
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ TInt ret=AddCommonExpectStrings();
+ if (ret)
+ {
+ Complete(ret,aSource);
+ break;
+ }
+ iIo->SetTimeOut(this);
+ iState=EATCancellingReadCompleted;
+ break;
+ }
+
+ case EATCancellingReadCompleted:
+ {
+ iState = EATNotInProgress;
+ if (aSource==EReadCompletion)
+ {
+ TInt ret=ValidateAnswerExpectString();
+ RemoveCommonExpectStrings();
+ if (ret==KErrNone)
+ {
+ iIo->DropDtr(); // Has connected despite sending CR
+ iIo->SetTimeOut(this,KDTRLowPeriod);
+ iState=EDTRDropped;
+ return;
+ }
+ }
+ RemoveCommonExpectStrings();
+ Complete(KErrCancel,aSource);
+ }
+ break;
+
+ 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==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected));
+ TPtrC8 hangUpCommand(KHangUpCommand);
+ Write(hangUpCommand,1);
+ iState=EATHangupWaitForWriteComplete;
+ }
+ break;
+
+ case EATHangupWaitForWriteComplete:
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ if (!iNoCarrierExpectString)
+ iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString);
+ StandardWriteCompletionHandler(aSource,2);
+ iState=EATHangupReadCompleted;
+ break;
+
+ case EATHangupReadCompleted:
+ __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected));
+ Complete(KErrCancel,aSource); // if ret!=KErrNone, perhaps don't complete but carry on
+ break;
+
+ case EATInitialising:
+ case EATNotInProgress:
+ default:
+ ;
+ }
+ }
+
+void CATAnswerData::Complete(TInt aError,TEventSource aSource)
+ {
+ CATDataCallConnectCommands::Complete(aError,aSource);
+ }
+
+//
+// CATAnswerFax
+//
+
+CATAnswerFax* CATAnswerFax::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ {
+ CATAnswerFax* answer=new(ELeave) CATAnswerFax(aIo, aTelObject, aInit,aPhoneGlobals);
+ CleanupStack::PushL(answer);
+ answer->ConstructL();
+ CleanupStack::Pop();
+ return answer;
+ }
+
+CATAnswerFax::CATAnswerFax(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : CATFaxCallConnectCommands(aIo,aTelObject,aInit,aPhoneGlobals)
+ {}
+
+CATAnswerFax::~CATAnswerFax()
+ {}
+
+void CATAnswerFax::Start(TTsyReqHandle aTsyReqHandle, TAny* /*aParams*/)
+ {
+ LOGTEXT(_L8("Starting Answer fax call"));
+// CATFaxCallConnectCommands::Start(aTsyReqHandle,aParams);
+
+ //-- the change made by Dmitry Lyokhin. PIA-586KGE defect fix
+ //-- CATFaxCallConnectCommands::Start(); starts answering a fax call from sending
+ //-- init strings to the modem that occassionally causes a collision with incoming "+CRING".
+ //-- now state machine starts with EATCallInitCompleted state that does nothing.
+
+ iReqHandle=aTsyReqHandle;
+ __ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL, Panic(EGeneral));
+
+ iPreConnectState=CATCallConnectCommands::EATCallInitCompleted;
+
+ LOGTEXT2(_L8("-CATAnswerFax::Start, iPreConnectState=%d"), iPreConnectState);
+
+ EventSignal(EReadCompletion); // EReadCompletion is a dummy enum here
+ }
+
+void CATAnswerFax::Stop(TTsyReqHandle aTsyReqHandle)
+//
+// If still doing pre-answer command, cancel that, otherwise tell the fax server to cancel
+//
+ {
+ LOGTEXT(_L8("Cancelling Answer Fax Call Command"));
+ CATFaxCallConnectCommands::Stop(aTsyReqHandle);
+ }
+
+void CATAnswerFax::EventSignal(TEventSource aSource)
+ {
+ if((aSource==ETimeOutCompletion)
+ &&(iPreConnectState!=EATWaitForATCheckOK))
+ {
+ LOGTEXT(_L8("Timeout Error during Answer"));
+ Complete(KErrTimedOut,aSource);
+ return;
+ }
+ if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted
+ && iPreConnectState!=CATCallConnectCommands::ENotInProgress)
+ {
+ CATCallConnectCommands::PreConnectEventSignal(aSource);
+ }
+ }
+
+void CATAnswerFax::CompleteSuccessfully()
+ {
+ REINTERPRET_CAST(CCallMobileFax*,iTelObject)->FaxAnswer(iReqHandle);
+ }