telephonyserverplugins/multimodetsy/hayes/ATBASE.CPP
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/multimodetsy/hayes/ATBASE.CPP	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +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();
+	}