diff -r a249528449c3 -r 87d139e87731 localconnectivityservice/modematplugin/src/atcopscmd.cpp --- 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 -#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, , - 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(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(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& 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 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 - }