telephonyserverplugins/multimodetsy/Multimode/mnetwork.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/telephonyserverplugins/multimodetsy/Multimode/mnetwork.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/multimodetsy/Multimode/mnetwork.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,935 +1,935 @@
-// Copyright (c) 2000-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:
-// \file mnetwork.cpp
-// Basic GSM Network and Operator information Implementation file.
-// This file contains the implementation of the CATNetworkInfo, CATDetectNetwork,
-// CNotifyNetworkRegistrationStatusChange and CCurrentNetworkChangedNotify classes.
-// Find the current Network Operator in Numeric, Long and Short formats.
-// NB - Some phones do not fully support all the formats, if any. The commands are 
-// sent in sequence starting with the query command (AT+COPS?). All the phones currently
-// supported implement this command. Valid responses are set in the TMobilePhoneLocationAreaV1
-// and the TMobilePhoneNetworkInfoV1 structures and the Network's status is set to Current.
-// 
-//
-
-#include <et_phone.h>
-#include "mnetwork.h"
-#include "mSLOGGER.H"
-#include "ATIO.H"
-#include "Matstd.h"
-#include "mPHONE.H"
-
-const TInt KSettlingPause=1;	//< This pause is used at the end of the network information queries.  The Nokia 8210 has been shown to require this, if it is not to error the next command.
-
-_LIT8(KSetAndReadOperatorCommandNumeric, "AT+COPS=3,2;+COPS?\r");
-_LIT8(KSetAndReadOperatorCommandShort, "AT+COPS=3,1;+COPS?\r");
-_LIT8(KSetAndReadOperatorCommandLong, "AT+COPS=3,0;+COPS?\r");
-
-_LIT8(KGetCurrentOperatorCommand, "AT+COPS?\r");
-_LIT8(KOperatorResponse,"+COPS:");
-
-_LIT8(KDetectNetworkCommand,"AT+COPS=?");
-
-
-static TInt NetworkIdL(const TDesC8& aCode,
-					   RMobilePhone::TMobilePhoneNetworkCountryCode& aCountryCode, 
-					   RMobilePhone::TMobilePhoneNetworkIdentity& aNetworkIdentity)
-	{
-/**
- * Utility function to translate the 5 digit ASCII network identification returned by the ME
- * into Mobile Country Code (aCountryCode) and a Mobile Network Code (aNetworkIdentity) strings.
- * Tbe format returned by the ME is XXXYY, where XXX represents the Mobile Country Code and YY
- * represents the Mobile Network Code.
- */
-	if (aCode.Length()!=5)
-		{
-		return KErrGeneral;
-		}
-	
-	aCountryCode.SetLength(3);
-	aCountryCode[0] = aCode[0];
-	aCountryCode[1] = aCode[1];
-	aCountryCode[2] = aCode[2];
-
-	aNetworkIdentity.SetLength(2);
-	aNetworkIdentity[0] = aCode[3];
-	aNetworkIdentity[1] = aCode[4];
-	return KErrNone;
-	}
-
-
-CATNetworkInfo* CATNetworkInfo::NewL(CATIO* aIo,CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
-/**
- * Standard two-phase constructor.
- */
-	{
-	CATNetworkInfo* netInfo = new(ELeave) CATNetworkInfo(aIo, aTelObject, aInit, aPhoneGlobals);
-	CleanupStack::PushL(netInfo);
-	netInfo->ConstructL();
-	CleanupStack::Pop();
-	return netInfo;
-	}
-
-CATNetworkInfo::CATNetworkInfo(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
-	: CATCommands(aIo,aTelObject,aInit,aPhoneGlobals)
-	,iPhoneGlobals(aPhoneGlobals)
-	{}
-
-CATNetworkInfo::~CATNetworkInfo()
-/**
- * Standard Destructor.
- * Note the NULLing of the iATNetworkInfo pointer.  This should prevent any unwanted calling
- * of this function from the "end of command" sequence after the class' destruction.
- */
-	{
-	iIo->RemoveExpectStrings(this);
-	iPhoneGlobals->iATNetworkInfo=NULL;
-	}
-
-void CATNetworkInfo::Start(TTsyReqHandle aTsyReqHandle,TAny* aParam)
-/**
- * This is the standard entry point for retrieving the Network Information.
- */
-	{
-	LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tStarting Operator Info."));
-	iReqHandle = aTsyReqHandle;
-	if (aParam!=NULL)
-		{
-		TTsyNetworkInfo* info = static_cast<TTsyNetworkInfo*>(aParam);
-		iNetworkInfo.iNetworkInfoPckg = info->iNetworkInfoPckg;
-		iNetworkInfo.iArea = info->iArea;
-		}
-
-	//
-	// This object is not always started thru the CATBase::ExecuteCommand
-	// So we sometimes have to manually control the flow control of iEventSignalActive
-	iPhoneGlobals->iEventSignalActive = ETrue;
-	iCancelled=EFalse;
-
-	if (iReqHandle==0)
-		iTelObject->FlowControlSuspend();
-	StartGetOperator();
-	}
-
-void CATNetworkInfo::CheckOperator()
-/**
- * This function is called whenever an EventSignal Completes.  It is a second entry point for the command.
- * It checks CPhoneGlobals iPhoneStatus.iNetworkChanged and calls this function if it detects that the
- * networking information has changed and therefore the CPhoneGlobals data may be out of date and needs
- * to be refreshed.
- */
-	{
-	Start(0,0);
-	}
-
-
-void CATNetworkInfo::EventSignal(TEventSource aSource)
-/**
- * This function contains the state machine for the command.  The states flow consecutively and are
- * described below.
- * 
- * \par EATGetCurrentOperatorWriteComplete
- * Wait for the "AT+COPS?" write to complete
- *
- * \par EATGetCurrentOperatorReadComplete
- * Parse the "AT+COPS?" response.  If it gets an "ERROR" back it assume that no COPS commands are
- * supported, so complete the request with an error.  If it is supported, parse the result and proceed
- * to retrieve the numeric network code with "AT+COPS=3,2;+COPS?"
- *
- * \par EATNumericOperatorWaitForWriteComplete
- * Wait for the "AT+COPS=3,2;+COPS?" to complete
- *
- * \par EATSetNumericOperatorReadComplete
- * Parse the numeric network code if available.  Proceed to retrieve the short network code with
- * "AT+COPS=3,1;+COPS?".
- *
- * \par EATShortOperatorWaitForWriteComplete
- * Wait for the "AT+COPS=3,1;+COPS?" write to complete.
- *
- * \par EATSetShortOperatorReadComplete
- * Parse the short network name if available.  Proceed to retrieve the long network name with
- * "AT+COPS=3,0;+COPS?".
- *
- * \par EATLongOperatorWaitForWriteComplete
- * Wait for the "AT+COPS=3,0;+COPS?" write to complete.
- *
- * \par EATSetLongOperatorReadComplete
- * Parse the long network name if available.  Proceed to complete the request. 
- * Check for outstanding current network operator notifications at this point. 
- *
- * \par EATWaitForStopState
- * This state is used when stopping the state machine to ensure that a pending modem response has been
- * retrieved before freeing up the Multimode TSY to send more commands.  Prematurely stopping the state machine
- * is usually forced by a client cancel request.
- *
- * \par EATWaitForSettlingTimeout
- * This state is used to provide a pause at the end of the network information queries. The Nokia 8210
- * has been shown to require this, if it is not to arbitrarily error the next command.
- */
-	{
-	if ((aSource==ETimeOutCompletion)&&(iState!=EATWaitForSettlingTimeout))
-		{
-		LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tTimeout Error during Operator read"));
-		RemoveStdExpectStrings();
-		Complete(KErrTimedOut,aSource);
-		return;
-		}
-
-	switch(iState)
-		{
-		case EATGetCurrentOperatorWriteComplete:
-			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			StandardWriteCompletionHandler(aSource, 5);
-			iState=EATGetCurrentOperatorReadComplete;
-			}
-			break;
-
-		case EATGetCurrentOperatorReadComplete:
-			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			TInt ret(ValidateExpectString());
-			RemoveStdExpectStrings();
-			if (ret != KErrNone)
-				{
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t+COPS? not supported"));
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tSet Operator Command not supported")); // An assumption
-				Complete(ret, aSource);	// No point in sending the Set Command.
-				}
-			else if (iCancelled)
-				{
-				Complete(KErrCancel, aSource);	// Cancel state machine in safe place
-				}
-			else
-				{
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t+COPS? supported"));
-				TRAPD(ret,ParseOperatorResponseL());
-				if (ret != KErrNone)
-					{
-					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS?"));
-					}								
-				iTxBuffer.Copy(KSetAndReadOperatorCommandNumeric); // AT+COPS=3,2;+COPS?
-				iIo->Write(this, iTxBuffer);
-				iIo->SetTimeOut(this, 5000);
-				iState=EATNumericOperatorWaitForWriteComplete;
-				}
-			}
-			break;		
-
-		case EATNumericOperatorWaitForWriteComplete:
-			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			StandardWriteCompletionHandler(aSource, 5);
-			iState=EATSetNumericOperatorReadComplete;
-			}
-			break;
-
-		case EATSetNumericOperatorReadComplete:
-			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			TInt ret(ValidateExpectString());
-			RemoveStdExpectStrings();
-			if (iCancelled)
-				{
-				Complete(KErrCancel, aSource);	// Cancel state machine in safe place
-				return;
-				}
-			else if (ret != KErrNone) 
-				{
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tAT+COPS=3,2 not supported"));				
-				}				
-			else	// Set Operator Command was successful, Read the Current Operator
-				{
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t	AT+COPS=3,2 supported"));
-				TRAPD(ret,ParseOperatorResponseL());
-				if (ret != KErrNone)
-					{
-					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS=3,2"));
-					}					
-				}
-			iTxBuffer.Copy(KSetAndReadOperatorCommandShort); // AT+COPS=3,1;+COPS?
-			iIo->Write(this, iTxBuffer);
-			iIo->SetTimeOut(this, 5000);
-			iState=EATShortOperatorWaitForWriteComplete; 
-			}
-			break;
-
-		case EATShortOperatorWaitForWriteComplete:
-			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			StandardWriteCompletionHandler(aSource, 5);
-			iState=EATSetShortOperatorReadComplete;
-			}
-			break;
-
-		case EATSetShortOperatorReadComplete:
-			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
-				{
-				iIo->WriteAndTimerCancel(this);
-				TInt ret(ValidateExpectString());
-				RemoveStdExpectStrings();
-				if (iCancelled)
-					{
-					Complete(KErrCancel, aSource);	// Cancel state machine in safe place
-					return;
-					}
-				else if (ret != KErrNone)
-					{
-					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tAT+COPS=3,1 not supported"));					
-					}
-				else// Set Operator Command was successful, Read the Current Operator
-					{	
-					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t	AT+COPS=3,1 supported"));
-					TRAPD(ret,ParseOperatorResponseL());
-					if (ret != KErrNone)
-						{
-						LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS=3,1"));
-						}						
-					}
-				iTxBuffer.Copy(KSetAndReadOperatorCommandLong); // AT+COPS=3,0;+COPS?
-				iIo->Write(this, iTxBuffer);
-				iIo->SetTimeOut(this, 5000);
-				iState=EATLongOperatorWaitForWriteComplete; 
-				}
-			break;
-
-		case EATLongOperatorWaitForWriteComplete:
-			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			StandardWriteCompletionHandler(aSource, 5);
-			iState=EATSetLongOperatorReadComplete;
-			}
-			break;
-
-		case EATSetLongOperatorReadComplete:
-			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			TInt ret(ValidateExpectString());
-			RemoveStdExpectStrings();
-			if (ret != KErrNone)
-				{
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t+COPS=3,0 not supported"));
-				}
-			else	// Set Operator cmd was successful, Read the Current Operator
-				{
-				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tAT+COPS=3,0 supported"));
-				TRAPD(ret,ParseOperatorResponseL());
-				if (ret != KErrNone)
-					{
-					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS=3,0"));
-					}						
-				}
-
-			// Check outstanding current network operator notifications
-			iPhoneGlobals->iNotificationStore->CheckNotification(iTelObject,ECurrentNetworkChanged);
-
-			iIo->SetTimeOut(this, KSettlingPause*1000);
-			iState=EATWaitForSettlingTimeout;
-			}
-			break;
-
-		case EATWaitForSettlingTimeout:
-			__ASSERT_ALWAYS((aSource==ETimeOutCompletion),Panic(EATCommand_IllegalCompletionWriteExpected));
-			Complete(KErrNone,aSource);
-			break;
-	
-		case EATWaitForStopState:
-			__ASSERT_ALWAYS(aSource==EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected));
-			{
-			iIo->WriteAndTimerCancel(this);
-			Complete(KErrCancel, aSource);
-			}
-			break;
-
-		default:
-			break;
-		}//switch
-	}//EventSignal
-
-void CATNetworkInfo::Stop(TTsyReqHandle aTsyReqHandle)
-/**
- * This function is used to prematurely stop the state machine.  This would usually occur following a
- * client cancel request.
- */
-{
-	__ASSERT_ALWAYS(aTsyReqHandle == iReqHandle, Panic(EIllegalTsyReqHandle));
-	LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tCancel called."));
-	iCancelled=ETrue;
-}
-
-
-void CATNetworkInfo::Complete(TInt aError,TEventSource aSource)
-/**
- * This function completes the client's request.
- */
-	{
-	iIo->WriteAndTimerCancel(this);
-	iIo->RemoveExpectStrings(this);
-	iOKExpectString = NULL;
-	iErrorExpectString = NULL;
-	if (aSource==EWriteCompletion)
-		iIo->Read();
-	iState = EATNotInProgress;
-	LOGTEXT2(_L8("MMTsy:CATNetworkInfo:\tCATNetworkInfo completed with error code : %d"), aError);
-	//
-	// BEWARE: The next command will be started from inside ReqCompleted or FlowControlResume
-	// 
-	//
-	// This object is not always started thru the CATBase::ExecuteCommand
-	// So we sometimes have to manually control the flow control of iEventSignalActive
-	iPhoneGlobals->iEventSignalActive = EFalse;
-
-	if (iReqHandle)
-		{
-		// Explicit call from a client
-		if (aError==KErrNone)
-			{
-			GetCurrentNetworkInfo(&iNetworkInfo); 
-			}
-		iTelObject->ReqCompleted(iReqHandle, aError);
-		}
-	else
-		{
-		// CheckOperator() call from CATCommands::Complete
-		iTelObject->FlowControlResume();
-		}
-	CATCommands::Complete(aError,aSource);
-	}
-
-void CATNetworkInfo::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus)
-/**
- * This function handles I/O errors that may occur during any of the stages of the state machine.
- */
-	{
-	if (iState!=EATNotInProgress)
-		{
-		iIo->WriteAndTimerCancel(this);
-		if (iReqHandle)
-			{
-			iTelObject->ReqCompleted(iReqHandle, aStatus);
-			}
-		else
-			{
-			// CheckOperator() call from CATCommands::Complete
-			iTelObject->FlowControlResume();
-			}
-		iState = EATNotInProgress;
-		}
-	}
-
-void CATNetworkInfo::StartGetOperator()
-/**
- * This function kicks off the state machine by transmitting the first command, "AT+COPS?" and
- * setting the state.
- */
-	{
-	iPhoneGlobals->iPhoneStatus.iNetworkChanged=EFalse;
-	InitializeNetworkInfo();		// Initialize the TNetworkInfo struct that will contain the mobile's responses
-	iTxBuffer.Copy(KGetCurrentOperatorCommand);
-	iIo->Write(this, iTxBuffer);
-	iIo->SetTimeOut(this, 5000);
-	iState=EATGetCurrentOperatorWriteComplete;
-	}
-
-void CATNetworkInfo::InitializeNetworkInfo()
-/**
- * This function is used to initialize (to zero) the network information elements in the CPhoneGlobals
- * structure.
- */
-	{
-	RMobilePhone::TMobilePhoneNetworkInfoV1& networkinfo = iPhoneGlobals->iPhoneStatus.iCurrentNetwork;
-
-	networkinfo.iMode = RMobilePhone::ENetworkModeUnknown;
-	networkinfo.iCountryCode.Zero();		// Unknown, MCC
-	networkinfo.iNetworkId.Zero();			// MNC
-	networkinfo.iCdmaSID.Zero();			// Unused CDMA field
-	networkinfo.iAnalogSID.Zero();			// Unused CDMA field
-	networkinfo.iShortName.Zero();
-	networkinfo.iLongName.Zero();
-	networkinfo.iStatus = RMobilePhone::ENetworkStatusUnknown; 
-	networkinfo.iDisplayTag.Zero();
-	}
-
-void CATNetworkInfo::ParseOperatorResponseL()
-/**
- * This function is used to parse the ME responses to commands to retrieve numeric, short name 
- * or long name network information.  Possible responses are:
- * +COPS: mode, 0, "long format name"
- * +COPS: mode, 1, "short format name"
- * +COPS: mode, 2, "operator ID in hex"
- * +COPS: mode  (no network information available)
- *
- * Relevant information is retrieved and written into the CPhoneGlobals class.
- */
-	{
-	RMobilePhone::TMobilePhoneNetworkInfoV1& networkInfo = iPhoneGlobals->iPhoneStatus.iCurrentNetwork; 
-
-	ParseBufferLC();	// Parse the buffer and create a linked list with the phone's response
-
-	CATParamListEntry* entry;
-	TDblQueIter<CATParamListEntry> iter(iRxResults);
-
-	// The 1st item in the list should be the +COPS: response
-	entry=iter++;
-	if (entry && entry->iResultPtr.MatchF(KOperatorResponse)!=0)
-		User::Leave(KErrGeneral);
-
-	// The next item is the mode (this information is not used)
-	entry=iter++;
-	if (!entry)
-		User::Leave(KErrGeneral);  
-	
-	// The next item should be the format. If there is no network information then this item
-	// would be empty. The network status is consequently updated.
-	entry=iter++;
-	if (!entry)  // Not connected, so the response is "+COPS: 0"
-		networkInfo.iStatus=RMobilePhone::ENetworkStatusUnknown;
-	else	
-		{
-		TInt format=CATParamListEntry::EntryValL(entry);
-		
-		// If the format is available, the network name is the next item in the list 
-		entry=iter++;
-		if (!entry)
-			User::Leave(KErrGeneral);
-		switch (format)
-			{
-		case 0:
-			if((entry->iResultPtr).Length() > networkInfo.iLongName.MaxLength())
-				networkInfo.iLongName.Copy((entry->iResultPtr).Mid(0,networkInfo.iLongName.MaxLength()));			
-			else
-				networkInfo.iLongName.Copy(entry->iResultPtr);
-			break;
-		case 1:
-			if((entry->iResultPtr).Length() > networkInfo.iShortName.MaxLength())
-				networkInfo.iShortName.Copy((entry->iResultPtr).Mid(0,networkInfo.iShortName.MaxLength()));			
-			else 
-				networkInfo.iShortName.Copy(entry->iResultPtr);	
-			break;
-		case 2:
-			User::LeaveIfError(NetworkIdL(entry->iResultPtr,networkInfo.iCountryCode, networkInfo.iNetworkId));
-			break;
-		default:
-			User::Leave(KErrGeneral);
-			break;
-			}
-
-		// We've got an answer, so this must be the current network
-		networkInfo.iStatus=RMobilePhone::ENetworkStatusCurrent;
-		}
-	CleanupStack::PopAndDestroy();
-	}
-
-void CATNetworkInfo::GetCurrentNetworkInfo(CATNetworkInfo::TTsyNetworkInfo* aNetworkInfo)
-/**
- * This function checks to see if the network registration information in CPhoneGlobals is valid,
- * and, if it is, it copies the CPhoneGlobals network information into the waiting client request
- * buffer.
- */
-	{
-	RMobilePhone::TMobilePhoneNetworkInfoV1& networkInfo = (*(aNetworkInfo->iNetworkInfoPckg))();
-	RMobilePhone::TMobilePhoneLocationAreaV1& areaInfo = *(aNetworkInfo->iArea);
-	RMobilePhone::TMobilePhoneRegistrationStatus status = iPhoneGlobals->iPhoneStatus.iRegistrationStatus;
-
-	if (status == RMobilePhone::ERegisteredOnHomeNetwork
-		|| status == RMobilePhone::ERegisteredRoaming
-		|| status == RMobilePhone::ERegistrationUnknown) // AT+CREG? is not supported, but info obtained during initialization is still valid. NickyM
-		{
-		RMobilePhone::TMobilePhoneNetworkInfoV1& info = iPhoneGlobals->iPhoneStatus.iCurrentNetwork;
-		RMobilePhone::TMobilePhoneLocationAreaV1& locationInfo = iPhoneGlobals->iPhoneStatus.iLocationArea;
-
-		networkInfo.iStatus			= info.iStatus;
-		networkInfo.iCountryCode	= info.iCountryCode;	
-		networkInfo.iNetworkId		= info.iNetworkId;
-		networkInfo.iCdmaSID		= info.iCdmaSID;   // for CDMA
-		networkInfo.iAnalogSID		= info.iAnalogSID; // for CDMA
-		networkInfo.iShortName		= info.iShortName;
-		networkInfo.iLongName		= info.iLongName;
-		networkInfo.iDisplayTag		= info.iLongName;		// This TSY handles the display tag as the same as longname
-		networkInfo.iMode			= iPhoneGlobals->iNetworkMode;
-		areaInfo.iAreaKnown			= locationInfo.iAreaKnown;
-		areaInfo.iLocationAreaCode	= locationInfo.iLocationAreaCode;
-		areaInfo.iCellId			= locationInfo.iCellId;
-		}
-	else
-		{
-		networkInfo.iStatus			= RMobilePhone::ENetworkStatusUnknown;
-		networkInfo.iShortName.Zero();			// Should this be .Zero() ?
-		networkInfo.iLongName.Zero();			// Should this be .Zero() ?
-		areaInfo.iAreaKnown			= EFalse;	
-		areaInfo.iLocationAreaCode	= 0;
-		areaInfo.iCellId			= 0;
-
-		}
-	return;
-	}
-
-
-// class CNotifyNetworkRegistrationStatusChange
-
-CNotifyNetworkRegistrationStatusChange* CNotifyNetworkRegistrationStatusChange::NewL(TTsyReqHandle aReqHandle,CTelObject* aTelObject, 
-																					 RMobilePhone::TMobilePhoneRegistrationStatus* aRegStatus)
-	{
-	return new(ELeave) CNotifyNetworkRegistrationStatusChange(aReqHandle,aTelObject,aRegStatus);
-	}
-
-CNotifyNetworkRegistrationStatusChange::CNotifyNetworkRegistrationStatusChange(TTsyReqHandle aReqHandle,CTelObject* aTelObject, 
-																			   RMobilePhone::TMobilePhoneRegistrationStatus* aRegStatus)
-	: CNotifyBase(aReqHandle,aTelObject)
-	{
-	iRegStatus = aRegStatus;
-	}
-
-CNotifyNetworkRegistrationStatusChange::~CNotifyNetworkRegistrationStatusChange()
-	{}
-
-TBool CNotifyNetworkRegistrationStatusChange::CheckAndCompleteNotification(CTelObject* aTelObject, TEvent aEvent, TEvent /*aLastEvent*/)
-/**
- * This function completes a Registration status Notification.
- */
-	{	
-	if (aEvent!=ERegistrationStatusChanged)
-		return EFalse;
-
-	LOGTEXT2(_L8("Event %d:\tRegistration Status Changed Notification completed"),aEvent);
-	*iRegStatus = reinterpret_cast<CPhoneMobile*>(aTelObject)->RegistrationStatus();
-	iTelObject->ReqCompleted(iReqHandle,KErrNone);
-	return ETrue;
-	}
-
-// class CCurrentNetworkChangedNotify
-
-CNotifyCurrentNetworkChange* CNotifyCurrentNetworkChange::NewL(TTsyReqHandle aReqHandle,CTelObject* aTelObject,TInt* aInfo)
-	{	
-	return new(ELeave) CNotifyCurrentNetworkChange(aReqHandle,aTelObject,aInfo);
-	}
-
-CNotifyCurrentNetworkChange::CNotifyCurrentNetworkChange(TTsyReqHandle aReqHandle,CTelObject* aTelObject,TInt* aInfo)
-	: CNotifyBase(aReqHandle,aTelObject)
-	{
-	CATNetworkInfo::TTsyNetworkInfo* info = reinterpret_cast<CATNetworkInfo::TTsyNetworkInfo*>(aInfo);
-	iNetworkInfo.iNetworkInfoPckg = info->iNetworkInfoPckg;
-	iNetworkInfo.iArea = info->iArea;
-	}
-
-CNotifyCurrentNetworkChange::~CNotifyCurrentNetworkChange()
-	{}
-
-TBool CNotifyCurrentNetworkChange::CheckAndCompleteNotification(CTelObject* aTelObject,TEvent aEvent,TEvent /*aLastEvent*/)
-/**
- * This function completes a Current Network Change Notification.
- */
-	{	
-	if (aEvent!=ECurrentNetworkChanged)
-		return EFalse; 
-
-	LOGTEXT2(_L8("Event %d:\tCurrent Network Changed Notification completed"),aEvent);
-//	REINTERPRET_CAST(CPhoneMobile*,aTelObject)->CurrentNetworkInfo(&iNetworkInfo);
-	reinterpret_cast<CPhoneMobile*>(aTelObject)->CurrentNetworkInfo(&iNetworkInfo);
-	iTelObject->ReqCompleted(iReqHandle,KErrNone);
-	return ETrue;
-	}
-
-// Class CATDetectNetwork
-//
-// Detect all available networks.
-
-CATDetectNetwork::CATDetectNetwork(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
-	: CATCommands(aIo,aTelObject,aInit,aPhoneGlobals)
-	{}
-
-CATDetectNetwork* CATDetectNetwork::NewL(CATIO* aIo,CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
-/**
- * Standard 2 phase constructor.
- */
-	{
-	CATDetectNetwork* self = new(ELeave) CATDetectNetwork(aIo, aTelObject, aInit, aPhoneGlobals);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop();
-	return self;
-	}
-
-CATDetectNetwork::~CATDetectNetwork()
-/**
- * Destructor.
- */
-	{
-	iIo->RemoveExpectStrings(this);
-	}
-
-void CATDetectNetwork::Start(TTsyReqHandle aTsyReqHandle,TAny* aParam)
-/**
- * This is the standard entry point for retrieving the detected Operator Information.
- */
-	{
-	LOGTEXT(_L8("MMTsy:\tCATDetectNetwork:\tStarting Network detection"));
-	if (aParam != NULL)
-		{
-		TTsyDetectedNetworks*  info = static_cast<TTsyDetectedNetworks* >(aParam);
-		iDetectedNetworks.iBufSize = info->iBufSize;
-		iDetectedNetworks.iBufPtr = info->iBufPtr;
-		}
-
-	iReqHandle = aTsyReqHandle;
-
-	WriteExpectingResults(KDetectNetworkCommand, 3);
-	__ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL,Panic(EGeneral));
-	iState=EATDetectWaitForWriteComplete;
-	}
-
-void CATDetectNetwork::EventSignal(TEventSource aSource)
-/**
- * This function contains the state machine for the command.  The states flow consecutively and are
- * described below.
- * 
- * \par EATDetectWaitForWriteComplete
- * Wait for the "AT+COPS=?" write to complete
- *
- * \par EATDetectReadComplete
- * Reads the Modem's response to the AT+COPS=? command.  If it gets an "ERROR" back it resets the 
- * timer and sets a new state (EATDetectExtendedReadComplete) and waits for another response.
- *
- * \par EATDetectExtendedReadComplete
- * Reads the phone's response to the AT+COPS=? command and parses the response. Completes the
- * request.
- *
- * \par EATWaitForStopState
- * This state is used when stopping the state machine to ensure that a pending modem response has been
- * retrieved before freeing up the Multimode TSY to send more commands.  Prematurely stopping the state machine
- * is usually forced by a client cancel request.
- */
-	{
-	if (aSource==ETimeOutCompletion)
-		{
-		if (iState!=EATDetectExtendedReadComplete)
-			{
-			LOGTEXT(_L8("MmTsy:\tCATDetectNetwork:\tTimeout Error during Network Detect read"));
-			RemoveStdExpectStrings();
-			Complete(KErrTimedOut,aSource);
-			return;
-			}
-		else
-			{
-			// the phone really does not support +COPS=?, so report that error
-			RemoveStdExpectStrings();
-			Complete(KErrNotSupported,EReadCompletion);
-			return;
-			}
-		}
-
-	switch(iState)
-		{
-	case EATDetectWaitForWriteComplete:
-		__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
-		{
-		iIo->WriteAndTimerCancel(this);
-		iIo->SetTimeOut(this,45 * KOneSecondPause); // Some phones take a long time to detect all the networks
-		AddStdExpectStrings();
-		iState=EATDetectReadComplete;
-		}
-		break;
-
-	case EATDetectReadComplete:
-		__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
-		iIo->WriteAndTimerCancel(this);
-		if (iIo->FoundChatString()==iErrorExpectString)
-			{
-			LOGTEXT(_L8("Modem returned ERROR - waiting for further response"));
-			iIo->ClearCurrentLine();
-			iIo->SetTimeOut(this,45 * KOneSecondPause);
-			iState = EATDetectExtendedReadComplete;
-			break;
-			}
-		// fall through ...
-
-	case EATDetectExtendedReadComplete:
-		__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
-		iIo->WriteAndTimerCancel(this);
-		{
-		TInt ret(ValidateExpectString());
-		RemoveStdExpectStrings();
-		if (ret==KErrNone)
-			TRAP(ret,ParseResponseL());
-		Complete(ret,aSource); // The return value is set in the Complete methode
-		}
-		break;
-
-	case EATWaitForStopState:
-		__ASSERT_ALWAYS(aSource==EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected));
-		{
-		iIo->WriteAndTimerCancel(this);
-		Complete(KErrCancel, aSource);
-		}
-		break;
-
-	default:
-		break;
-		}//switch
-	}//EventSignal
-
-void CATDetectNetwork::Stop(TTsyReqHandle aTsyReqHandle)
-/**
- * This function is used to prematurely stop the state machine.  This would usually occur following a
- * client cancel request.
- */
-	{
-	__ASSERT_ALWAYS(aTsyReqHandle == iReqHandle, Panic(EIllegalTsyReqHandle));
-	LOGTEXT(_L8("MMTsy:\tCATDetectNetwork:\tCancel called."));
-	switch(iState)
-		{
-		case EATNotInProgress:
-		case EATDetectWaitForWriteComplete:
-			{
-			LOGTEXT2(_L8("Current state TSY is cancelling from %d"), iState);
-			Complete(KErrCancel, EReadCompletion);
-			}
-			break;
-
-		default:
-			{
-			LOGTEXT(_L8("MmTsy:\tCATDetectNetwork:\tStop, now waiting for expected modem response"));
-			AddStdExpectStrings();
-			iIo->SetTimeOut(this);
-			iState = EATWaitForStopState;
-			}
-			break;
-		}
-	}
-
-
-void CATDetectNetwork::Complete(TInt aError,TEventSource aSource)
-/**
- * This function completes the client request.
- */
-	{
-	iState = EATNotInProgress;
-	iIo->WriteAndTimerCancel(this);
-	iIo->RemoveExpectStrings(this);
-	iOKExpectString = NULL;
-	iErrorExpectString = NULL;
-	CATCommands::Complete(aError,aSource);
-
-	LOGTEXT2(_L8("MMTsy:CATDetectNetwork:\tCATDetectNetwork completed with error code : %d"), aError);
-	if (aError==KErrCancel)
-		{
-		CPhoneMobile* phone = static_cast<CPhoneMobile*>(iTelObject);
-		phone->CompleteDetectedNetworksCancel(iReqHandle);
-		}
-	else
-		iTelObject->ReqCompleted(iReqHandle, aError);
-	}
-
-void CATDetectNetwork::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus)
-/**
- * This function handles I/O errors that may occur during any of the stages of the state machine.
- */
-	{
-	if (iState!=EATNotInProgress)
-		{
-		iIo->WriteAndTimerCancel(this);
-		iState = EATNotInProgress;
-		iTelObject->ReqCompleted(iReqHandle, aStatus);
-		}
-	}
-
-void CATDetectNetwork::ParseResponseL()
-/**
- * This function parses the phone's response to the Detect Networks command.
- */
-	{
-	// should be
-	//
-	// +COPS: (status,"longname","shortname",code),... ,,(list),(list)
-	//
-	// but SH888 gives
-	//
-	// +COPS: (status,"longname","shortname",code)<cr><lf>
-	// +COPS: ...
-	//
-
-	CMobilePhoneNetworkList* list=CMobilePhoneNetworkList::NewL();
-	CleanupStack::PushL(list);
-
-	ParseBufferLC();
-
-	RMobilePhone::TMobilePhoneNetworkInfoV1 info;	
-	// This TSY only supports GSM mode so we can hardcode this
-	info.iMode=RMobilePhone::ENetworkModeGsm;
-	TDblQueIter<CATParamListEntry> iter(iRxResults);
-	CATParamListEntry* entry=iter++;
-	if (entry)
-		{
-		if (entry->iResultPtr!=KOperatorResponse)
-			User::Leave(KErrGeneral);
-		//
-		entry=iter++;
-		if (!entry)
-			User::Leave(KErrGeneral);
-		for (;;)
-			{
-			info.iStatus = RMobilePhone::TMobilePhoneNetworkStatus(CATParamListEntry::EntryValL(entry));
-			//
-			entry=iter++;
-			if (!entry)
-				User::Leave(KErrGeneral);
-			info.iLongName.Copy(entry->iResultPtr);		
-			//
-			entry=iter++;
-			if (!entry)
-				User::Leave(KErrGeneral);
-			if((entry->iResultPtr).Length() > info.iShortName.MaxLength())
-				info.iShortName.Copy((entry->iResultPtr).Mid(0,info.iShortName.MaxLength()));			
-			else
-				info.iShortName.Copy(entry->iResultPtr);
-			//
-			entry=iter++;
-			if (!entry)
-				User::Leave(KErrGeneral);
-			User::LeaveIfError(NetworkIdL(entry->iResultPtr,info.iCountryCode, info.iNetworkId));  // MNC and MCC	
-			
-			list->AddEntryL(info); 
-		
-			entry=iter++;
-			if (!entry)
-				break;
-			if (entry->iResultPtr.Length()==0)
-				break;
-			if (entry->iResultPtr!=KOperatorResponse)
-				continue;
-			entry=iter++;
-			if (!entry)
-				break;
-			}
-		}
-
-	CleanupStack::PopAndDestroy();			// results
-
-	*(iDetectedNetworks.iBufPtr) = list->StoreLC();	 // Stream the list to optimice the size of it.
-	*(iDetectedNetworks.iBufSize) = (*(iDetectedNetworks.iBufPtr))->Size(); // Store the size of the streamed list to be passed back to the client.   
-
-	CleanupStack::Pop();					// pop the CBufBase allocated by StoreLC
-	CleanupStack::PopAndDestroy();			// pop AND detroy the list.
-
-	} // End of ParseResponseL()  
-
-
-
+// Copyright (c) 2000-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:
+// \file mnetwork.cpp
+// Basic GSM Network and Operator information Implementation file.
+// This file contains the implementation of the CATNetworkInfo, CATDetectNetwork,
+// CNotifyNetworkRegistrationStatusChange and CCurrentNetworkChangedNotify classes.
+// Find the current Network Operator in Numeric, Long and Short formats.
+// NB - Some phones do not fully support all the formats, if any. The commands are 
+// sent in sequence starting with the query command (AT+COPS?). All the phones currently
+// supported implement this command. Valid responses are set in the TMobilePhoneLocationAreaV1
+// and the TMobilePhoneNetworkInfoV1 structures and the Network's status is set to Current.
+// 
+//
+
+#include <et_phone.h>
+#include "mnetwork.h"
+#include "mSLOGGER.H"
+#include "ATIO.H"
+#include "Matstd.h"
+#include "mPHONE.H"
+
+const TInt KSettlingPause=1;	//< This pause is used at the end of the network information queries.  The Nokia 8210 has been shown to require this, if it is not to error the next command.
+
+_LIT8(KSetAndReadOperatorCommandNumeric, "AT+COPS=3,2;+COPS?\r");
+_LIT8(KSetAndReadOperatorCommandShort, "AT+COPS=3,1;+COPS?\r");
+_LIT8(KSetAndReadOperatorCommandLong, "AT+COPS=3,0;+COPS?\r");
+
+_LIT8(KGetCurrentOperatorCommand, "AT+COPS?\r");
+_LIT8(KOperatorResponse,"+COPS:");
+
+_LIT8(KDetectNetworkCommand,"AT+COPS=?");
+
+
+static TInt NetworkIdL(const TDesC8& aCode,
+					   RMobilePhone::TMobilePhoneNetworkCountryCode& aCountryCode, 
+					   RMobilePhone::TMobilePhoneNetworkIdentity& aNetworkIdentity)
+	{
+/**
+ * Utility function to translate the 5 digit ASCII network identification returned by the ME
+ * into Mobile Country Code (aCountryCode) and a Mobile Network Code (aNetworkIdentity) strings.
+ * Tbe format returned by the ME is XXXYY, where XXX represents the Mobile Country Code and YY
+ * represents the Mobile Network Code.
+ */
+	if (aCode.Length()!=5)
+		{
+		return KErrGeneral;
+		}
+	
+	aCountryCode.SetLength(3);
+	aCountryCode[0] = aCode[0];
+	aCountryCode[1] = aCode[1];
+	aCountryCode[2] = aCode[2];
+
+	aNetworkIdentity.SetLength(2);
+	aNetworkIdentity[0] = aCode[3];
+	aNetworkIdentity[1] = aCode[4];
+	return KErrNone;
+	}
+
+
+CATNetworkInfo* CATNetworkInfo::NewL(CATIO* aIo,CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+/**
+ * Standard two-phase constructor.
+ */
+	{
+	CATNetworkInfo* netInfo = new(ELeave) CATNetworkInfo(aIo, aTelObject, aInit, aPhoneGlobals);
+	CleanupStack::PushL(netInfo);
+	netInfo->ConstructL();
+	CleanupStack::Pop();
+	return netInfo;
+	}
+
+CATNetworkInfo::CATNetworkInfo(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+	: CATCommands(aIo,aTelObject,aInit,aPhoneGlobals)
+	,iPhoneGlobals(aPhoneGlobals)
+	{}
+
+CATNetworkInfo::~CATNetworkInfo()
+/**
+ * Standard Destructor.
+ * Note the NULLing of the iATNetworkInfo pointer.  This should prevent any unwanted calling
+ * of this function from the "end of command" sequence after the class' destruction.
+ */
+	{
+	iIo->RemoveExpectStrings(this);
+	iPhoneGlobals->iATNetworkInfo=NULL;
+	}
+
+void CATNetworkInfo::Start(TTsyReqHandle aTsyReqHandle,TAny* aParam)
+/**
+ * This is the standard entry point for retrieving the Network Information.
+ */
+	{
+	LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tStarting Operator Info."));
+	iReqHandle = aTsyReqHandle;
+	if (aParam!=NULL)
+		{
+		TTsyNetworkInfo* info = static_cast<TTsyNetworkInfo*>(aParam);
+		iNetworkInfo.iNetworkInfoPckg = info->iNetworkInfoPckg;
+		iNetworkInfo.iArea = info->iArea;
+		}
+
+	//
+	// This object is not always started thru the CATBase::ExecuteCommand
+	// So we sometimes have to manually control the flow control of iEventSignalActive
+	iPhoneGlobals->iEventSignalActive = ETrue;
+	iCancelled=EFalse;
+
+	if (iReqHandle==0)
+		iTelObject->FlowControlSuspend();
+	StartGetOperator();
+	}
+
+void CATNetworkInfo::CheckOperator()
+/**
+ * This function is called whenever an EventSignal Completes.  It is a second entry point for the command.
+ * It checks CPhoneGlobals iPhoneStatus.iNetworkChanged and calls this function if it detects that the
+ * networking information has changed and therefore the CPhoneGlobals data may be out of date and needs
+ * to be refreshed.
+ */
+	{
+	Start(0,0);
+	}
+
+
+void CATNetworkInfo::EventSignal(TEventSource aSource)
+/**
+ * This function contains the state machine for the command.  The states flow consecutively and are
+ * described below.
+ * 
+ * \par EATGetCurrentOperatorWriteComplete
+ * Wait for the "AT+COPS?" write to complete
+ *
+ * \par EATGetCurrentOperatorReadComplete
+ * Parse the "AT+COPS?" response.  If it gets an "ERROR" back it assume that no COPS commands are
+ * supported, so complete the request with an error.  If it is supported, parse the result and proceed
+ * to retrieve the numeric network code with "AT+COPS=3,2;+COPS?"
+ *
+ * \par EATNumericOperatorWaitForWriteComplete
+ * Wait for the "AT+COPS=3,2;+COPS?" to complete
+ *
+ * \par EATSetNumericOperatorReadComplete
+ * Parse the numeric network code if available.  Proceed to retrieve the short network code with
+ * "AT+COPS=3,1;+COPS?".
+ *
+ * \par EATShortOperatorWaitForWriteComplete
+ * Wait for the "AT+COPS=3,1;+COPS?" write to complete.
+ *
+ * \par EATSetShortOperatorReadComplete
+ * Parse the short network name if available.  Proceed to retrieve the long network name with
+ * "AT+COPS=3,0;+COPS?".
+ *
+ * \par EATLongOperatorWaitForWriteComplete
+ * Wait for the "AT+COPS=3,0;+COPS?" write to complete.
+ *
+ * \par EATSetLongOperatorReadComplete
+ * Parse the long network name if available.  Proceed to complete the request. 
+ * Check for outstanding current network operator notifications at this point. 
+ *
+ * \par EATWaitForStopState
+ * This state is used when stopping the state machine to ensure that a pending modem response has been
+ * retrieved before freeing up the Multimode TSY to send more commands.  Prematurely stopping the state machine
+ * is usually forced by a client cancel request.
+ *
+ * \par EATWaitForSettlingTimeout
+ * This state is used to provide a pause at the end of the network information queries. The Nokia 8210
+ * has been shown to require this, if it is not to arbitrarily error the next command.
+ */
+	{
+	if ((aSource==ETimeOutCompletion)&&(iState!=EATWaitForSettlingTimeout))
+		{
+		LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tTimeout Error during Operator read"));
+		RemoveStdExpectStrings();
+		Complete(KErrTimedOut,aSource);
+		return;
+		}
+
+	switch(iState)
+		{
+		case EATGetCurrentOperatorWriteComplete:
+			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			StandardWriteCompletionHandler(aSource, 5);
+			iState=EATGetCurrentOperatorReadComplete;
+			}
+			break;
+
+		case EATGetCurrentOperatorReadComplete:
+			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			TInt ret(ValidateExpectString());
+			RemoveStdExpectStrings();
+			if (ret != KErrNone)
+				{
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t+COPS? not supported"));
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tSet Operator Command not supported")); // An assumption
+				Complete(ret, aSource);	// No point in sending the Set Command.
+				}
+			else if (iCancelled)
+				{
+				Complete(KErrCancel, aSource);	// Cancel state machine in safe place
+				}
+			else
+				{
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t+COPS? supported"));
+				TRAPD(ret,ParseOperatorResponseL());
+				if (ret != KErrNone)
+					{
+					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS?"));
+					}								
+				iTxBuffer.Copy(KSetAndReadOperatorCommandNumeric); // AT+COPS=3,2;+COPS?
+				iIo->Write(this, iTxBuffer);
+				iIo->SetTimeOut(this, 5000);
+				iState=EATNumericOperatorWaitForWriteComplete;
+				}
+			}
+			break;		
+
+		case EATNumericOperatorWaitForWriteComplete:
+			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			StandardWriteCompletionHandler(aSource, 5);
+			iState=EATSetNumericOperatorReadComplete;
+			}
+			break;
+
+		case EATSetNumericOperatorReadComplete:
+			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			TInt ret(ValidateExpectString());
+			RemoveStdExpectStrings();
+			if (iCancelled)
+				{
+				Complete(KErrCancel, aSource);	// Cancel state machine in safe place
+				return;
+				}
+			else if (ret != KErrNone) 
+				{
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tAT+COPS=3,2 not supported"));				
+				}				
+			else	// Set Operator Command was successful, Read the Current Operator
+				{
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t	AT+COPS=3,2 supported"));
+				TRAPD(ret,ParseOperatorResponseL());
+				if (ret != KErrNone)
+					{
+					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS=3,2"));
+					}					
+				}
+			iTxBuffer.Copy(KSetAndReadOperatorCommandShort); // AT+COPS=3,1;+COPS?
+			iIo->Write(this, iTxBuffer);
+			iIo->SetTimeOut(this, 5000);
+			iState=EATShortOperatorWaitForWriteComplete; 
+			}
+			break;
+
+		case EATShortOperatorWaitForWriteComplete:
+			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			StandardWriteCompletionHandler(aSource, 5);
+			iState=EATSetShortOperatorReadComplete;
+			}
+			break;
+
+		case EATSetShortOperatorReadComplete:
+			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
+				{
+				iIo->WriteAndTimerCancel(this);
+				TInt ret(ValidateExpectString());
+				RemoveStdExpectStrings();
+				if (iCancelled)
+					{
+					Complete(KErrCancel, aSource);	// Cancel state machine in safe place
+					return;
+					}
+				else if (ret != KErrNone)
+					{
+					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tAT+COPS=3,1 not supported"));					
+					}
+				else// Set Operator Command was successful, Read the Current Operator
+					{	
+					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t	AT+COPS=3,1 supported"));
+					TRAPD(ret,ParseOperatorResponseL());
+					if (ret != KErrNone)
+						{
+						LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS=3,1"));
+						}						
+					}
+				iTxBuffer.Copy(KSetAndReadOperatorCommandLong); // AT+COPS=3,0;+COPS?
+				iIo->Write(this, iTxBuffer);
+				iIo->SetTimeOut(this, 5000);
+				iState=EATLongOperatorWaitForWriteComplete; 
+				}
+			break;
+
+		case EATLongOperatorWaitForWriteComplete:
+			__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			StandardWriteCompletionHandler(aSource, 5);
+			iState=EATSetLongOperatorReadComplete;
+			}
+			break;
+
+		case EATSetLongOperatorReadComplete:
+			__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			TInt ret(ValidateExpectString());
+			RemoveStdExpectStrings();
+			if (ret != KErrNone)
+				{
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\t+COPS=3,0 not supported"));
+				}
+			else	// Set Operator cmd was successful, Read the Current Operator
+				{
+				LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tAT+COPS=3,0 supported"));
+				TRAPD(ret,ParseOperatorResponseL());
+				if (ret != KErrNone)
+					{
+					LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tError parsing +COPS=3,0"));
+					}						
+				}
+
+			// Check outstanding current network operator notifications
+			iPhoneGlobals->iNotificationStore->CheckNotification(iTelObject,ECurrentNetworkChanged);
+
+			iIo->SetTimeOut(this, KSettlingPause*1000);
+			iState=EATWaitForSettlingTimeout;
+			}
+			break;
+
+		case EATWaitForSettlingTimeout:
+			__ASSERT_ALWAYS((aSource==ETimeOutCompletion),Panic(EATCommand_IllegalCompletionWriteExpected));
+			Complete(KErrNone,aSource);
+			break;
+	
+		case EATWaitForStopState:
+			__ASSERT_ALWAYS(aSource==EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected));
+			{
+			iIo->WriteAndTimerCancel(this);
+			Complete(KErrCancel, aSource);
+			}
+			break;
+
+		default:
+			break;
+		}//switch
+	}//EventSignal
+
+void CATNetworkInfo::Stop(TTsyReqHandle aTsyReqHandle)
+/**
+ * This function is used to prematurely stop the state machine.  This would usually occur following a
+ * client cancel request.
+ */
+{
+	__ASSERT_ALWAYS(aTsyReqHandle == iReqHandle, Panic(EIllegalTsyReqHandle));
+	LOGTEXT(_L8("MMTsy:\tCATNetworkInfo:\tCancel called."));
+	iCancelled=ETrue;
+}
+
+
+void CATNetworkInfo::Complete(TInt aError,TEventSource aSource)
+/**
+ * This function completes the client's request.
+ */
+	{
+	iIo->WriteAndTimerCancel(this);
+	iIo->RemoveExpectStrings(this);
+	iOKExpectString = NULL;
+	iErrorExpectString = NULL;
+	if (aSource==EWriteCompletion)
+		iIo->Read();
+	iState = EATNotInProgress;
+	LOGTEXT2(_L8("MMTsy:CATNetworkInfo:\tCATNetworkInfo completed with error code : %d"), aError);
+	//
+	// BEWARE: The next command will be started from inside ReqCompleted or FlowControlResume
+	// 
+	//
+	// This object is not always started thru the CATBase::ExecuteCommand
+	// So we sometimes have to manually control the flow control of iEventSignalActive
+	iPhoneGlobals->iEventSignalActive = EFalse;
+
+	if (iReqHandle)
+		{
+		// Explicit call from a client
+		if (aError==KErrNone)
+			{
+			GetCurrentNetworkInfo(&iNetworkInfo); 
+			}
+		iTelObject->ReqCompleted(iReqHandle, aError);
+		}
+	else
+		{
+		// CheckOperator() call from CATCommands::Complete
+		iTelObject->FlowControlResume();
+		}
+	CATCommands::Complete(aError,aSource);
+	}
+
+void CATNetworkInfo::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus)
+/**
+ * This function handles I/O errors that may occur during any of the stages of the state machine.
+ */
+	{
+	if (iState!=EATNotInProgress)
+		{
+		iIo->WriteAndTimerCancel(this);
+		if (iReqHandle)
+			{
+			iTelObject->ReqCompleted(iReqHandle, aStatus);
+			}
+		else
+			{
+			// CheckOperator() call from CATCommands::Complete
+			iTelObject->FlowControlResume();
+			}
+		iState = EATNotInProgress;
+		}
+	}
+
+void CATNetworkInfo::StartGetOperator()
+/**
+ * This function kicks off the state machine by transmitting the first command, "AT+COPS?" and
+ * setting the state.
+ */
+	{
+	iPhoneGlobals->iPhoneStatus.iNetworkChanged=EFalse;
+	InitializeNetworkInfo();		// Initialize the TNetworkInfo struct that will contain the mobile's responses
+	iTxBuffer.Copy(KGetCurrentOperatorCommand);
+	iIo->Write(this, iTxBuffer);
+	iIo->SetTimeOut(this, 5000);
+	iState=EATGetCurrentOperatorWriteComplete;
+	}
+
+void CATNetworkInfo::InitializeNetworkInfo()
+/**
+ * This function is used to initialize (to zero) the network information elements in the CPhoneGlobals
+ * structure.
+ */
+	{
+	RMobilePhone::TMobilePhoneNetworkInfoV1& networkinfo = iPhoneGlobals->iPhoneStatus.iCurrentNetwork;
+
+	networkinfo.iMode = RMobilePhone::ENetworkModeUnknown;
+	networkinfo.iCountryCode.Zero();		// Unknown, MCC
+	networkinfo.iNetworkId.Zero();			// MNC
+	networkinfo.iCdmaSID.Zero();			// Unused CDMA field
+	networkinfo.iAnalogSID.Zero();			// Unused CDMA field
+	networkinfo.iShortName.Zero();
+	networkinfo.iLongName.Zero();
+	networkinfo.iStatus = RMobilePhone::ENetworkStatusUnknown; 
+	networkinfo.iDisplayTag.Zero();
+	}
+
+void CATNetworkInfo::ParseOperatorResponseL()
+/**
+ * This function is used to parse the ME responses to commands to retrieve numeric, short name 
+ * or long name network information.  Possible responses are:
+ * +COPS: mode, 0, "long format name"
+ * +COPS: mode, 1, "short format name"
+ * +COPS: mode, 2, "operator ID in hex"
+ * +COPS: mode  (no network information available)
+ *
+ * Relevant information is retrieved and written into the CPhoneGlobals class.
+ */
+	{
+	RMobilePhone::TMobilePhoneNetworkInfoV1& networkInfo = iPhoneGlobals->iPhoneStatus.iCurrentNetwork; 
+
+	ParseBufferLC();	// Parse the buffer and create a linked list with the phone's response
+
+	CATParamListEntry* entry;
+	TDblQueIter<CATParamListEntry> iter(iRxResults);
+
+	// The 1st item in the list should be the +COPS: response
+	entry=iter++;
+	if (entry && entry->iResultPtr.MatchF(KOperatorResponse)!=0)
+		User::Leave(KErrGeneral);
+
+	// The next item is the mode (this information is not used)
+	entry=iter++;
+	if (!entry)
+		User::Leave(KErrGeneral);  
+	
+	// The next item should be the format. If there is no network information then this item
+	// would be empty. The network status is consequently updated.
+	entry=iter++;
+	if (!entry)  // Not connected, so the response is "+COPS: 0"
+		networkInfo.iStatus=RMobilePhone::ENetworkStatusUnknown;
+	else	
+		{
+		TInt format=CATParamListEntry::EntryValL(entry);
+		
+		// If the format is available, the network name is the next item in the list 
+		entry=iter++;
+		if (!entry)
+			User::Leave(KErrGeneral);
+		switch (format)
+			{
+		case 0:
+			if((entry->iResultPtr).Length() > networkInfo.iLongName.MaxLength())
+				networkInfo.iLongName.Copy((entry->iResultPtr).Mid(0,networkInfo.iLongName.MaxLength()));			
+			else
+				networkInfo.iLongName.Copy(entry->iResultPtr);
+			break;
+		case 1:
+			if((entry->iResultPtr).Length() > networkInfo.iShortName.MaxLength())
+				networkInfo.iShortName.Copy((entry->iResultPtr).Mid(0,networkInfo.iShortName.MaxLength()));			
+			else 
+				networkInfo.iShortName.Copy(entry->iResultPtr);	
+			break;
+		case 2:
+			User::LeaveIfError(NetworkIdL(entry->iResultPtr,networkInfo.iCountryCode, networkInfo.iNetworkId));
+			break;
+		default:
+			User::Leave(KErrGeneral);
+			break;
+			}
+
+		// We've got an answer, so this must be the current network
+		networkInfo.iStatus=RMobilePhone::ENetworkStatusCurrent;
+		}
+	CleanupStack::PopAndDestroy();
+	}
+
+void CATNetworkInfo::GetCurrentNetworkInfo(CATNetworkInfo::TTsyNetworkInfo* aNetworkInfo)
+/**
+ * This function checks to see if the network registration information in CPhoneGlobals is valid,
+ * and, if it is, it copies the CPhoneGlobals network information into the waiting client request
+ * buffer.
+ */
+	{
+	RMobilePhone::TMobilePhoneNetworkInfoV1& networkInfo = (*(aNetworkInfo->iNetworkInfoPckg))();
+	RMobilePhone::TMobilePhoneLocationAreaV1& areaInfo = *(aNetworkInfo->iArea);
+	RMobilePhone::TMobilePhoneRegistrationStatus status = iPhoneGlobals->iPhoneStatus.iRegistrationStatus;
+
+	if (status == RMobilePhone::ERegisteredOnHomeNetwork
+		|| status == RMobilePhone::ERegisteredRoaming
+		|| status == RMobilePhone::ERegistrationUnknown) // AT+CREG? is not supported, but info obtained during initialization is still valid. NickyM
+		{
+		RMobilePhone::TMobilePhoneNetworkInfoV1& info = iPhoneGlobals->iPhoneStatus.iCurrentNetwork;
+		RMobilePhone::TMobilePhoneLocationAreaV1& locationInfo = iPhoneGlobals->iPhoneStatus.iLocationArea;
+
+		networkInfo.iStatus			= info.iStatus;
+		networkInfo.iCountryCode	= info.iCountryCode;	
+		networkInfo.iNetworkId		= info.iNetworkId;
+		networkInfo.iCdmaSID		= info.iCdmaSID;   // for CDMA
+		networkInfo.iAnalogSID		= info.iAnalogSID; // for CDMA
+		networkInfo.iShortName		= info.iShortName;
+		networkInfo.iLongName		= info.iLongName;
+		networkInfo.iDisplayTag		= info.iLongName;		// This TSY handles the display tag as the same as longname
+		networkInfo.iMode			= iPhoneGlobals->iNetworkMode;
+		areaInfo.iAreaKnown			= locationInfo.iAreaKnown;
+		areaInfo.iLocationAreaCode	= locationInfo.iLocationAreaCode;
+		areaInfo.iCellId			= locationInfo.iCellId;
+		}
+	else
+		{
+		networkInfo.iStatus			= RMobilePhone::ENetworkStatusUnknown;
+		networkInfo.iShortName.Zero();			// Should this be .Zero() ?
+		networkInfo.iLongName.Zero();			// Should this be .Zero() ?
+		areaInfo.iAreaKnown			= EFalse;	
+		areaInfo.iLocationAreaCode	= 0;
+		areaInfo.iCellId			= 0;
+
+		}
+	return;
+	}
+
+
+// class CNotifyNetworkRegistrationStatusChange
+
+CNotifyNetworkRegistrationStatusChange* CNotifyNetworkRegistrationStatusChange::NewL(TTsyReqHandle aReqHandle,CTelObject* aTelObject, 
+																					 RMobilePhone::TMobilePhoneRegistrationStatus* aRegStatus)
+	{
+	return new(ELeave) CNotifyNetworkRegistrationStatusChange(aReqHandle,aTelObject,aRegStatus);
+	}
+
+CNotifyNetworkRegistrationStatusChange::CNotifyNetworkRegistrationStatusChange(TTsyReqHandle aReqHandle,CTelObject* aTelObject, 
+																			   RMobilePhone::TMobilePhoneRegistrationStatus* aRegStatus)
+	: CNotifyBase(aReqHandle,aTelObject)
+	{
+	iRegStatus = aRegStatus;
+	}
+
+CNotifyNetworkRegistrationStatusChange::~CNotifyNetworkRegistrationStatusChange()
+	{}
+
+TBool CNotifyNetworkRegistrationStatusChange::CheckAndCompleteNotification(CTelObject* aTelObject, TEvent aEvent, TEvent /*aLastEvent*/)
+/**
+ * This function completes a Registration status Notification.
+ */
+	{	
+	if (aEvent!=ERegistrationStatusChanged)
+		return EFalse;
+
+	LOGTEXT2(_L8("Event %d:\tRegistration Status Changed Notification completed"),aEvent);
+	*iRegStatus = reinterpret_cast<CPhoneMobile*>(aTelObject)->RegistrationStatus();
+	iTelObject->ReqCompleted(iReqHandle,KErrNone);
+	return ETrue;
+	}
+
+// class CCurrentNetworkChangedNotify
+
+CNotifyCurrentNetworkChange* CNotifyCurrentNetworkChange::NewL(TTsyReqHandle aReqHandle,CTelObject* aTelObject,TInt* aInfo)
+	{	
+	return new(ELeave) CNotifyCurrentNetworkChange(aReqHandle,aTelObject,aInfo);
+	}
+
+CNotifyCurrentNetworkChange::CNotifyCurrentNetworkChange(TTsyReqHandle aReqHandle,CTelObject* aTelObject,TInt* aInfo)
+	: CNotifyBase(aReqHandle,aTelObject)
+	{
+	CATNetworkInfo::TTsyNetworkInfo* info = reinterpret_cast<CATNetworkInfo::TTsyNetworkInfo*>(aInfo);
+	iNetworkInfo.iNetworkInfoPckg = info->iNetworkInfoPckg;
+	iNetworkInfo.iArea = info->iArea;
+	}
+
+CNotifyCurrentNetworkChange::~CNotifyCurrentNetworkChange()
+	{}
+
+TBool CNotifyCurrentNetworkChange::CheckAndCompleteNotification(CTelObject* aTelObject,TEvent aEvent,TEvent /*aLastEvent*/)
+/**
+ * This function completes a Current Network Change Notification.
+ */
+	{	
+	if (aEvent!=ECurrentNetworkChanged)
+		return EFalse; 
+
+	LOGTEXT2(_L8("Event %d:\tCurrent Network Changed Notification completed"),aEvent);
+//	REINTERPRET_CAST(CPhoneMobile*,aTelObject)->CurrentNetworkInfo(&iNetworkInfo);
+	reinterpret_cast<CPhoneMobile*>(aTelObject)->CurrentNetworkInfo(&iNetworkInfo);
+	iTelObject->ReqCompleted(iReqHandle,KErrNone);
+	return ETrue;
+	}
+
+// Class CATDetectNetwork
+//
+// Detect all available networks.
+
+CATDetectNetwork::CATDetectNetwork(CATIO* aIo, CTelObject* aTelObject, CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+	: CATCommands(aIo,aTelObject,aInit,aPhoneGlobals)
+	{}
+
+CATDetectNetwork* CATDetectNetwork::NewL(CATIO* aIo,CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+/**
+ * Standard 2 phase constructor.
+ */
+	{
+	CATDetectNetwork* self = new(ELeave) CATDetectNetwork(aIo, aTelObject, aInit, aPhoneGlobals);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CATDetectNetwork::~CATDetectNetwork()
+/**
+ * Destructor.
+ */
+	{
+	iIo->RemoveExpectStrings(this);
+	}
+
+void CATDetectNetwork::Start(TTsyReqHandle aTsyReqHandle,TAny* aParam)
+/**
+ * This is the standard entry point for retrieving the detected Operator Information.
+ */
+	{
+	LOGTEXT(_L8("MMTsy:\tCATDetectNetwork:\tStarting Network detection"));
+	if (aParam != NULL)
+		{
+		TTsyDetectedNetworks*  info = static_cast<TTsyDetectedNetworks* >(aParam);
+		iDetectedNetworks.iBufSize = info->iBufSize;
+		iDetectedNetworks.iBufPtr = info->iBufPtr;
+		}
+
+	iReqHandle = aTsyReqHandle;
+
+	WriteExpectingResults(KDetectNetworkCommand, 3);
+	__ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL,Panic(EGeneral));
+	iState=EATDetectWaitForWriteComplete;
+	}
+
+void CATDetectNetwork::EventSignal(TEventSource aSource)
+/**
+ * This function contains the state machine for the command.  The states flow consecutively and are
+ * described below.
+ * 
+ * \par EATDetectWaitForWriteComplete
+ * Wait for the "AT+COPS=?" write to complete
+ *
+ * \par EATDetectReadComplete
+ * Reads the Modem's response to the AT+COPS=? command.  If it gets an "ERROR" back it resets the 
+ * timer and sets a new state (EATDetectExtendedReadComplete) and waits for another response.
+ *
+ * \par EATDetectExtendedReadComplete
+ * Reads the phone's response to the AT+COPS=? command and parses the response. Completes the
+ * request.
+ *
+ * \par EATWaitForStopState
+ * This state is used when stopping the state machine to ensure that a pending modem response has been
+ * retrieved before freeing up the Multimode TSY to send more commands.  Prematurely stopping the state machine
+ * is usually forced by a client cancel request.
+ */
+	{
+	if (aSource==ETimeOutCompletion)
+		{
+		if (iState!=EATDetectExtendedReadComplete)
+			{
+			LOGTEXT(_L8("MmTsy:\tCATDetectNetwork:\tTimeout Error during Network Detect read"));
+			RemoveStdExpectStrings();
+			Complete(KErrTimedOut,aSource);
+			return;
+			}
+		else
+			{
+			// the phone really does not support +COPS=?, so report that error
+			RemoveStdExpectStrings();
+			Complete(KErrNotSupported,EReadCompletion);
+			return;
+			}
+		}
+
+	switch(iState)
+		{
+	case EATDetectWaitForWriteComplete:
+		__ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected));
+		{
+		iIo->WriteAndTimerCancel(this);
+		iIo->SetTimeOut(this,45 * KOneSecondPause); // Some phones take a long time to detect all the networks
+		AddStdExpectStrings();
+		iState=EATDetectReadComplete;
+		}
+		break;
+
+	case EATDetectReadComplete:
+		__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
+		iIo->WriteAndTimerCancel(this);
+		if (iIo->FoundChatString()==iErrorExpectString)
+			{
+			LOGTEXT(_L8("Modem returned ERROR - waiting for further response"));
+			iIo->ClearCurrentLine();
+			iIo->SetTimeOut(this,45 * KOneSecondPause);
+			iState = EATDetectExtendedReadComplete;
+			break;
+			}
+		// fall through ...
+
+	case EATDetectExtendedReadComplete:
+		__ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected));
+		iIo->WriteAndTimerCancel(this);
+		{
+		TInt ret(ValidateExpectString());
+		RemoveStdExpectStrings();
+		if (ret==KErrNone)
+			TRAP(ret,ParseResponseL());
+		Complete(ret,aSource); // The return value is set in the Complete methode
+		}
+		break;
+
+	case EATWaitForStopState:
+		__ASSERT_ALWAYS(aSource==EReadCompletion, Panic(EATCommand_IllegalCompletionReadExpected));
+		{
+		iIo->WriteAndTimerCancel(this);
+		Complete(KErrCancel, aSource);
+		}
+		break;
+
+	default:
+		break;
+		}//switch
+	}//EventSignal
+
+void CATDetectNetwork::Stop(TTsyReqHandle aTsyReqHandle)
+/**
+ * This function is used to prematurely stop the state machine.  This would usually occur following a
+ * client cancel request.
+ */
+	{
+	__ASSERT_ALWAYS(aTsyReqHandle == iReqHandle, Panic(EIllegalTsyReqHandle));
+	LOGTEXT(_L8("MMTsy:\tCATDetectNetwork:\tCancel called."));
+	switch(iState)
+		{
+		case EATNotInProgress:
+		case EATDetectWaitForWriteComplete:
+			{
+			LOGTEXT2(_L8("Current state TSY is cancelling from %d"), iState);
+			Complete(KErrCancel, EReadCompletion);
+			}
+			break;
+
+		default:
+			{
+			LOGTEXT(_L8("MmTsy:\tCATDetectNetwork:\tStop, now waiting for expected modem response"));
+			AddStdExpectStrings();
+			iIo->SetTimeOut(this);
+			iState = EATWaitForStopState;
+			}
+			break;
+		}
+	}
+
+
+void CATDetectNetwork::Complete(TInt aError,TEventSource aSource)
+/**
+ * This function completes the client request.
+ */
+	{
+	iState = EATNotInProgress;
+	iIo->WriteAndTimerCancel(this);
+	iIo->RemoveExpectStrings(this);
+	iOKExpectString = NULL;
+	iErrorExpectString = NULL;
+	CATCommands::Complete(aError,aSource);
+
+	LOGTEXT2(_L8("MMTsy:CATDetectNetwork:\tCATDetectNetwork completed with error code : %d"), aError);
+	if (aError==KErrCancel)
+		{
+		CPhoneMobile* phone = static_cast<CPhoneMobile*>(iTelObject);
+		phone->CompleteDetectedNetworksCancel(iReqHandle);
+		}
+	else
+		iTelObject->ReqCompleted(iReqHandle, aError);
+	}
+
+void CATDetectNetwork::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus)
+/**
+ * This function handles I/O errors that may occur during any of the stages of the state machine.
+ */
+	{
+	if (iState!=EATNotInProgress)
+		{
+		iIo->WriteAndTimerCancel(this);
+		iState = EATNotInProgress;
+		iTelObject->ReqCompleted(iReqHandle, aStatus);
+		}
+	}
+
+void CATDetectNetwork::ParseResponseL()
+/**
+ * This function parses the phone's response to the Detect Networks command.
+ */
+	{
+	// should be
+	//
+	// +COPS: (status,"longname","shortname",code),... ,,(list),(list)
+	//
+	// but SH888 gives
+	//
+	// +COPS: (status,"longname","shortname",code)<cr><lf>
+	// +COPS: ...
+	//
+
+	CMobilePhoneNetworkList* list=CMobilePhoneNetworkList::NewL();
+	CleanupStack::PushL(list);
+
+	ParseBufferLC();
+
+	RMobilePhone::TMobilePhoneNetworkInfoV1 info;	
+	// This TSY only supports GSM mode so we can hardcode this
+	info.iMode=RMobilePhone::ENetworkModeGsm;
+	TDblQueIter<CATParamListEntry> iter(iRxResults);
+	CATParamListEntry* entry=iter++;
+	if (entry)
+		{
+		if (entry->iResultPtr!=KOperatorResponse)
+			User::Leave(KErrGeneral);
+		//
+		entry=iter++;
+		if (!entry)
+			User::Leave(KErrGeneral);
+		for (;;)
+			{
+			info.iStatus = RMobilePhone::TMobilePhoneNetworkStatus(CATParamListEntry::EntryValL(entry));
+			//
+			entry=iter++;
+			if (!entry)
+				User::Leave(KErrGeneral);
+			info.iLongName.Copy(entry->iResultPtr);		
+			//
+			entry=iter++;
+			if (!entry)
+				User::Leave(KErrGeneral);
+			if((entry->iResultPtr).Length() > info.iShortName.MaxLength())
+				info.iShortName.Copy((entry->iResultPtr).Mid(0,info.iShortName.MaxLength()));			
+			else
+				info.iShortName.Copy(entry->iResultPtr);
+			//
+			entry=iter++;
+			if (!entry)
+				User::Leave(KErrGeneral);
+			User::LeaveIfError(NetworkIdL(entry->iResultPtr,info.iCountryCode, info.iNetworkId));  // MNC and MCC	
+			
+			list->AddEntryL(info); 
+		
+			entry=iter++;
+			if (!entry)
+				break;
+			if (entry->iResultPtr.Length()==0)
+				break;
+			if (entry->iResultPtr!=KOperatorResponse)
+				continue;
+			entry=iter++;
+			if (!entry)
+				break;
+			}
+		}
+
+	CleanupStack::PopAndDestroy();			// results
+
+	*(iDetectedNetworks.iBufPtr) = list->StoreLC();	 // Stream the list to optimice the size of it.
+	*(iDetectedNetworks.iBufSize) = (*(iDetectedNetworks.iBufPtr))->Size(); // Store the size of the streamed list to be passed back to the client.   
+
+	CleanupStack::Pop();					// pop the CBufBase allocated by StoreLC
+	CleanupStack::PopAndDestroy();			// pop AND detroy the list.
+
+	} // End of ParseResponseL()  
+
+
+