--- a/telephonyserverplugins/multimodetsy/hayes/ATBASE.CPP Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/multimodetsy/hayes/ATBASE.CPP Thu May 06 15:10:38 2010 +0100
@@ -1,682 +1,682 @@
-// 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:
-// AT Command Base Class
-//
-//
-
-#include "PHONE.H"
-#include "ATIO.H"
-#include "mSLOGGER.H"
-#include "ATINIT.H"
-#include "ATESCAPE.H"
-#include "LINE.H"
-#include "NOTIFY.H"
-#include "sms_rx_queue.h" // for CReceiveSmsQueue
-
-// Specific GSM Error String Response
-_LIT8(KCmsErrorString,"+CMS ERROR:*");
-
-//
-// CATParamListEntry
-// A pointer to a meaningful result in the received buffer from the modem
-//
-CATParamListEntry::CATParamListEntry(const TDesC8& aDes) :
- iResultPtr(aDes)
- {
- }
-
-CATParamListEntry::~CATParamListEntry()
- {}
-
-void CATParamListEntry::Deque()
- {
- iLink.Deque();
- }
-
-void CATParamListEntry::EntryValL(CATParamListEntry* aEntry,TInt& aValue)
- {
- if (aEntry==NULL)
- User::Leave(KErrGeneral);
- TLex8 lex(aEntry->iResultPtr);
- (void)User::LeaveIfError(lex.Val(aValue));
- aEntry->Deque();
- delete aEntry;
- }
-
-TInt CATParamListEntry::EntryValL(CATParamListEntry* aEntry)
- {
- TInt val;
- EntryValL(aEntry,val);
- return val;
- }
-
-
-//
-// Async One Shot to call RelinquishOwnershipComplete().
-// If RelinquishOwnershipComplete() is called synchronously, it destroys the CATIO object
-// before the latter has finished processing.
-//
-CCompleteRelinquish* CCompleteRelinquish::New(CTelObject* aTelObject)
-//
-// Create the Relinquish Complete async one shot
-//
- {
- // The below TRAP is used to stop leavescan errors occurring.
- // This is not the best solution, but I am pressed for time ;-(
- CCompleteRelinquish* ptr=NULL;
- TRAP_IGNORE(ptr=new(ELeave)CCompleteRelinquish(aTelObject));
- return ptr;
- }
-
-CCompleteRelinquish::CCompleteRelinquish(CTelObject* aTelObject)
-//
-// C'tor
-//
- :CAsyncOneShot(CActive::EPriorityLow), iTelObject(aTelObject)
- {
- __DECLARE_NAME(_S("CCompleteRelinquish"));
- }
-
-
-CCompleteRelinquish::~CCompleteRelinquish()
- {
- Cancel();
- }
-
-void CCompleteRelinquish::RunL()
-//
-// Call RelinquishOwnershipCompleted() or RecoverDataPortAndRelinquishOwnershipCompleted()
-// after CATIO has finished its processing
-//
- {
- __ASSERT_ALWAYS(iPanicOccurred!=ENoPanicOccurred,Panic(EIllegalPanicOccurredValue));
- if (iPanicOccurred == EPanicOccurredWithoutDataPortLoan)
- {
- REINTERPRET_CAST(CCallBase*,iTelObject)->RelinquishOwnershipCompleted(KErrNone);
- }
- if (iPanicOccurred == EPanicOccurredDuringDataPortLoan)
- {
- REINTERPRET_CAST(CCallBase*,iTelObject)->RecoverDataPortAndRelinquishOwnershipCompleted(KErrNone);
- }
- delete this;
- }
-//
-// The Command Base Class
-//
-CATBase::CATBase(CATIO* aIo, CTelObject* aTelObject,CPhoneGlobals* aPhoneGlobals)
- : iIo(aIo),iPhoneGlobals(aPhoneGlobals),iComplete(NULL),iTelObject(aTelObject),iCallInfo(NULL)
- {
- iRxResults.SetOffset(_FOFF(CATParamListEntry,iLink));
- }
-
-CATBase::~CATBase()
-//
-// Assumes CATIO pointer is still valid
-//
- {
- if(!iRxResults.IsEmpty())
- {
- CATParamListEntry* entry;
- TDblQueIter<CATParamListEntry> iter(iRxResults);
- while (entry = iter++,entry!=NULL)
- {
- entry->Deque();
- delete entry;
- }
- }
- }
-
-void CATBase::GenericEventSignal(TEventSource aEventSource, TInt aStatus)
-//
-// If an IO error has occurred, complete this ATBase-object with the error.
-//
- {
- if (aStatus!=KErrNone)
- {
- LOGTEXT2(_L8("EventSignal received error status %d"),aStatus);
- CompleteWithIOError(aEventSource,aStatus);
- }
- else
- {
- EventSignal(aEventSource);
- }
- }
-
-void CATBase::AddStdExpectStrings()
- {
- if (!iOKExpectString)
- iOKExpectString=iIo->AddExpectString(this,KOkString);
- if (!iErrorExpectString)
- iErrorExpectString=iIo->AddExpectString(this,KErrorString);
- }
-
-
-TInt CATBase::ValidateExpectString()
-/**
- * New version ValidateExpectStringL which returns an error code
- * as opposed to leaving.
- * Use of this new code should hopefully remove alot of
- * unesseccary TRAP harness in the TSY.
- */
- {
- TInt ret(KErrNone);
-
- if(iIo->FoundChatString()!=iOKExpectString)
- {
- if(iIo->FoundChatString()==iErrorExpectString)
- {
- LOGTEXT(_L8("Modem returned ERROR in response to command"));
- ret=KErrGeneral;
- }
- else
- {
- LOGTEXT(_L8("Modem returned unexpected response to command"));
- ret=KErrUnknown;
- }
- }
-
- return ret;
- }
-
-void CATBase::RemoveStdExpectStrings()
- {
- LOGTEXT(_L8("RemoveStdExpectStrings()"));
- iIo->RemoveExpectString(iOKExpectString);
- iOKExpectString=NULL;
- iIo->RemoveExpectString(iErrorExpectString);
- iErrorExpectString=NULL;
- }
-
-void CATBase::RemoveUnsolicitedStrings()
- {
- LOGTEXT(_L8("RemoveUnsolicitedStrings()"));
-
- _LIT8(KNetworkRegistration,"+CREG:"); // Network registration
- _LIT8(KIncomingCallIndication,"RING"); // Normal Ring
- _LIT8(KIncomingExtCallIndication,"+CRING:"); // Extended format call
- _LIT8(KIncomingExtNTCallParameter,"REL"); // Non-Transparent parameter
- _LIT8(KIncomingExtAlternatingCallParameter,"ALT"); // Unsupported Alternating parameter
- _LIT8(KIncomingExtVoiceRelCallParameter,"VOICE/REL"); // NT Voice parameter
-
- if(!iRxResults.IsEmpty())
- {
- TInt aQueueSteps = NULL;
- CATParamListEntry* entry;
- TDblQueIter<CATParamListEntry> iter(iRxResults);
- // Step along the queue looking for an unsolicited strings
- while (entry = iter++,entry!=NULL)
- {
- TPtrC8 aResult(entry->iResultPtr);
- // If a match is found, we dequeue it and all its expected parameters
- if (aResult==KIncomingCallIndication) // 0 Params
- {
- // Remove the "RING"
- entry->Deque(); delete entry;
- LOGTEXT2(_L8("Unsolicited >%S< Removed"),&aResult);
- }
- else if (aResult==KIncomingExtCallIndication) // 1/2 Params
- {
- // Remove the "+CRING:"
- entry->Deque(); delete entry; entry = iter++;
- LOGTEXT2(_L8("Unsolicited >%S< Removed"),&aResult);
- // We know we should be getting at least one and maybee two parameters
- TPtrC8 aFirstParameterResult(entry->iResultPtr);
- if (aFirstParameterResult==KIncomingExtNTCallParameter
- || aFirstParameterResult==KIncomingExtVoiceRelCallParameter
- || aFirstParameterResult==KIncomingExtAlternatingCallParameter)
- {
- // We have an "ALT" or a "REL" so we have two parameters
- entry->Deque(); delete entry; entry = iter++;
- TPtrC8 aSecondParameterResult(entry->iResultPtr);
- entry->Deque(); delete entry; // If recognised parameter - remove
- LOGTEXT3(_L8("Unsolicited Parameter >%S %S< Removed"),&aFirstParameterResult,&aSecondParameterResult); aSecondParameterResult==KIncomingCallIndication; // Quick fix to remove unused parameters make warning
- }
- else
- {
- // We only have one parameter
- entry->Deque(); delete entry; // If recognised parameter - remove
- LOGTEXT2(_L8("Unsolicited Parameter >%S< Removed"),&aFirstParameterResult);
- }
- }
- else if (aResult==KNetworkRegistration) // 2 Params
- {
- // Remove the "+CREG:"
- entry->Deque(); delete entry; entry = iter++;
- LOGTEXT2(_L8("Unsolicited >%S< Removed"),&aResult);
- // Remove both parameters
- TPtrC8 aFirstParameterResult(entry->iResultPtr);
- entry->Deque(); delete entry; entry = iter++;
- TPtrC8 aSecondParameterResult(entry->iResultPtr);
- entry->Deque(); delete entry;
- LOGTEXT3(_L8("Unsolicited Parameters >%S,%S< Removed"),&aFirstParameterResult,&aSecondParameterResult); aFirstParameterResult==KIncomingCallIndication; aSecondParameterResult==KIncomingCallIndication; // Quick fix to remove unused parameters make warning
- }
-
- // Increment the queue step counter
- else aQueueSteps++;
- }
- // Now we have to retrace the list, ignoring dequeued entries
- for (TInt aLoop=NULL;aLoop<aQueueSteps;aLoop++)
- iter--;
- }
- }
-
-void CATBase::CleanupRxResults(TAny *aCATBase) // for TCleanupOperation
- {
- CATBase* p= reinterpret_cast<CATBase*>(aCATBase);
- TDblQueIter<CATParamListEntry> iter(p->iRxResults);
- CATParamListEntry* entry=iter++;
- while (entry!=NULL)
- {
- entry->Deque();
- delete entry;
- entry=iter++;
- }
- }
-
-void CATBase::RxResultsPushLC()
- {
- TCleanupItem cleanup(CleanupRxResults,this);
- CleanupStack::PushL(cleanup);
- }
-
-void CATBase::ParseBufferLC(TBool aReportLists, TUint aSeparatorChar)
-//
-// Parses buffer. Treats aSeparatorChar like a comma
-//
- {
- LOGTEXT(_L8("Parse the Buffer List"));
-
- if (iIo->CurrentLine()==KOkString)
- iIo->ClearCurrentLine(); // remove trailing "OK"
-
- iBuffer.Set(iIo->Buffer());
- iIo->ClearBuffer();
-
- ParseLC(aReportLists, aSeparatorChar);
- }
-
-void CATBase::ParseLineLC(TBool aReportLists, TUint aSeparatorChar)
-//
-// Parses current line. Treats aSeparatorChar like a comma
-//
- {
- LOGTEXT(_L8("Parse the current line"));
-
- iBuffer.Set(iIo->CurrentLine());
- iIo->ClearCurrentLine();
- ParseLC(aReportLists, aSeparatorChar);
- }
-
-void CATBase::AddParamL(const TDesC8 &aPtr)
- {
- CATParamListEntry* aParamListEntry = new (ELeave) CATParamListEntry(aPtr);
- iRxResults.AddLast(*aParamListEntry);
- }
-
-void CATBase::ParseLC(TBool aReportLists, TUint aSeparatorChar)
-//
-// Does the actual parsing of iBuffer, set up from ParseLineLC or ParseBufferLC
-//
- {
-_LIT8(KOpenBracket, "(");
-_LIT8(KCloseBracket, ")");
-
-#ifdef __LOGDEB__
- TPtrC8 buf(iBuffer);
- if (buf.Length()>180)
- {
- buf.Set(buf.Left(180));
- LOGTEXT2(_L8("buffer to parse >%S< and so on ..."),&buf);
- }
- else
- LOGTEXT2(_L8("buffer to parse >%S<"),&buf);
-#endif
-
- RxResultsPushLC();
- TLex8 yyLex(iBuffer);
-
- // Move cursor past any spaces or open brackets
- yyLex.SkipSpace();
- TChar peek=yyLex.Peek();
- if (peek=='(' || peek=='[' || peek=='{')
- yyLex.Inc();
-
- if (aReportLists && peek=='(')
- {
- AddParamL(KOpenBracket);
- LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
- }
- do
- {
- // Skip all space and opening brackets
- for (;;)
- {
- yyLex.SkipSpace();
- if (yyLex.Eos())
- return;
- peek = yyLex.Peek();
- if (peek!='(')
- break;
- if (aReportLists)
- {
- AddParamL(KOpenBracket);
- LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
- }
- yyLex.Inc();
- }
-
- if (peek=='"') // start of quoted string
- {
- yyLex.Inc(); // step over the quote
- yyLex.Mark();
- while (!yyLex.Eos())
- {
- peek=yyLex.Peek();
- if (peek=='"')
- break;
- yyLex.Inc();
- }
-
- AddParamL(yyLex.MarkedToken());
- LOGTEXT2(_L8("quoted parameter >%S<"),&iRxResults.Last()->iResultPtr);
- if (yyLex.Eos())
- return;
-
- // Skip all space and closing brackets
- for (;;)
- {
- yyLex.Inc();
- yyLex.SkipSpace();
- if (yyLex.Eos())
- return;
- peek = yyLex.Peek();
- if (peek!=')')
- break;
- if (aReportLists)
- {
- AddParamL(KCloseBracket);
- LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
- }
- }
-
- // Skip any following separator
- if (peek==',' || peek==aSeparatorChar)
- {
- yyLex.Inc();
- yyLex.SkipSpace();
- if (yyLex.Eos())
- return;
- peek=yyLex.Peek();
- }
- }
- else // if (peek!=',' && peek !='(' && peek!='"' && peek!=aSeparatorChar)
- {
- yyLex.Mark();
- while (peek!=',' && !peek.IsSpace() && peek!=')' && peek!=']' && peek!='}' && peek!=aSeparatorChar)
- {
- yyLex.Inc();
- if (yyLex.Eos())
- break;
- peek=yyLex.Peek();
- if ((peek==':')&&(aSeparatorChar!=':'))
- {
- yyLex.Inc();
- break;
- }
- }
-
- AddParamL(yyLex.MarkedToken());
- LOGTEXT2(_L8("normal parameter >%S<"),&iRxResults.Last()->iResultPtr);
- if (yyLex.Eos())
- return;
- // skip any whitespace and closing brackets
- for (;;)
- {
- yyLex.SkipSpace();
- if (yyLex.Eos())
- return;
- peek = yyLex.Peek();
- if (peek!=')')
- break;
- if (aReportLists)
- {
- AddParamL(KCloseBracket);
- LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
- }
- yyLex.Inc();
- }
- // Skip any following separator
- if (peek==',' || peek==aSeparatorChar)
- {
- yyLex.Inc();
- yyLex.SkipSpace();
- if (yyLex.Eos())
- return;
- peek=yyLex.Peek();
- }
- }
- } while (peek!=')'&& peek!=']'&& peek!='}');
- if (aReportLists && peek==')')
- {
- AddParamL(KCloseBracket);
- LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
- }
-
- }
-
-void CATBase::ChangeCallStatus(RMobileCall::TMobileCallStatus aCallStatus)
-//
-// This is called from a phone-based command as it is overloaded in CATCallAlterCommands.
-//
- {
- if (iCallInfo->iMobileStatus != aCallStatus)
- {
- iCallInfo->iMobileStatus = aCallStatus;
- if (aCallStatus == RMobileCall::EStatusIdle)
- {
- iCallInfo->iHookStatus = RCall::EHookStatusOn;
- iPhoneGlobals->iNotificationStore->CheckNotification(iTelObject,EBecomeIdle);
- }
- else if (aCallStatus != RMobileCall::EStatusUnknown && aCallStatus != RMobileCall::EStatusRinging)
- {
- iCallInfo->iHookStatus = RCall::EHookStatusOff;
- }
- }
- }
-
-void CATBase::ChangeLineStatus(RCall::TStatus aLineStatus)
- {
- iPhoneGlobals->iPhoneStatus.iLineStatus = aLineStatus;
- }
-
-void CATBase::SetToNotInitialised()
- {
- iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeUnknown;
- iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags = RPhone::KCapsUnknown;
- iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised;
- }
-
-void CATBase::StandardWriteCompletionHandler(TEventSource aSource,TInt aTimeOut)
- {
- __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
- iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
- AddStdExpectStrings();
- }
-
-void CATBase::Write(const TDesC8& aCommand,TInt aTimeOut)
- {
- iTxBuffer.Format(KStringFormatString,&aCommand);
- iIo->Write(this,iTxBuffer);
- iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
- }
-
-void CATBase::Write(const TDesC8& aCommand,TInt aTimeOut,TInt aValue)
- {
- iTxBuffer.Format(KStringAndIntegerFormatString,&aCommand,aValue);
- iIo->Write(this,iTxBuffer);
- iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
- }
-
-void CATBase::Write(const TInt aTimeOut)
-{
- iIo->Write(this,iTxBuffer);
- iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
-}
-
-void CATBase::WriteExpectingResults(const TDesC8& aCommand,TInt aTimeOut)
- {
- iIo->ClearBuffer();
- Write(aCommand,aTimeOut);
- }
-
-void CATBase::AppendWildCardChar(TDes8& aString)
-//
-// A utility function to append a '*' to aString if there's not one already there
-//
- {
- _LIT8(KAsterisk,"*");
- if(aString.Right(1)!=KAsterisk)
- aString.Append(KAsterisk);
- }
-
-void CATBase::AddCmsErrorExpectString()
-//
-// Add the "+CMS ERROR:" expect string
-//
- {
- iCmsExpectString=iIo->AddExpectString(this,KCmsErrorString);
- LOGTEXT(_L8("Added \"+CMS ERROR:\" string."));
- }
-
-void CATBase::RemoveCmsErrorExpectString()
-//
-// Remove the "+CMS ERROR:" expect string
-//
- {
- iIo->RemoveExpectString(iCmsExpectString);
- iCmsExpectString=NULL;
- LOGTEXT(_L8("Removed \"+CMS ERROR:\" string."));
- }
-
-CTelObject* CATBase::Owner()
- {
- return iTelObject;
- }
-
-TCallInfoTSY* CATBase::CallInfo()
- {
- return iCallInfo;
- }
-
-//
-// CATCommands class
-//
-CATCommands::CATCommands(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit, CPhoneGlobals* aPhoneGlobals)
- : CATBase(aIo,aTelObject,aPhoneGlobals), iInit(aInit)
- {}
-
-void CATCommands::ConstructL()
- {
- iATSetToOnlineCommandMode=CATSetToOnlineCommandMode::NewL(iIo,iTelObject,iPhoneGlobals);
- }
-
-CATCommands::~CATCommands()
- {
- delete iATSetToOnlineCommandMode;
- }
-
-void CATCommands::ExecuteCommand(TTsyReqHandle aTsyReqHandle, TAny* aParams)
-//
-// Ensures that phone is initialised and not in on-line data mode
-//
- {
- if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneNotInitialised)
- {
- iInit->StartInit(this,aTsyReqHandle,aParams);
- }
- else if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineData)
- {
- iATSetToOnlineCommandMode->StartEscapeSequence(this,aTsyReqHandle,aParams);
- }
- else
- {
- if (iPhoneGlobals->iEventSignalActive)
- {
- // Make sure request only completed if we have a valid request handle
- // Signal that request could not be executed
- if (aTsyReqHandle)
- iTelObject->ReqCompleted(aTsyReqHandle, KErrInUse);
- }
- else
- {
- iPhoneGlobals->iEventSignalActive = ETrue;
- Start(aTsyReqHandle, aParams);
- }
- }
- }
-
-void CATCommands::ExecuteCommand(TTsyReqHandle aTsyReqHandle, TAny* aParams,TCallInfoTSY* aCallInfo)
-//
-// Overloaded function for CCallHayes-originated commands, so that the status can be
-// changed for CCallHayes->iCallInfo
-//
- {
- iCallInfo = aCallInfo;
- ExecuteCommand(aTsyReqHandle,aParams);
- }
-
-void CATCommands::CancelCommand(TTsyReqHandle aTsyReqHandle)
- {
- if(iInit->CheckActiveReqHandle(aTsyReqHandle))
- {
- iInit->StopInit(aTsyReqHandle);
- }
- else if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineData)
- {
- iATSetToOnlineCommandMode->StopEscapeSequence(aTsyReqHandle);
- }
- else
- {
- Stop(aTsyReqHandle);
- }
- }
-
-void CATCommands::Complete(TInt aError,TEventSource /*aSource*/)
-//
-// Should be called by all Complete()'s before ReqCompleted()
-//
- {
- LOGTEXT(_L8("CATCommands::Complete called"));
-
- if (aError==KErrTimedOut)
- {
- LOGTEXT(_L8("CATCommands::Complete KErrTimedOut error, setting EPhoneNotIntialised"));
- iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised;
- }
-
- // Clear the flow control flag to show no AT commands are writing to the
- // serial port.
- iPhoneGlobals->iEventSignalActive = EFalse;
-
- // Allow the CReceiveSmsQueue object to read PDUs from the phones memory, if needed
- if(iPhoneGlobals->iReceiveSmsQueuePtr)
- iPhoneGlobals->iReceiveSmsQueuePtr->ReadPDUFromPhone();
-
- // Check the flow control flag, as the previous lines may have started off a
- // AT command.
- // If the flow control is clear then allow the Check ForChangeOfNetwork to have
- // a go at updating its status and writing to the serial port.
- if (!(iPhoneGlobals->iEventSignalActive))
- iPhoneGlobals->CheckForChangeOfNetwork();
- }
+// 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:
+// AT Command Base Class
+//
+//
+
+#include "PHONE.H"
+#include "ATIO.H"
+#include "mSLOGGER.H"
+#include "ATINIT.H"
+#include "ATESCAPE.H"
+#include "LINE.H"
+#include "NOTIFY.H"
+#include "sms_rx_queue.h" // for CReceiveSmsQueue
+
+// Specific GSM Error String Response
+_LIT8(KCmsErrorString,"+CMS ERROR:*");
+
+//
+// CATParamListEntry
+// A pointer to a meaningful result in the received buffer from the modem
+//
+CATParamListEntry::CATParamListEntry(const TDesC8& aDes) :
+ iResultPtr(aDes)
+ {
+ }
+
+CATParamListEntry::~CATParamListEntry()
+ {}
+
+void CATParamListEntry::Deque()
+ {
+ iLink.Deque();
+ }
+
+void CATParamListEntry::EntryValL(CATParamListEntry* aEntry,TInt& aValue)
+ {
+ if (aEntry==NULL)
+ User::Leave(KErrGeneral);
+ TLex8 lex(aEntry->iResultPtr);
+ (void)User::LeaveIfError(lex.Val(aValue));
+ aEntry->Deque();
+ delete aEntry;
+ }
+
+TInt CATParamListEntry::EntryValL(CATParamListEntry* aEntry)
+ {
+ TInt val;
+ EntryValL(aEntry,val);
+ return val;
+ }
+
+
+//
+// Async One Shot to call RelinquishOwnershipComplete().
+// If RelinquishOwnershipComplete() is called synchronously, it destroys the CATIO object
+// before the latter has finished processing.
+//
+CCompleteRelinquish* CCompleteRelinquish::New(CTelObject* aTelObject)
+//
+// Create the Relinquish Complete async one shot
+//
+ {
+ // The below TRAP is used to stop leavescan errors occurring.
+ // This is not the best solution, but I am pressed for time ;-(
+ CCompleteRelinquish* ptr=NULL;
+ TRAP_IGNORE(ptr=new(ELeave)CCompleteRelinquish(aTelObject));
+ return ptr;
+ }
+
+CCompleteRelinquish::CCompleteRelinquish(CTelObject* aTelObject)
+//
+// C'tor
+//
+ :CAsyncOneShot(CActive::EPriorityLow), iTelObject(aTelObject)
+ {
+ __DECLARE_NAME(_S("CCompleteRelinquish"));
+ }
+
+
+CCompleteRelinquish::~CCompleteRelinquish()
+ {
+ Cancel();
+ }
+
+void CCompleteRelinquish::RunL()
+//
+// Call RelinquishOwnershipCompleted() or RecoverDataPortAndRelinquishOwnershipCompleted()
+// after CATIO has finished its processing
+//
+ {
+ __ASSERT_ALWAYS(iPanicOccurred!=ENoPanicOccurred,Panic(EIllegalPanicOccurredValue));
+ if (iPanicOccurred == EPanicOccurredWithoutDataPortLoan)
+ {
+ REINTERPRET_CAST(CCallBase*,iTelObject)->RelinquishOwnershipCompleted(KErrNone);
+ }
+ if (iPanicOccurred == EPanicOccurredDuringDataPortLoan)
+ {
+ REINTERPRET_CAST(CCallBase*,iTelObject)->RecoverDataPortAndRelinquishOwnershipCompleted(KErrNone);
+ }
+ delete this;
+ }
+//
+// The Command Base Class
+//
+CATBase::CATBase(CATIO* aIo, CTelObject* aTelObject,CPhoneGlobals* aPhoneGlobals)
+ : iIo(aIo),iPhoneGlobals(aPhoneGlobals),iComplete(NULL),iTelObject(aTelObject),iCallInfo(NULL)
+ {
+ iRxResults.SetOffset(_FOFF(CATParamListEntry,iLink));
+ }
+
+CATBase::~CATBase()
+//
+// Assumes CATIO pointer is still valid
+//
+ {
+ if(!iRxResults.IsEmpty())
+ {
+ CATParamListEntry* entry;
+ TDblQueIter<CATParamListEntry> iter(iRxResults);
+ while (entry = iter++,entry!=NULL)
+ {
+ entry->Deque();
+ delete entry;
+ }
+ }
+ }
+
+void CATBase::GenericEventSignal(TEventSource aEventSource, TInt aStatus)
+//
+// If an IO error has occurred, complete this ATBase-object with the error.
+//
+ {
+ if (aStatus!=KErrNone)
+ {
+ LOGTEXT2(_L8("EventSignal received error status %d"),aStatus);
+ CompleteWithIOError(aEventSource,aStatus);
+ }
+ else
+ {
+ EventSignal(aEventSource);
+ }
+ }
+
+void CATBase::AddStdExpectStrings()
+ {
+ if (!iOKExpectString)
+ iOKExpectString=iIo->AddExpectString(this,KOkString);
+ if (!iErrorExpectString)
+ iErrorExpectString=iIo->AddExpectString(this,KErrorString);
+ }
+
+
+TInt CATBase::ValidateExpectString()
+/**
+ * New version ValidateExpectStringL which returns an error code
+ * as opposed to leaving.
+ * Use of this new code should hopefully remove alot of
+ * unesseccary TRAP harness in the TSY.
+ */
+ {
+ TInt ret(KErrNone);
+
+ if(iIo->FoundChatString()!=iOKExpectString)
+ {
+ if(iIo->FoundChatString()==iErrorExpectString)
+ {
+ LOGTEXT(_L8("Modem returned ERROR in response to command"));
+ ret=KErrGeneral;
+ }
+ else
+ {
+ LOGTEXT(_L8("Modem returned unexpected response to command"));
+ ret=KErrUnknown;
+ }
+ }
+
+ return ret;
+ }
+
+void CATBase::RemoveStdExpectStrings()
+ {
+ LOGTEXT(_L8("RemoveStdExpectStrings()"));
+ iIo->RemoveExpectString(iOKExpectString);
+ iOKExpectString=NULL;
+ iIo->RemoveExpectString(iErrorExpectString);
+ iErrorExpectString=NULL;
+ }
+
+void CATBase::RemoveUnsolicitedStrings()
+ {
+ LOGTEXT(_L8("RemoveUnsolicitedStrings()"));
+
+ _LIT8(KNetworkRegistration,"+CREG:"); // Network registration
+ _LIT8(KIncomingCallIndication,"RING"); // Normal Ring
+ _LIT8(KIncomingExtCallIndication,"+CRING:"); // Extended format call
+ _LIT8(KIncomingExtNTCallParameter,"REL"); // Non-Transparent parameter
+ _LIT8(KIncomingExtAlternatingCallParameter,"ALT"); // Unsupported Alternating parameter
+ _LIT8(KIncomingExtVoiceRelCallParameter,"VOICE/REL"); // NT Voice parameter
+
+ if(!iRxResults.IsEmpty())
+ {
+ TInt aQueueSteps = NULL;
+ CATParamListEntry* entry;
+ TDblQueIter<CATParamListEntry> iter(iRxResults);
+ // Step along the queue looking for an unsolicited strings
+ while (entry = iter++,entry!=NULL)
+ {
+ TPtrC8 aResult(entry->iResultPtr);
+ // If a match is found, we dequeue it and all its expected parameters
+ if (aResult==KIncomingCallIndication) // 0 Params
+ {
+ // Remove the "RING"
+ entry->Deque(); delete entry;
+ LOGTEXT2(_L8("Unsolicited >%S< Removed"),&aResult);
+ }
+ else if (aResult==KIncomingExtCallIndication) // 1/2 Params
+ {
+ // Remove the "+CRING:"
+ entry->Deque(); delete entry; entry = iter++;
+ LOGTEXT2(_L8("Unsolicited >%S< Removed"),&aResult);
+ // We know we should be getting at least one and maybee two parameters
+ TPtrC8 aFirstParameterResult(entry->iResultPtr);
+ if (aFirstParameterResult==KIncomingExtNTCallParameter
+ || aFirstParameterResult==KIncomingExtVoiceRelCallParameter
+ || aFirstParameterResult==KIncomingExtAlternatingCallParameter)
+ {
+ // We have an "ALT" or a "REL" so we have two parameters
+ entry->Deque(); delete entry; entry = iter++;
+ TPtrC8 aSecondParameterResult(entry->iResultPtr);
+ entry->Deque(); delete entry; // If recognised parameter - remove
+ LOGTEXT3(_L8("Unsolicited Parameter >%S %S< Removed"),&aFirstParameterResult,&aSecondParameterResult); aSecondParameterResult==KIncomingCallIndication; // Quick fix to remove unused parameters make warning
+ }
+ else
+ {
+ // We only have one parameter
+ entry->Deque(); delete entry; // If recognised parameter - remove
+ LOGTEXT2(_L8("Unsolicited Parameter >%S< Removed"),&aFirstParameterResult);
+ }
+ }
+ else if (aResult==KNetworkRegistration) // 2 Params
+ {
+ // Remove the "+CREG:"
+ entry->Deque(); delete entry; entry = iter++;
+ LOGTEXT2(_L8("Unsolicited >%S< Removed"),&aResult);
+ // Remove both parameters
+ TPtrC8 aFirstParameterResult(entry->iResultPtr);
+ entry->Deque(); delete entry; entry = iter++;
+ TPtrC8 aSecondParameterResult(entry->iResultPtr);
+ entry->Deque(); delete entry;
+ LOGTEXT3(_L8("Unsolicited Parameters >%S,%S< Removed"),&aFirstParameterResult,&aSecondParameterResult); aFirstParameterResult==KIncomingCallIndication; aSecondParameterResult==KIncomingCallIndication; // Quick fix to remove unused parameters make warning
+ }
+
+ // Increment the queue step counter
+ else aQueueSteps++;
+ }
+ // Now we have to retrace the list, ignoring dequeued entries
+ for (TInt aLoop=NULL;aLoop<aQueueSteps;aLoop++)
+ iter--;
+ }
+ }
+
+void CATBase::CleanupRxResults(TAny *aCATBase) // for TCleanupOperation
+ {
+ CATBase* p= reinterpret_cast<CATBase*>(aCATBase);
+ TDblQueIter<CATParamListEntry> iter(p->iRxResults);
+ CATParamListEntry* entry=iter++;
+ while (entry!=NULL)
+ {
+ entry->Deque();
+ delete entry;
+ entry=iter++;
+ }
+ }
+
+void CATBase::RxResultsPushLC()
+ {
+ TCleanupItem cleanup(CleanupRxResults,this);
+ CleanupStack::PushL(cleanup);
+ }
+
+void CATBase::ParseBufferLC(TBool aReportLists, TUint aSeparatorChar)
+//
+// Parses buffer. Treats aSeparatorChar like a comma
+//
+ {
+ LOGTEXT(_L8("Parse the Buffer List"));
+
+ if (iIo->CurrentLine()==KOkString)
+ iIo->ClearCurrentLine(); // remove trailing "OK"
+
+ iBuffer.Set(iIo->Buffer());
+ iIo->ClearBuffer();
+
+ ParseLC(aReportLists, aSeparatorChar);
+ }
+
+void CATBase::ParseLineLC(TBool aReportLists, TUint aSeparatorChar)
+//
+// Parses current line. Treats aSeparatorChar like a comma
+//
+ {
+ LOGTEXT(_L8("Parse the current line"));
+
+ iBuffer.Set(iIo->CurrentLine());
+ iIo->ClearCurrentLine();
+ ParseLC(aReportLists, aSeparatorChar);
+ }
+
+void CATBase::AddParamL(const TDesC8 &aPtr)
+ {
+ CATParamListEntry* aParamListEntry = new (ELeave) CATParamListEntry(aPtr);
+ iRxResults.AddLast(*aParamListEntry);
+ }
+
+void CATBase::ParseLC(TBool aReportLists, TUint aSeparatorChar)
+//
+// Does the actual parsing of iBuffer, set up from ParseLineLC or ParseBufferLC
+//
+ {
+_LIT8(KOpenBracket, "(");
+_LIT8(KCloseBracket, ")");
+
+#ifdef __LOGDEB__
+ TPtrC8 buf(iBuffer);
+ if (buf.Length()>180)
+ {
+ buf.Set(buf.Left(180));
+ LOGTEXT2(_L8("buffer to parse >%S< and so on ..."),&buf);
+ }
+ else
+ LOGTEXT2(_L8("buffer to parse >%S<"),&buf);
+#endif
+
+ RxResultsPushLC();
+ TLex8 yyLex(iBuffer);
+
+ // Move cursor past any spaces or open brackets
+ yyLex.SkipSpace();
+ TChar peek=yyLex.Peek();
+ if (peek=='(' || peek=='[' || peek=='{')
+ yyLex.Inc();
+
+ if (aReportLists && peek=='(')
+ {
+ AddParamL(KOpenBracket);
+ LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
+ }
+ do
+ {
+ // Skip all space and opening brackets
+ for (;;)
+ {
+ yyLex.SkipSpace();
+ if (yyLex.Eos())
+ return;
+ peek = yyLex.Peek();
+ if (peek!='(')
+ break;
+ if (aReportLists)
+ {
+ AddParamL(KOpenBracket);
+ LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
+ }
+ yyLex.Inc();
+ }
+
+ if (peek=='"') // start of quoted string
+ {
+ yyLex.Inc(); // step over the quote
+ yyLex.Mark();
+ while (!yyLex.Eos())
+ {
+ peek=yyLex.Peek();
+ if (peek=='"')
+ break;
+ yyLex.Inc();
+ }
+
+ AddParamL(yyLex.MarkedToken());
+ LOGTEXT2(_L8("quoted parameter >%S<"),&iRxResults.Last()->iResultPtr);
+ if (yyLex.Eos())
+ return;
+
+ // Skip all space and closing brackets
+ for (;;)
+ {
+ yyLex.Inc();
+ yyLex.SkipSpace();
+ if (yyLex.Eos())
+ return;
+ peek = yyLex.Peek();
+ if (peek!=')')
+ break;
+ if (aReportLists)
+ {
+ AddParamL(KCloseBracket);
+ LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
+ }
+ }
+
+ // Skip any following separator
+ if (peek==',' || peek==aSeparatorChar)
+ {
+ yyLex.Inc();
+ yyLex.SkipSpace();
+ if (yyLex.Eos())
+ return;
+ peek=yyLex.Peek();
+ }
+ }
+ else // if (peek!=',' && peek !='(' && peek!='"' && peek!=aSeparatorChar)
+ {
+ yyLex.Mark();
+ while (peek!=',' && !peek.IsSpace() && peek!=')' && peek!=']' && peek!='}' && peek!=aSeparatorChar)
+ {
+ yyLex.Inc();
+ if (yyLex.Eos())
+ break;
+ peek=yyLex.Peek();
+ if ((peek==':')&&(aSeparatorChar!=':'))
+ {
+ yyLex.Inc();
+ break;
+ }
+ }
+
+ AddParamL(yyLex.MarkedToken());
+ LOGTEXT2(_L8("normal parameter >%S<"),&iRxResults.Last()->iResultPtr);
+ if (yyLex.Eos())
+ return;
+ // skip any whitespace and closing brackets
+ for (;;)
+ {
+ yyLex.SkipSpace();
+ if (yyLex.Eos())
+ return;
+ peek = yyLex.Peek();
+ if (peek!=')')
+ break;
+ if (aReportLists)
+ {
+ AddParamL(KCloseBracket);
+ LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
+ }
+ yyLex.Inc();
+ }
+ // Skip any following separator
+ if (peek==',' || peek==aSeparatorChar)
+ {
+ yyLex.Inc();
+ yyLex.SkipSpace();
+ if (yyLex.Eos())
+ return;
+ peek=yyLex.Peek();
+ }
+ }
+ } while (peek!=')'&& peek!=']'&& peek!='}');
+ if (aReportLists && peek==')')
+ {
+ AddParamL(KCloseBracket);
+ LOGTEXT2(_L8("list separator >%S<"),&iRxResults.Last()->iResultPtr);
+ }
+
+ }
+
+void CATBase::ChangeCallStatus(RMobileCall::TMobileCallStatus aCallStatus)
+//
+// This is called from a phone-based command as it is overloaded in CATCallAlterCommands.
+//
+ {
+ if (iCallInfo->iMobileStatus != aCallStatus)
+ {
+ iCallInfo->iMobileStatus = aCallStatus;
+ if (aCallStatus == RMobileCall::EStatusIdle)
+ {
+ iCallInfo->iHookStatus = RCall::EHookStatusOn;
+ iPhoneGlobals->iNotificationStore->CheckNotification(iTelObject,EBecomeIdle);
+ }
+ else if (aCallStatus != RMobileCall::EStatusUnknown && aCallStatus != RMobileCall::EStatusRinging)
+ {
+ iCallInfo->iHookStatus = RCall::EHookStatusOff;
+ }
+ }
+ }
+
+void CATBase::ChangeLineStatus(RCall::TStatus aLineStatus)
+ {
+ iPhoneGlobals->iPhoneStatus.iLineStatus = aLineStatus;
+ }
+
+void CATBase::SetToNotInitialised()
+ {
+ iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeUnknown;
+ iPhoneGlobals->iPhoneStatus.iDataAndFaxFlags = RPhone::KCapsUnknown;
+ iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised;
+ }
+
+void CATBase::StandardWriteCompletionHandler(TEventSource aSource,TInt aTimeOut)
+ {
+ __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+ iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
+ AddStdExpectStrings();
+ }
+
+void CATBase::Write(const TDesC8& aCommand,TInt aTimeOut)
+ {
+ iTxBuffer.Format(KStringFormatString,&aCommand);
+ iIo->Write(this,iTxBuffer);
+ iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
+ }
+
+void CATBase::Write(const TDesC8& aCommand,TInt aTimeOut,TInt aValue)
+ {
+ iTxBuffer.Format(KStringAndIntegerFormatString,&aCommand,aValue);
+ iIo->Write(this,iTxBuffer);
+ iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
+ }
+
+void CATBase::Write(const TInt aTimeOut)
+{
+ iIo->Write(this,iTxBuffer);
+ iIo->SetTimeOut(this,aTimeOut * KOneSecondPause);
+}
+
+void CATBase::WriteExpectingResults(const TDesC8& aCommand,TInt aTimeOut)
+ {
+ iIo->ClearBuffer();
+ Write(aCommand,aTimeOut);
+ }
+
+void CATBase::AppendWildCardChar(TDes8& aString)
+//
+// A utility function to append a '*' to aString if there's not one already there
+//
+ {
+ _LIT8(KAsterisk,"*");
+ if(aString.Right(1)!=KAsterisk)
+ aString.Append(KAsterisk);
+ }
+
+void CATBase::AddCmsErrorExpectString()
+//
+// Add the "+CMS ERROR:" expect string
+//
+ {
+ iCmsExpectString=iIo->AddExpectString(this,KCmsErrorString);
+ LOGTEXT(_L8("Added \"+CMS ERROR:\" string."));
+ }
+
+void CATBase::RemoveCmsErrorExpectString()
+//
+// Remove the "+CMS ERROR:" expect string
+//
+ {
+ iIo->RemoveExpectString(iCmsExpectString);
+ iCmsExpectString=NULL;
+ LOGTEXT(_L8("Removed \"+CMS ERROR:\" string."));
+ }
+
+CTelObject* CATBase::Owner()
+ {
+ return iTelObject;
+ }
+
+TCallInfoTSY* CATBase::CallInfo()
+ {
+ return iCallInfo;
+ }
+
+//
+// CATCommands class
+//
+CATCommands::CATCommands(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit, CPhoneGlobals* aPhoneGlobals)
+ : CATBase(aIo,aTelObject,aPhoneGlobals), iInit(aInit)
+ {}
+
+void CATCommands::ConstructL()
+ {
+ iATSetToOnlineCommandMode=CATSetToOnlineCommandMode::NewL(iIo,iTelObject,iPhoneGlobals);
+ }
+
+CATCommands::~CATCommands()
+ {
+ delete iATSetToOnlineCommandMode;
+ }
+
+void CATCommands::ExecuteCommand(TTsyReqHandle aTsyReqHandle, TAny* aParams)
+//
+// Ensures that phone is initialised and not in on-line data mode
+//
+ {
+ if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneNotInitialised)
+ {
+ iInit->StartInit(this,aTsyReqHandle,aParams);
+ }
+ else if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineData)
+ {
+ iATSetToOnlineCommandMode->StartEscapeSequence(this,aTsyReqHandle,aParams);
+ }
+ else
+ {
+ if (iPhoneGlobals->iEventSignalActive)
+ {
+ // Make sure request only completed if we have a valid request handle
+ // Signal that request could not be executed
+ if (aTsyReqHandle)
+ iTelObject->ReqCompleted(aTsyReqHandle, KErrInUse);
+ }
+ else
+ {
+ iPhoneGlobals->iEventSignalActive = ETrue;
+ Start(aTsyReqHandle, aParams);
+ }
+ }
+ }
+
+void CATCommands::ExecuteCommand(TTsyReqHandle aTsyReqHandle, TAny* aParams,TCallInfoTSY* aCallInfo)
+//
+// Overloaded function for CCallHayes-originated commands, so that the status can be
+// changed for CCallHayes->iCallInfo
+//
+ {
+ iCallInfo = aCallInfo;
+ ExecuteCommand(aTsyReqHandle,aParams);
+ }
+
+void CATCommands::CancelCommand(TTsyReqHandle aTsyReqHandle)
+ {
+ if(iInit->CheckActiveReqHandle(aTsyReqHandle))
+ {
+ iInit->StopInit(aTsyReqHandle);
+ }
+ else if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineData)
+ {
+ iATSetToOnlineCommandMode->StopEscapeSequence(aTsyReqHandle);
+ }
+ else
+ {
+ Stop(aTsyReqHandle);
+ }
+ }
+
+void CATCommands::Complete(TInt aError,TEventSource /*aSource*/)
+//
+// Should be called by all Complete()'s before ReqCompleted()
+//
+ {
+ LOGTEXT(_L8("CATCommands::Complete called"));
+
+ if (aError==KErrTimedOut)
+ {
+ LOGTEXT(_L8("CATCommands::Complete KErrTimedOut error, setting EPhoneNotIntialised"));
+ iPhoneGlobals->iPhoneStatus.iInitStatus = EPhoneNotInitialised;
+ }
+
+ // Clear the flow control flag to show no AT commands are writing to the
+ // serial port.
+ iPhoneGlobals->iEventSignalActive = EFalse;
+
+ // Allow the CReceiveSmsQueue object to read PDUs from the phones memory, if needed
+ if(iPhoneGlobals->iReceiveSmsQueuePtr)
+ iPhoneGlobals->iReceiveSmsQueuePtr->ReadPDUFromPhone();
+
+ // Check the flow control flag, as the previous lines may have started off a
+ // AT command.
+ // If the flow control is clear then allow the Check ForChangeOfNetwork to have
+ // a go at updating its status and writing to the serial port.
+ if (!(iPhoneGlobals->iEventSignalActive))
+ iPhoneGlobals->CheckForChangeOfNetwork();
+ }