localconnectivityservice/modematplugin/src/atcopscmd.cpp
branchRCL_3
changeset 9 87d139e87731
parent 8 a249528449c3
child 10 031b9cffe6e4
--- a/localconnectivityservice/modematplugin/src/atcopscmd.cpp	Mon Mar 15 12:43:27 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1118 +0,0 @@
-/*
-* Copyright (c) 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:  Handles the commands "AT+COPS?", "AT+COPS=?" and "AT+COPS=..."
-*
-*/
-
-
-#include <mmtsy_names.h>
-#include "atcopscmd.h"
-#include "cmdpluginobserver.h"
-#include "debug.h"
-
-_LIT8( KCOPSTestCmd, "AT+COPS=?");
-_LIT8( KCOPSReadCmd, "AT+COPS?");
-_LIT8( KCOPSSetCmd,  "AT+COPS=");
-
-_LIT8(KSupportedModesStr, ",(0,1,3,4)");
-_LIT8(KSupportedFormatsStr, ",(0,1,2)"); 
-
-// The parameters are in predefined indexes in an incoming AT command. 
-const TInt KModeParameterIndex     			= 0;  
-const TInt KFormatParameterIndex   			= 1;  
-const TInt KOperatorParameterIndex 			= 2;  
-const TInt KAccessTechnologyParameterIndex  = 3;  
-
-const TInt KMinimumParameterCountWhenModePresent       = 1;  
-const TInt KMinimumParameterCountWhenFormatPresent     = 2;  
-const TInt KMinimumParameterCountWhenOperatorPresent   = 3;  
-const TInt KMinimumParameterCountWhenAccTechPresent    = 4;  
-
-// These parameter lengths are derived from 3GPP TS 27.007 V8.4.1
-const TInt KShortOperatorNameFormatLength 			= 10; 
-const TInt KLongOperatorNameFormatLength 			= 20; 
-const TInt KNumericOperatorNameFormatLength 		= 5; 
-const TInt KMaxNetworkTestResponseAdditionalSize 	= 17; // The maximun length of parts of fixed length. 
-const TInt KMaxNetworkReadResponseAdditionalSize 	= 28 ; // The maximun length of parts fixed length.
-
-// ---------------------------------------------------------------------------
-// Two-phased constructor.
-// ---------------------------------------------------------------------------
-//
-CATCOPSCmd* CATCOPSCmd::NewL( MCmdPluginObserver* aCallback )
-    {
-    CATCOPSCmd* self = new (ELeave) CATCOPSCmd( aCallback );
-    CleanupStack::PushL( self );
-    self->ConstructL();
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// ---------------------------------------------------------------------------
-// Destructor.
-// ---------------------------------------------------------------------------
-//
-CATCOPSCmd::~CATCOPSCmd()
-    {
-    iParamArray.ResetAndDestroy(); 
-    iParamArray.Close(); 
-    iPacketService.Close(); 
-    iCustomApi.Close(); 
-    iPhone.Close(); 
-    iServer.Close();
-    delete iDetectedNetworks;
-    delete iRetrieveDetectedNetworks; 
-    }
-
-// ---------------------------------------------------------------------------
-// CATCOPSCmd::CATCOPSCmd
-// ---------------------------------------------------------------------------
-//
-CATCOPSCmd::CATCOPSCmd( MCmdPluginObserver* aCallback ) :
-    CActive(EPriorityStandard),
-    iCallback( aCallback ), 
-	iFormat(RMmCustomAPI::EOperatorNameMccMnc), 
-    iRegistrationMode(EModeAutomatic), 
-    iAccTech(EAccTechNotSet), 
-    iCurrentOperation(EIdle)
-    {
-    iCmdHandlerType = ECmdHandlerTypeUndefined;
-    }
-
-// ---------------------------------------------------------------------------
-// CATCOPSCmd::ConstructL
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::ConstructL()
-    {
-    if ( !iCallback )
-        {
-        User::Leave( KErrGeneral );
-        }
-    CActiveScheduler::Add(this);
-    LEAVE_IF_ERROR(iServer.Connect());
-    LEAVE_IF_ERROR(iServer.LoadPhoneModule(KMmTsyModuleName));
-    LEAVE_IF_ERROR(iPhone.Open(iServer, KMmTsyPhoneName));
-    LEAVE_IF_ERROR(iCustomApi.Open(iPhone));
-    LEAVE_IF_ERROR(iPacketService.Open(iPhone));
-    iRetrieveDetectedNetworks = CRetrieveMobilePhoneDetectedNetworks::NewL(iPhone); 
-    }
-
-// ---------------------------------------------------------------------------
-// Reports the support status of an AT command. This is a synchronous API.
-// ---------------------------------------------------------------------------
-//
-TBool CATCOPSCmd::IsCommandSupported( const TDesC8& aCmd )
-    {
-    TRACE_FUNC_ENTRY
-    TInt retTemp = KErrNone;
-
-		// First test if "test" command, because the pattern is similar with the "set" command, 
-		// this is just one extra question mark longer than that. 
-    retTemp = aCmd.Compare( KCOPSTestCmd );
-    if ( retTemp == 0 )
-        {
-        iCmdHandlerType = ECmdHandlerTypeTest;
-        TRACE_FUNC_EXIT
-        return ETrue;
-        }
-
-    retTemp = aCmd.Compare( KCOPSReadCmd );
-    if ( retTemp == 0 )
-        {
-        iCmdHandlerType = ECmdHandlerTypeRead;
-        TRACE_FUNC_EXIT
-        return ETrue;
-        }
-
-	// Test if the beginning matches the test command pattern. We're skipping parameters 
-	// here on purpose, because "set" handler will create an error reply later if 
-	// parameters are not valid. 
-    retTemp = aCmd.Left(KCOPSSetCmd().Length()).Compare(KCOPSSetCmd);
-    if ( retTemp == 0 )
-        {
-        iCmdHandlerType = ECmdHandlerTypeSet;
-        TRACE_FUNC_EXIT
-        return ETrue;
-        }
-
-    iCmdHandlerType = ECmdHandlerTypeUndefined;
-    TRACE_FUNC_EXIT
-    return EFalse;
-    }
-
-// ---------------------------------------------------------------------------
-// Handles an AT command. Cancelling of the pending request is done by
-// HandleCommandCancel(). The implementation in the extension plugin should
-// be asynchronous.
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::HandleCommand( const TDesC8& aCmd,
-                                   RBuf8& aReply,
-                                   TBool aReplyNeeded )
-    {
-    TRACE_FUNC_ENTRY
-
-    if ( !aReplyNeeded )
-        {
-        TRACE_FUNC_EXIT
-        return;
-        }
-
-    if(iCurrentOperation != EIdle)  
-        {
-        // only one call at time allowed. If another one is passed in, 
-        // then cancel the previous and reply with an error.   
-        HandleCommandCancel(); 
-        CreateReply(EFalse); 
-        }
-    
-    if ( iCmdHandlerType == ECmdHandlerTypeUndefined )
-        {
-		CreateReply(EFalse); 
-		}
-
-    if ( iCmdHandlerType == ECmdHandlerTypeTest )
-        {
-        // Collect network data and complete in RunL 
-        iRetrieveDetectedNetworks->StartV2(iStatus); 
-        iCurrentOperation = EListAvailableNetworkOperators; 
-        SetActive(); 
-        TRACE_FUNC_EXIT
-        return;
-        }
-
-/*
-Read command returns the current mode, the currently selected operator 
-and the current Access Technology. If no operator is selected, <format>, 
-<oper> and < AcT>  are omitted.
-*/
-    if ( iCmdHandlerType == ECmdHandlerTypeRead )
-        {
-        // Collect data in two steps. First read operator name. Continue in RunL() 
-        RMobilePhone::TMobilePhoneNetworkSelectionV1 selection; 
-        RMobilePhone::TMobilePhoneNetworkSelectionV1Pckg nwSelectionSetting(selection); 
-        iPhone.GetNetworkSelectionSetting(nwSelectionSetting);
-        switch(selection.iMethod)
-            {
-            case RMobilePhone::ENetworkSelectionAutomatic: 
-                iRegistrationMode = EModeAutomatic;
-                break; 
-            case RMobilePhone::ENetworkSelectionManual: 
-                iRegistrationMode = EModeManual;
-                break; 
-            default: 
-                // Cannot get a known selection mode! 
-                TRACE_INFO(_L("CATCOPSCmd::HandleCommand() -- Cannot get a known selection mode!"));
-                CreateReply(EFalse); 
-                TRACE_FUNC_EXIT
-                return; 
-            }
-        RMobilePhone::TMobilePhoneNetworkInfoV2Pckg nwInfo(iNetworkInfo); 
-        iPhone.GetCurrentNetwork(iStatus, nwInfo); 
-        iCurrentOperation = EGetNetworkInfoOperatorName; 
-		SetActive(); 
-        TRACE_INFO((_L("CATCOPSCmd::HandleCommand() starting operation (%d)"), iCurrentOperation));
-        TRACE_FUNC_EXIT
-        return;
-        }
-
-    // Getting this far means ECmdHandlerTypeSet. There must be parameter(s), too.   
-    TRAPD(err, ExtractParametersL(aCmd)); 
-
-    // Check that we got some parameters, at least the "mode". If not, return an error: 
-	if(iParamArray.Count() < KMinimumParameterCountWhenModePresent) 
-        {
-        // Return error response, there were no parameters! 
-        TRACE_INFO(_L("CATCOPSCmd::HandleCommand() -- no parameters!"));
-        CreateReply(EFalse); 
-        TRACE_FUNC_EXIT
-        return; 
-        }
-
-	// At least the mode parameter is present at this point. Inspect it and check other parameters. 
-	TNetworkRegistrationMode mode; 
-	err = GetModeAndCheckParameterCount(iParamArray[KModeParameterIndex]->Des(), mode); 
-	if(err != KErrNone) 
-		{
-        // Return error response, invalid mode or other parameters! 
-		TRACE_INFO(_L("CATCOPSCmd::HandleCommand() -- invalid mode or other parameters!"));
-        CreateReply(EFalse); 
-	    TRACE_FUNC_EXIT
-        return; 
-		}
-
-    // At this point the iRegistrationMode is stored and the parameters are valid. 
-	iRegistrationMode = mode; 
-	TRACE_INFO(( _L("CATCOPSCmd::HandleCommand() mode stored (%d)"), iRegistrationMode));
-		
-	if(iParamArray.Count() > 1) 
-		{
-		// If also format is present, extract it and store for later reference. 
-        RMmCustomAPI::TOperatorNameType format;
-        err = GetFormatFromParameter(iParamArray[KFormatParameterIndex]->Des(), format); 
-		if(err != KErrNone) 
-		    {
-		    // Return an error, invalid format. 
-			// Previously set format is still in use. 
-	 		TRACE_INFO(_L("CATCOPSCmd::HandleCommand() -- invalid format!"));
-            CreateReply(EFalse); 
-	 		TRACE_FUNC_EXIT
-			return; 
-			}
-		// Format parameter is OK, keep it.
-		iFormat = format;  
-		TRACE_INFO(( _L("CATCOPSCmd::HandleCommand() format stored (%d)"), iFormat));
-		}
-
-	// We're done with the required parameters, it's time to start processing the command. 
-	// So do a self complete and continue in RunL(): 
-	iReply = &aReply;  // Store the reply for later reference in RunL. 
-	iCurrentOperation = EInspectModeAndProcessCommand; 
-	TRequestStatus *status = &iStatus;  
-	User::RequestComplete(status, KErrNone); 
-	SetActive(); 
-	TRACE_INFO((_L("CATCOPSCmd::HandleCommand() starting operation (%d)"), iCurrentOperation));
-    TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// Parses the aCmd parameter and stores results in iParamArray.
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::ExtractParametersL(const TDesC8& aCmd) 
-	{
-    TRACE_FUNC_ENTRY
-
-    TRACE_INFO(( _L8("CATCOPSCmd::ExtractParameters() extracting (%S)"), &aCmd));
-
-    TPtrC8 parameters = aCmd.Right(aCmd.Length() - KCOPSSetCmd().Length()); 
-
-    iParamArray.ResetAndDestroy(); 
-
-    // Parse the parameters into the parameter array: 
-    TInt separatorPos;  
-    while((separatorPos = parameters.Locate(',')) != KErrNotFound)
-        {
-        TRACE_INFO(( _L("CATCOPSCmd::ExtractParameters() separator position (%d)"), separatorPos));
-        TPtrC8 param = parameters.Left(separatorPos);
-        parameters.Set(parameters.Right(parameters.Length() - (separatorPos + 1))); // Remove the extracted part + separator 
-        HBufC8 *heapParam = param.AllocL();    
-        CleanupStack::PushL( heapParam );
-        // Strip the quotation marks from the parameter: 
-        TPtr8 ptr = heapParam->Des(); 
-        RemoveQuotationMarks(ptr); 
-        TRACE_INFO(( _L8("CATCOPSCmd::ExtractParameters() appending (%S)"), &ptr));
-        iParamArray.Append(heapParam); 
-        CleanupStack::Pop( heapParam );
-        }
-
-    // Finally append the last piece of parameters: 
-    HBufC8 *param = parameters.AllocL(); 
-    CleanupStack::PushL( param );
-    TPtr8 ptr = param->Des(); 
-    RemoveQuotationMarks(ptr); 
-    TRACE_INFO(( _L8("CATCOPSCmd::ExtractParameters() appending (%S)"), &ptr));
-    iParamArray.Append(param); 
-    CleanupStack::Pop( param );
-
-    TRACE_FUNC_EXIT
-	}
-
-// ---------------------------------------------------------------------------
-// Strips all quotation parms from the string passed in. 
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::RemoveQuotationMarks(TPtr8& aParameter) 
-    {
-    TRACE_FUNC_ENTRY
-    // Strip the quotation marks from the parameter: 
-    TInt quotePos;  
-    while((quotePos = aParameter.Locate('"')) != KErrNotFound)
-    {
-        aParameter.Delete(quotePos,1); 
-    }
-    TRACE_FUNC_EXIT
-    }
-
-
-// ---------------------------------------------------------------------------
-// Returns the selected mode in aMode and checks the parameter count. 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::GetModeAndCheckParameterCount(const TDesC8& aParameter, TNetworkRegistrationMode &aMode) 
-	{
-  TRACE_FUNC_ENTRY
-	TLex8 lex;
-	lex.Assign(aParameter);
-	TInt mode(0); 
-
-	TInt err = lex.Val(mode); 
-	TRACE_INFO(( _L("CATCOPSCmd::GetModeAndCheckParameterCount() mode (%d)"), mode));
-
-	if( err != KErrNone )
-		{
-        TRACE_INFO(_L("CATCOPSCmd::GetModeAndCheckParameterCount() TLex error!)"));
-        TRACE_FUNC_EXIT
-        return KErrArgument; 
-		}			
-
-  if(mode < EModeAutomatic || mode > EModeManualAutomatic || mode == EModeDeregister)
-      {
-      // Not a valid mode. 
-      TRACE_FUNC_EXIT
-      return KErrArgument; 
-      }
-
-  if( (mode == EModeManual || mode == EModeManualAutomatic)  &&  iParamArray.Count() < KMinimumParameterCountWhenOperatorPresent )
-      {
-      // Valid modes but not enough parameters. At least format and operator needed.  
-      TRACE_INFO(( _L("CATCOPSCmd::GetModeAndCheckParameterCount() not enough parameters (%d)"), iParamArray.Count()));
-      TRACE_FUNC_EXIT
-      return KErrArgument; 
-      }
-  if( mode == EModeSetFormatParameter && iParamArray.Count() < KMinimumParameterCountWhenFormatPresent )
-      {
-      // Valid mode, but not enough parameters. Format is needed.  
-      TRACE_INFO(_L("CATCOPSCmd::GetModeAndCheckParameterCount() no format parameter)"));
-      TRACE_FUNC_EXIT
-      return KErrArgument; 
-      }
-
-  // Valid mode and enough parameters. 
-  aMode = static_cast<TNetworkRegistrationMode>(mode);
-
-	TRACE_FUNC_EXIT
-	return KErrNone; 
-	}
-
-// ---------------------------------------------------------------------------
-// Converts an AT command parameter to numeric format value and checks it is valid. 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::GetFormatFromParameter(const TDesC8& aParameter, RMmCustomAPI::TOperatorNameType &aFormat) 
-	{
-    TRACE_FUNC_ENTRY
-    TLex8 lex;
-    lex.Assign(aParameter);
-    TInt format(0); 
-    TInt err = lex.Val(format); 
-
-    if(err != KErrNone)
-        {
-        TRACE_FUNC_EXIT
-        return KErrArgument; 
-        }
-    switch(format)
-        {
-        case EFormatLong: // long by 3GPP TS 27.007 V8.4.1  
-            TRACE_INFO(_L("Format is long by 3GPP TS 27.007 V8.4.1"));
-            aFormat = RMmCustomAPI::EOperatorNameNitzFull; 
-            break; 
-        case EFormatShort: // short by 3GPP TS 27.007 V8.4.1 
-            TRACE_INFO(_L("Format is short by 3GPP TS 27.007 V8.4.1"));
-            aFormat = RMmCustomAPI::EOperatorNameNitzShort; 
-            break; 
-        case EFormatNumeric: // numeric by 3GPP TS 27.007 V8.4.1 
-            TRACE_INFO(_L("Format is numeric by 3GPP TS 27.007 V8.4.1"));
-            aFormat = RMmCustomAPI::EOperatorNameMccMnc; 
-            // Operator is numeric, conver it into S60 style. 
-            break; 
-        default: 
-            TRACE_FUNC_EXIT
-            return KErrArgument;
-        }
-
-    TRACE_FUNC_EXIT
-    return KErrNone; 
-    }
-
-// ---------------------------------------------------------------------------
-// Converts an AT command parameter to numeric access technology value and checks it is valid. 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::GetAccTechFromParameter(const TDesC8& aParameter, TAccessTechnology& aAccTech) 
-    {
-    TRACE_FUNC_ENTRY
-    TLex8 lex;
-    lex.Assign(aParameter);
-    TInt accTech(0); 
-    TInt err = lex.Val(accTech); 
-
-    if(err != KErrNone)
-        {
-        TRACE_FUNC_EXIT
-        return KErrArgument; 
-        }
-
-    if(accTech != EGSM && accTech != EUDMA) // The only allowed access technologies. 
-        {
-        TRACE_FUNC_EXIT
-        return KErrArgument; 
-        }
- 
-    aAccTech = static_cast<TAccessTechnology>(accTech);
-
-    TRACE_FUNC_EXIT
-    return KErrNone; 
-    }
-
-// ---------------------------------------------------------------------------
-// Converts an AT command parameter to ETel compatible operator values 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::ConvertOperatorToMccMnc(const CMobilePhoneNetworkListV2 *aDetectedNetworks, 
-                                        const RMmCustomAPI::TOperatorNameType aFormat, 
-                                        const TBuf<KMaxOperatorNameLength>& aOperatorParameter, 
-                                        RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc, 
-                                        RMobilePhone::TMobilePhoneNetworkIdentity& aMnc) 
-    {
-    TRACE_FUNC_ENTRY
-
-    if(aFormat == RMmCustomAPI::EOperatorNameMccMnc) 
-        {
-        // Check first that there are at least five characters passed in. 
-       	TChar nextChar; 
-        if(aOperatorParameter.Length() < 5)
-        	{
-			return KErrArgument; 
-        	}
-        for(int i = 0; i < 5; ++i)
-        	{
-            nextChar = aOperatorParameter[i]; 
-            if(!nextChar.IsDigit()) 
-                {
-                return KErrArgument; 
-                }
-      		}
-        // Operator is in three digit country code + two digit network code format.  
-	    // Must be converted to ETel style. The possible extra will be simply discarded. 
-     	TRACE_INFO(_L("CATCOPSCmd::ConvertOperatorToMccMnc() operator is all digits, convert it into ETel data types."));
-	    aMcc.Copy(aOperatorParameter.Left(3)); 
-	    aMnc.Copy(aOperatorParameter.Right(2)); 
-	    }
-    else  // The short or long text string formats. 
-        {
-        // Find the requested operator from the operator array.  
-        // If array is empty, return an error. 
-        if(!aDetectedNetworks)
-            {
-            TRACE_INFO(_L("CATCOPSCmd::ConvertOperatorToMccMnc() No detected networks!"));
-            TRACE_FUNC_EXIT
-            return KErrNotFound; 
-            }
-
-        RMobilePhone::TMobilePhoneNetworkInfoV2 nwInfo; 
-        for(TInt i=0; i < iDetectedNetworks->Enumerate(); ++i)
-            {
-            TRAPD(err, nwInfo = iDetectedNetworks->GetEntryL(i))  
-            if(err != KErrNone)
-                {
-                return KErrNotFound; 
-                }
-
-            if(aFormat == RMmCustomAPI::EOperatorNameNitzShort)
-                {
-                TRACE_INFO(_L("CATCOPSCmd::ConvertOperatorToMccMnc() Operator is in short format, comparing."));
-                if(nwInfo.iShortName.Compare(aOperatorParameter) == 0)
-                    {
-                    TRACE_INFO(_L("Match found."));
-                    aMcc = nwInfo.iCountryCode; 
-                    aMnc = nwInfo.iNetworkId; 
-                    TRACE_FUNC_EXIT
-                    return KErrNone; 
-                    } 
-                }
-            else if(aFormat == RMmCustomAPI::EOperatorNameNitzFull)
-                {
-                TRACE_INFO(_L("CATCOPSCmd::ConvertOperatorToMccMnc() Operator is in long format, comparing."));
-                if(nwInfo.iLongName.Compare(aOperatorParameter) == 0)
-                    {
-                    TRACE_INFO(_L("Match found."));
-                    aMcc = nwInfo.iCountryCode; 
-                    aMnc = nwInfo.iNetworkId; 
-                    TRACE_FUNC_EXIT
-                    return KErrNone; 
-                    } 
-                }
-            else        
-                {
-                TRACE_INFO(_L("CATCOPSCmd::ConvertOperatorToMccMnc() Unknown operator format!"));
-                TRACE_FUNC_EXIT
-                return KErrArgument; 
-                }
-            }
-        TRACE_INFO(_L("CATCOPSCmd::ConvertOperatorToMccMnc() Operator was not found in list!"));
-        TRACE_FUNC_EXIT
-        return KErrNotFound; 
-        }
-
-    TRACE_FUNC_EXIT
-    return KErrNone; 
-    }
-
-
-// ---------------------------------------------------------------------------
-// Initiates an automatic network registration.  
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::AutomaticNetworkRegistration() 
-    {
-    TRACE_FUNC_ENTRY
-    RMobilePhone::TMobilePhoneNetworkManualSelection nwInfo; 
-	iCurrentOperation = EAutomaticallyRegisterToNetwork; 
-	nwInfo.iCountry = KNullDesC;
-	nwInfo.iNetwork = KNullDesC;
-	iPhone.SelectNetwork(iStatus, EFalse, nwInfo); 
-	SetActive();  // Response will be sent in RunL 
-	TRACE_INFO((_L("CATCOPSCmd::HandleCommand() starting operation (%d)"), iCurrentOperation));
-	TRACE_FUNC_EXIT
-	}
-
-// ---------------------------------------------------------------------------
-// Initiates a manual network registration.  
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::ManualNetworkRegistration(const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc, 
-                                           const RMobilePhone::TMobilePhoneNetworkIdentity& aMnc) 
-    {
-	TRACE_FUNC_ENTRY
-	RMobilePhone::TMobilePhoneNetworkManualSelection nwInfo; 
-	iCurrentOperation = EManuallyRegisterToNetwork; 
-	nwInfo.iCountry.Append(aMcc);
-	nwInfo.iNetwork.Append(aMnc);
-	iPhone.SelectNetwork(iStatus, ETrue, nwInfo); 
-	SetActive(); 	// Response will be sent in RunL 
-	TRACE_INFO((_L("CATCOPSCmd::HandleCommand() starting operation (%d)"), iCurrentOperation));
-	TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// Initiates a manual network registration and access technology selection.  
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::ManualNetworkRegistration(const RMobilePhone::TMobilePhoneNetworkCountryCode& aMcc, 
-                                           const RMobilePhone::TMobilePhoneNetworkIdentity& aMnc, 
-                                           const TAccessTechnology aAccTech) 
-    {
-    TRACE_FUNC_ENTRY
-	// Store access technology for later reference: 
-    iAccTech = aAccTech; 
-	// Call another overload to start the first phase of the operation: 
-	ManualNetworkRegistration(aMcc, aMnc); 
-	// Set the state again so the RunL knows to launch the next phase: 
-	iCurrentOperation = EManuallyRegisterToNetworkAndChooseAccTech; 
-  	TRACE_INFO((_L("CATCOPSCmd::HandleCommand() starting operation (%d)"), iCurrentOperation));
-	TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// CATCOPSCmd::RunL 
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::RunL()
-    {
-    TRACE_FUNC_ENTRY
-	TInt err = KErrNone; 
-	if(iStatus != KErrNone)   
-	    {
-        HandleError(); 
-	    }
-    // Proceed to next step or return a response if all is done.
-    switch(iCurrentOperation)
-        {
-        case EListAvailableNetworkOperators: 
-            TRACE_INFO((_L("CATCOPSCmd::HandleCommand() completing operation (%d)"), iCurrentOperation));
-            if(iDetectedNetworks)
-                {
-                delete iDetectedNetworks;
-                iDetectedNetworks = NULL; 
-                }
-            iDetectedNetworks = iRetrieveDetectedNetworks->RetrieveListV2L(); 
-            // Then create a response. 
-            TRAP(err, ConstructNetworkListResponseL()); 
-            if(err != KErrNone)
-                {
-                // An error here means that no response has been sent. Reply with an error. 
-                CreateReply(EFalse); 
-                }
-            break; 
-        
-        case EInspectModeAndProcessCommand: 
-            // Check the mode and act accordingly 
-            TRACE_INFO((_L("CATCOPSCmd::HandleCommand() completing operation (%d)"), iCurrentOperation));
-            err = InspectModeAndProcessCommand(); 
-            if(err != KErrNone)
-                {
-                CreateReply(EFalse); 
-                }
-            break; 
-
-        case EGetNetworkInfoOperatorName: 
-            if(ConstructNetworkInfoResponse() != KErrNone)
-                {
-                // An error means that no response has been sent. Reply with an error. 
-                CreateReply(EFalse); 
-                }
-            break; 
-
-        case EManuallyRegisterToNetworkAndChooseAccTech: 
-            TRACE_INFO((_L("CATCOPSCmd::HandleCommand() completing operation (%d)"), iCurrentOperation));
-            switch(iAccTech)
-                {
-                case EGSM: 
-                    iCustomApi.SetSystemNetworkMode(iStatus, RMmCustomAPI::KCapsNetworkModeGsm);
-                    iCurrentOperation = ESetSystemNetworkBand; 
-                    SetActive(); 
-                    break; 
-                case EUDMA: 
-                    iCustomApi.SetSystemNetworkMode(iStatus, RMmCustomAPI::KCapsNetworkModeUmts);
-                    iCurrentOperation = ESetSystemNetworkBand; 
-                    SetActive(); 
-                    break; 
-                default:
-                    // No automatic registering requested, so send back an error response. 
-                    TRACE_INFO( _L("CATCOPSCmd::RunL() incorrect acc.tech., reply an error."));
-                    CreateReply(EFalse); 
-                }
-            TRACE_INFO((_L("CATCOPSCmd::HandleCommand() starting operation (%d)"), iCurrentOperation));
-            break; 
-
-        case EManuallyRegisterToNetwork: 
-        case EAutomaticallyRegisterToNetwork: 
-        case ESetSystemNetworkBand: 
-            TRACE_INFO((_L("CATCOPSCmd::HandleCommand() completing operation (%d)"), iCurrentOperation));
-            // Last step completed successfully, so create OK response. 
-            CreateReply(ETrue); 
-            break; 
-
-        default: 
-            TRACE_INFO(( _L("CATCOPSCmd::RunL() default operation (%d)!"), iCurrentOperation));
-            break; 
-        }
-    TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// Handles an error in async call. 
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::HandleError()
-    {
-    TRACE_FUNC_ENTRY
-    TRACE_INFO(( _L("CATCOPSCmd::RunL() failure (%d) in operation (%d)!"), iStatus.Int(), iCurrentOperation));
-
-    // In case of failure check the operation. In some cases failures are OK.
-    switch(iCurrentOperation)
-        {
-        case EManuallyRegisterToNetwork: 
-            if(iRegistrationMode == EModeManualAutomatic)
-                {
-                // Manual registration failed, try automatic next. 
-                TRACE_INFO( _L("CATCOPSCmd::RunL() registration mode manual automatic, try automatic."));
-                AutomaticNetworkRegistration(); 
-                }
-            else 
-                {
-                // No automatic registering requested, so send back an error response. 
-                TRACE_INFO( _L("CATCOPSCmd::RunL() reply an error."));
-                CreateReply(EFalse); 
-                }
-            break; 
-        case ESetSystemNetworkBand: 
-        case EManuallyRegisterToNetworkAndChooseAccTech: 
-			if(iRegistrationMode == EModeManualAutomatic)
-                {
-                // Manual registration failed, try automatic next. 
-                TRACE_INFO( _L("CATCOPSCmd::RunL() registration mode manual automatic, try automatic."));
-                AutomaticNetworkRegistration(); 
-				break;
-                }
-            else 
-                {
-				// Cannot set the access technology, so set it back to EAccTechNotSet. 
-				// This prevents replying to queries with outdated or incorrect acc tech information. 
-				TRACE_INFO( _L("CATCOPSCmd::RunL() couldn't set system network band, so reset access tech."));
-				iAccTech = EAccTechNotSet; 
-				// Fall through to default, because these require an error response. 
-				}
-        default: 
-            // In all other cases send back an error response. 
-            TRACE_INFO( _L("CATCOPSCmd::RunL() reply an error."));
-            CreateReply(EFalse); 
-            break; 
-        }
-    TRACE_FUNC_EXIT
-    }
-
-
-// ---------------------------------------------------------------------------
-// Cancels a pending HandleCommand request.
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::HandleCommandCancel()
-    {
-    TRACE_FUNC_ENTRY
-    Cancel(); 
-    TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// CATCOPSCmd::DoCancel
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::DoCancel()
-    {
-    TRACE_FUNC_ENTRY
-    switch(iCurrentOperation)
-        {
-        case EAutomaticallyRegisterToNetwork:
-        case EManuallyRegisterToNetwork:
-        case EManuallyRegisterToNetworkAndChooseAccTech:
-            iPhone.CancelAsyncRequest(EMobilePhoneSelectNetworkCancel);  
-            break; 
-        case EGetNetworkInfoOperatorName:
-            iPhone.CancelAsyncRequest(EMobilePhoneGetCurrentNetworkCancel);  
-            break; 
-        case ESetSystemNetworkBand:
-            iCustomApi.CancelAsyncRequest(ECustomSetSystemNetworkModeIPC); 
-            break; 
-        case EListAvailableNetworkOperators:
-            iRetrieveDetectedNetworks->Cancel();  
-            break; 
-        default: 
-            break; 
-        }
-
-    iCurrentOperation = EIdle; 
-
-    TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// Helper method for RunL() 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::InspectModeAndProcessCommand()
-    {
-    TRACE_FUNC_ENTRY
-    TBuf<KMaxOperatorNameLength> buf;
-    TInt err; 
-
-    switch (iRegistrationMode)
-        {
-        case EModeAutomatic: 
-            AutomaticNetworkRegistration(); 
-            break; 
-        case EModeManual: 
-        case EModeManualAutomatic: // see also RunL() 
-            if(iParamArray.Count() < KMinimumParameterCountWhenOperatorPresent)
-                {
-                TRACE_FUNC_EXIT
-                return KErrArgument; 
-                }
-            
-            // At least the operator is present, so convert it into S60 format. 
-            buf.Copy(iParamArray[KOperatorParameterIndex]->Des()); 
-            err = ConvertOperatorToMccMnc(iDetectedNetworks, iFormat, buf, iMcc, iMnc); 
-            if(err != KErrNone)
-                {
-                TRACE_INFO(_L("CATCOPSCmd::HandleCommand() -- operator conversion failed!"));
-                TRACE_FUNC_EXIT
-                return KErrArgument; 
-                }
-
-            if (iParamArray.Count() >= KMinimumParameterCountWhenAccTechPresent) 
-                {
-                // Also access tech. is present. Convert it to ETel compatible value.  
-                TAccessTechnology accTech; 
-                TInt err = GetAccTechFromParameter(iParamArray[KAccessTechnologyParameterIndex]->Des(), accTech); 
-                if(err != KErrNone)
-                    {
-                    // Parameter problem, return an error. 
-                    TRACE_FUNC_EXIT
-                    return KErrArgument; 
-                    }
-                // Register both operator and access technology manually.
-                ManualNetworkRegistration(iMcc, iMnc, accTech); 
-                }
-            else 
-                {
-                // No access technology parameter, so register just the operator. 
-                ManualNetworkRegistration(iMcc, iMnc); 
-                }
-            break; 
-        case EModeDeregister: // Deregister from network 
-            // Not supported, return an error. 
-			TRACE_FUNC_EXIT
-            return KErrArgument; 
-        case EModeSetFormatParameter: 
-            // Storing format parameter was done already, so just reply OK. 
-            CreateReply(ETrue); 
-			TRACE_FUNC_EXIT
-            return KErrNone; 
-        default: 
-            return KErrArgument; 
-        }
-    TRACE_FUNC_EXIT
-    return KErrNone; 
-    }
-
-// ---------------------------------------------------------------------------
-// Converts the ETel access technology into 3GPP TS 27.007 V8.4.1 compatible format. 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::SolveAccessTechnology(RMobilePhone::TMobilePhoneNetworkAccess &aAccessTech)
-    {
-    TRACE_FUNC_ENTRY
-
-    TUint caps;
-    if(iPacketService.GetStaticCaps(caps, RPacketContext::EPdpTypePPP) != KErrNone)
-        {
-        TRACE_FUNC_EXIT
-        return KErrGeneral;     
-        }
-
-    TRACE_INFO(( _L8("CATCOPSCmd::SolveAccessTechnology() static caps gotten (%b)"), caps));
-
-    switch(aAccessTech)
-        {
-        case RMobilePhone::ENetworkAccessGsm: 
-            if(caps & RPacketService::KCapsEGPRSSupported)
-                {
-                iAccTech = EGSMwithEGPRS; 
-                }
-            else 
-                {
-                iAccTech = EGSM; 
-                }
-            break; 
-        case RMobilePhone::ENetworkAccessGsmCompact: 
-            iAccTech = EGSMCompact; 
-            break; 
-        case RMobilePhone::ENetworkAccessUtran: 
-            if(caps & RPacketService::KCapsHSDPASupported) 
-                {
-                if(caps & RPacketService::KCapsHSUPASupported)
-                    {
-                    iAccTech = EUDMAwithHSDPAandHSUPA;  
-                    }
-                else 
-                    {
-                    iAccTech = EHSDPA;  
-                    }
-                }
-            else if(caps & RPacketService::KCapsHSUPASupported) 
-                {
-                iAccTech = EHSUPA;  
-                }
-            else 
-                {
-                iAccTech = EUDMA;  
-                }
-            break;
-        default: 
-            TRACE_INFO( _L("CATCOPSCmd::SolveAccessTechnology() unknown access tech!"));
-            iAccTech = EAccTechNotSet; 
-            return KErrArgument; 
-		}
-    TRACE_FUNC_EXIT
-    return KErrNone;  
-    }
-
-// ---------------------------------------------------------------------------
-// Contructs a response for the read command. 
-// ---------------------------------------------------------------------------
-//
-TInt CATCOPSCmd::ConstructNetworkInfoResponse()
-    {
-    TRACE_FUNC_ENTRY
-    RBuf8 reply;
-    TInt size(KMaxNetworkTestResponseAdditionalSize + KLongOperatorNameFormatLength);       
-    TChar carriageReturn;
-    TChar lineFeed;
-    TInt err;
-    err = reply.Create(size);
-	err |= iCallback->GetCharacterValue( ECharTypeCR, carriageReturn );
-	err |= iCallback->GetCharacterValue( ECharTypeLF, lineFeed );		
-	if(err != KErrNone) 
-		{
-		return err; 
-		}
-
-	// Some PC Software expects and extra CR+LF, hence those are added twice: 
-	reply.Append( carriageReturn ); 
-	reply.Append( lineFeed );
-    reply.Append( carriageReturn );
-    reply.Append( lineFeed );  
-    reply.Append(_L("+COPS: "));  
-    reply.AppendNum(iRegistrationMode);  
-    reply.Append(_L(","));  
-    switch(iFormat)
-        {
-        case RMmCustomAPI::EOperatorNameNitzFull:   
-            reply.AppendNum(EFormatLong);  
-            reply.Append(_L(",")); 
-            reply.Append(_L("\""));   
-            TRACE_INFO(( _L8("CATCOPSCmd::ConstructNetworkInfoResponse() appending (%S)"), 
-                    &iNetworkInfo.iLongName));
-            reply.Append(iNetworkInfo.iLongName);  
-            break; 
-        case RMmCustomAPI::EOperatorNameNitzShort:
-            reply.AppendNum(EFormatShort); 
-            reply.Append(_L(",")); 
-            reply.Append(_L("\"")); 
-            TRACE_INFO(( _L8("CATCOPSCmd::ConstructNetworkInfoResponse() appending (%S)"), 
-                    &iNetworkInfo.iShortName));
-            reply.Append(iNetworkInfo.iShortName); 
-            break; 
-        case RMmCustomAPI::EOperatorNameMccMnc: 
-            reply.AppendNum(EFormatNumeric); 
-            reply.Append(_L(",")); 
-            reply.Append(_L("\"")); 
-            TRACE_INFO(( _L8("CATCOPSCmd::ConstructNetworkInfoResponse() appending codes (%S) and (%S)"), 
-                            &iNetworkInfo.iCountryCode, &iNetworkInfo.iNetworkId));
-            reply.Append(iNetworkInfo.iCountryCode); 
-            reply.Append(iNetworkInfo.iNetworkId); 
-            break; 
-        }
-    reply.Append(_L("\"")); 
-
-    if(SolveAccessTechnology(iNetworkInfo.iAccess) == KErrNone && iAccTech != EAccTechNotSet) 
-        {
-        TRACE_INFO((_L("CATCOPSCmd::ConstructNetworkInfoResponse() appending acc. tech. (%d)"), 
-                            iAccTech));
-        reply.Append(_L(",")); 
-        reply.AppendNum(iAccTech); 
-        }
-
-    reply.Append( carriageReturn );
-    reply.Append( lineFeed );
-
-    CreateReply(ETrue, reply); 
-
-    TRACE_FUNC_EXIT
-    return KErrNone;  
-    }
-
-
-// ---------------------------------------------------------------------------
-// Contructs a response for the test command. 
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::ConstructNetworkListResponseL()
-    {
-    TRACE_FUNC_ENTRY
-    RBuf8 reply;
-    TChar carriageReturn;
-    TChar lineFeed;
-
-    TInt maxItemSize(KMaxNetworkReadResponseAdditionalSize  
-            + KShortOperatorNameFormatLength 
-            + KLongOperatorNameFormatLength 
-            + KNumericOperatorNameFormatLength
-            + KSupportedModesStr().Length()
-            + KSupportedFormatsStr().Length()); 
-
-    CleanupClosePushL(reply); 
-
-    User::LeaveIfNull(iDetectedNetworks); 
-    User::LeaveIfError(reply.Create( maxItemSize * iDetectedNetworks->Enumerate())); 
-    User::LeaveIfError(iCallback->GetCharacterValue( ECharTypeCR, carriageReturn ));
-    User::LeaveIfError(iCallback->GetCharacterValue( ECharTypeLF, lineFeed ));		
-
-    // Some PC Software expects and extra CR+LF, hence those are added twice: 
-    reply.Append( carriageReturn );
-    reply.Append( lineFeed );
-    reply.Append( carriageReturn );
-    reply.Append( lineFeed );
-    reply.Append( _L("+COPS: ") ); 
-
-    RMobilePhone::TMobilePhoneNetworkInfoV2 nwInfo; 
-    for(TInt i = 0; i < iDetectedNetworks->Enumerate(); ++i)
-        {
-		if(i > 0) // Add CR+LF after the first cycle. 
-			{
-            reply.Append( carriageReturn );
-            reply.Append( lineFeed );
-			}
-        nwInfo = iDetectedNetworks->GetEntryL(i);  
-
-        reply.Append(_L("(")); 
-        reply.AppendNum(nwInfo.iStatus); 
-        reply.Append(_L(",")); 
-		reply.Append(_L("\"")); 
-        reply.Append(nwInfo.iLongName); 
-		reply.Append(_L("\"")); 
-        reply.Append(_L(",")); 
-		reply.Append(_L("\"")); 
-        reply.Append(nwInfo.iShortName); 
-		reply.Append(_L("\"")); 
-        reply.Append(_L(",")); 
-		reply.Append(_L("\"")); 
-        reply.Append(nwInfo.iCountryCode); 
-        reply.Append(nwInfo.iNetworkId); 
-		reply.Append(_L("\"")); 
-        if(SolveAccessTechnology(nwInfo.iAccess) == KErrNone && iAccTech != EAccTechNotSet) 
-            {
-            TRACE_INFO((_L("CATCOPSCmd::ConstructNetworkListResponse() appending acc. tech. (%d)"), iAccTech));
-            reply.Append(_L(",")); 
-            reply.AppendNum(iAccTech); 
-            }
-        reply.Append(_L(")")); 
-        reply.Append(_L(",")); 
-		TRACE_INFO( _L("CATCOPSCmd::ConstructNetworkListResponse() -- entry added to reply."));
-        }
-    reply.Append(KSupportedModesStr); // Supported modes as defined in 3GPP TS 27.007 V8.4.1
-    reply.Append(KSupportedFormatsStr);  // Supported formats as defined in 3GPP TS 27.007 V8.4.1
-
-    reply.Append( carriageReturn );
-    reply.Append( lineFeed );
-
-		// Finally append the "OK". CreateOkOrErrorReply returns verbose or numeric version. 
-    RBuf8 okReply;
-    CleanupClosePushL(okReply); 
-    iCallback->CreateOkOrErrorReply( okReply, ETrue );
-    reply.Append( okReply);
-    CreateReply(ETrue, reply); 
-    CleanupStack::PopAndDestroy(&okReply);   
-    CleanupStack::PopAndDestroy(&reply);   
-    TRACE_FUNC_EXIT
-    }
-
-// ---------------------------------------------------------------------------
-// Finalises the response and sends it. 
-// ---------------------------------------------------------------------------
-//
-void CATCOPSCmd::CreateReply(TBool aIsOK, const TDesC8 &aReply) 
-    {
-    if(aIsOK == EFalse)
-        {
-        iCallback->CreateReplyAndComplete( EReplyTypeError);
-        }
-    else 
-        {
-        if(aReply.Length() > 0)
-            {
-            iCallback->CreateReplyAndComplete( EReplyTypeOther,
-                                           aReply );
-            }
-        else 
-            {
-            iCallback->CreateReplyAndComplete( EReplyTypeOk);
-            }
-        }
-    iCurrentOperation = EIdle; 
-    TRACE_FUNC_EXIT
-    }