diff -r f7fbeaeb166a -r b23265fb36da cbsatplugin/atmisccmdplugin/src/clckcommandhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbsatplugin/atmisccmdplugin/src/clckcommandhandler.cpp Tue Apr 27 16:49:44 2010 +0300 @@ -0,0 +1,764 @@ +/* + * Copyright (c) 2010 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 : + * + */ + +#include "clckcommandhandler.h" + +#include +#include + +#include "securitycodeverifier.h" +#include "securityeventhandler.h" +#include "cbsettinghandler.h" + +#include "atmisccmdpluginconsts.h" +#include "debug.h" + +const TInt KSCPMaxHashLength( 32 ); + +CCLCKCommandHandler* CCLCKCommandHandler::NewL(MATMiscCmdPlugin* aCallback, TAtCommandParser& aATCmdParser, RMobilePhone& aPhone) + { + TRACE_FUNC_ENTRY + CCLCKCommandHandler* self = new (ELeave) CCLCKCommandHandler(aCallback, aATCmdParser, aPhone); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + TRACE_FUNC_EXIT + return self; + } + +CCLCKCommandHandler::CCLCKCommandHandler(MATMiscCmdPlugin* aCallback, TAtCommandParser& aATCmdParser, RMobilePhone& aPhone) : + CATCmdAsyncBase(aCallback, aATCmdParser, aPhone), + iLockInfoPckg(iLockInfo) + { + TRACE_FUNC_ENTRY + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::ConstructL() + { + TRACE_FUNC_ENTRY + iReply.CreateL(KDefaultCmdBufLength); + + // initialise AOs + iCBRetrieve = CRetrieveMobilePhoneCBList::NewL(iPhone); + iCBSettingHandler = CCBSettingHandler::NewL(iPhone); + iSecurityEventHandler = CSecurityEventHandler::NewL(this, iPhone); + iSecurityCodeVerifier = CSecurityCodeVerifier::NewL(this, iPhone); + + TRACE_FUNC_EXIT + } + +CCLCKCommandHandler::~CCLCKCommandHandler() + { + TRACE_FUNC_ENTRY + Cancel(); + + delete iCBRetrieve; + delete iCBSettingHandler; + delete iSecurityEventHandler; + delete iSecurityCodeVerifier; + + iPassword.Close(); + iReply.Close(); + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::DoCancel() + { + TRACE_FUNC_ENTRY + switch (iCLCKCommandType) + { + case (CCLCKCommandHandler::ECLCKLockGet): + { + iPhone.CancelAsyncRequest(EMobilePhoneGetLockInfo); + break; + } + case (CCLCKCommandHandler::ECLCKLockSet): + { + iPhone.CancelAsyncRequest(EMobilePhoneSetLockSetting); + iSecurityCodeVerifier->Cancel(); + iSecurityEventHandler->Cancel(); + break; + } + case (CCLCKCommandHandler::ECLCKBarringGet): + { + iCBRetrieve->Cancel(); + break; + } + case (CCLCKCommandHandler::ECLCKBarringSet): + { + iCBSettingHandler->Cancel(); + break; + } + } + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::HandleCommand( const TDesC8& /*aCmd*/, RBuf8& /*aReply*/, TBool /*aReplyNeeded*/) + { + TRACE_FUNC_ENTRY + TAtCommandParser::TCommandHandlerType cmdHandlerType = iATCmdParser.CommandHandlerType(); + Trace(KDebugPrintD, "cmdHandlerType: ", cmdHandlerType); + + switch (cmdHandlerType) + { + case (TAtCommandParser::ECmdHandlerTypeTest): + { + iCallback->CreateReplyAndComplete(EReplyTypeOther, KCLCKSupportedCmdsList); + break; + } + case (TAtCommandParser::ECmdHandlerTypeSet): + { + if (ParseCCLCKCommand() == KErrNone) + { + IssueCLCKCommand(); + } + else + { + iCallback->CreateReplyAndComplete(EReplyTypeError); + } + break; + } + default: + { + iCallback->CreateReplyAndComplete(EReplyTypeError); + break; + } + } + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::RunL() + { + TRACE_FUNC_ENTRY + Trace(KDebugPrintD, "iStatus.Int(): ", iStatus.Int()); + TInt err = iStatus.Int(); + if (err == KErrNone) + { + switch ( iCLCKCommandType ) + { + case (CCLCKCommandHandler::ECLCKLockGet): + { + iReply.Append(KAtCLCK); + if (iLockInfo.iStatus == RMobilePhone::EStatusUnlocked) + { + iReply.AppendNum(0); + iReply.Append(KCRLF); + } + else if (iLockInfo.iStatus == RMobilePhone::EStatusLocked) + { + iReply.AppendNum(1); + iReply.Append(KCRLF); + } + else + { + err = KErrArgument; + } + break; + } + case(CCLCKCommandHandler::ECLCKBarringGet): + { + err = ReceiveCBList(); + break; + } + case (CCLCKCommandHandler::ECLCKLockSet): + { + iLockSettingState = ELockSettingIdle; + iSecurityCodeVerifier->Cancel(); + iSecurityEventHandler->Cancel(); + break; + } + case(CCLCKCommandHandler::ECLCKBarringSet): + default: + { + // no action required + break; + } + } + } + + if (err != KErrNone) + { + if (iCLCKCommandType == CCLCKCommandHandler::ECLCKLockSet) + { + iLockSettingState =ELockSettingIdle; + iSecurityCodeVerifier->Cancel(); + iSecurityEventHandler->Cancel(); + } + iCallback->CreateCMEReplyAndComplete(err); + } + else + { + iCallback->CreateReplyAndComplete( EReplyTypeOther, iReply ); + } + + TRACE_FUNC_EXIT + } + +TInt CCLCKCommandHandler::ReceiveCBList() + { + TRACE_FUNC_ENTRY + iInfoClass = 0; + CMobilePhoneCBList* callBarringList=NULL; + TRAPD(leaveCode, callBarringList=iCBRetrieve->RetrieveListL();); + if (leaveCode != KErrNone) + { + TRACE_FUNC_EXIT + return leaveCode; + } + + TInt count = callBarringList->Enumerate(); + while (count-- > 0) + { + RMobilePhone::TMobilePhoneCBInfoEntryV1 entry; + TRAP(leaveCode, entry = callBarringList->GetEntryL(count);); + if (leaveCode != KErrNone) + { + TRACE_FUNC_EXIT + return leaveCode; + } + if (entry.iCondition == iCondition && + entry.iStatus == RMobilePhone::ECallBarringStatusActive) + { + switch (entry.iServiceGroup) + { + case(RMobilePhone::ETelephony): + { + iInfoClass |= EInfoClassVoice; + break; + } + case(RMobilePhone::EAllBearer): + { + iInfoClass |= EInfoClassData; + break; + } + case(RMobilePhone::EFaxService): + { + iInfoClass |= EInfoClassFax; + break; + } + case(RMobilePhone::EShortMessageService): + { + iInfoClass |= EInfoClassSMS; + break; + } + case(RMobilePhone::ESyncData): + { + iInfoClass |= EInfoClassSyncData; + break; + } + case(RMobilePhone::EAsyncData): + { + iInfoClass |= EInfoClassASyncData; + break; + } + case(RMobilePhone::EPacketData): + { + iInfoClass |= EInfoClassPacketData; + break; + } + case(RMobilePhone::EPadAccess): + { + iInfoClass |= EInfoClassPadAccess; + break; + } + } + } + } + + // There are no services with barring active - therefore report + // - status = 0 (inactive) + // - class = 7 (default value; voice, fax and data) + TInt status; + if (iInfoClass == 0) + { + status = 0; + iInfoClass = 7; // Default value, see ETSI TS 127 007 V6.9.0 (2007-06) + } + else + { + // There is at least one service with barring active - report status 1 (active) + status = 1; + } + + iReply.Append(KAtCLCK); + iReply.AppendNum(status); + iReply.Append(','); + iReply.AppendNum(iInfoClass); + iReply.Append(KCRLF); + + delete callBarringList; + TRACE_FUNC_EXIT + return KErrNone; + } + +void CCLCKCommandHandler::HandleCommandCancel() + { + TRACE_FUNC_ENTRY + Cancel(); + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::IssueCLCKCommand() + { + TRACE_FUNC_ENTRY + Trace(KDebugPrintD, "iCLCKCommandType: ", iCLCKCommandType); + iReply.Zero(); + + switch (iCLCKCommandType) + { + case (CCLCKCommandHandler::ECLCKLockGet): + { + iPhone.GetLockInfo(iStatus, iLockType, iLockInfoPckg); + SetActive(); + break; + } + case (CCLCKCommandHandler::ECLCKLockSet): + { + if (iPassword.Compare(KNullDesC8) == 0) + { + iCallback->CreateReplyAndComplete( EReplyTypeError); + } + else + { + // Set the property to ignore security events in other clients + // it allows to avoid GUI promt for security code + TInt ret = KErrNone; + // TODO: reenable when KIgnoreSecurityEvent propety definition is submitted to codeline +// if (iLockType == RMobilePhone::ELockICC) +// { +// ret = RProperty::Set(KPSUidStartup, KIgnoreSecurityEvent, EPSIgnoreSecurityEventEPin1Required); +// } +// else +// { +// ret = RProperty::Set(KPSUidStartup, KIgnoreSecurityEvent, EPSIgnoreSecurityEventEPhonePasswordRequired); +// } + Trace(KDebugPrintD, "RProperty::Set: ", ret); + if (ret == KErrNone) + { + // Start security event handler - this will notify whether a + // password is required to complete the set lock request. + iSecurityEventHandler->Start(); + + Trace(KDebugPrintD, "SetLockSetting iLockType: ", iLockType); + Trace(KDebugPrintD, "SetLockSetting iLockChange: ", iLockChange); + iPhone.SetLockSetting(iStatus, iLockType, iLockChange); + iLockSettingState = ELockSettingRequested; + SetActive(); + } + else + { + iCallback->CreateReplyAndComplete( EReplyTypeError); + } + } + break; + } + case (CCLCKCommandHandler::ECLCKBarringGet): + { + iCBRetrieve->Start(iStatus, iCondition, RMobilePhone::RMobilePhone::EInfoLocationNetwork); + SetActive(); + break; + } + case (CCLCKCommandHandler::ECLCKBarringSet): + { + if (iPassword.Compare(KNullDesC8) == 0) + { + iCallback->CreateReplyAndComplete(EReplyTypeError); + } + else + { + iCBSettingHandler->Start(iStatus, iInfoClass, iCondition, &iCBInfo); + SetActive(); + } + break; + } + default: + { + iCallback->CreateReplyAndComplete(EReplyTypeError); + break; + } + } + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::HandlePasswordVerification(TInt aError) + { + TRACE_FUNC_ENTRY + + if (aError != KErrNone) + { + iCallback->CreateCMEReplyAndComplete(aError); + Cancel(); + TRACE_FUNC_EXIT + return; + } + + switch (iLockSettingState) + { + case (ELockSettingIdle): + { + // Security code setting request has already been completed + iSecurityEventHandler->Cancel(); + break; + } + case (ELockSettingPasswordRequested): + { + // after password has been verified go back to the previous state + iLockSettingState = ELockSettingRequested; + break; + } + case (ELockSettingRequested): + default: + { + // should never be in this state + __ASSERT_DEBUG(EFalse, User::Invariant()); + break; + } + } + + TRACE_FUNC_EXIT + } + +void CCLCKCommandHandler::HandleSecurityEvent(TInt aError, RMobilePhone::TMobilePhoneSecurityEvent aSecurityEvent) + { + TRACE_FUNC_ENTRY + if (aError != KErrNone) + { + iCallback->CreateCMEReplyAndComplete(aError); + Cancel(); + TRACE_FUNC_EXIT + return; + } + + Trace(KDebugPrintD, "iLockSettingState: ", iLockSettingState); + Trace(KDebugPrintD, "aSecurityEvent: ", aSecurityEvent); + switch (iLockSettingState) + { + case (ELockSettingIdle): + { + // Set Lock request has already been completed + iSecurityCodeVerifier->Cancel(); + break; + } + case (ELockSettingRequested): + { + switch (aSecurityEvent) + { + case(RMobilePhone::EPin1Required): + case(RMobilePhone::EPhonePasswordRequired): + { + iSecurityEventHandler->Start(); + if( iSecurityCode == RMobilePhone::ESecurityCodePin1 && + aSecurityEvent == RMobilePhone::EPin1Required || + iSecurityCode == RMobilePhone::ESecurityCodePhonePassword && + aSecurityEvent == RMobilePhone::EPhonePasswordRequired) + { + // security code request has been triggered, reissue the security notification + // request and provide the code if this is expected + iSecurityCodeVerifier->Start(iPassword, iSecurityCode); + iLockSettingState =ELockSettingPasswordRequested; + } + break; + } + case(RMobilePhone::ENoICCFound): + case(RMobilePhone::EICCTerminated): + { + // No SIM present or it is unusable + iCallback->CreateCMEReplyAndComplete(aError); + Cancel(); + break; + } + default: + { + // other processes may trigger various security events, ignore them + // if not related and reissue the notification request + iSecurityEventHandler->Start(); + break; + } + } + break; + } + case (ELockSettingPasswordRequested): + { + switch (aSecurityEvent) + { + case(RMobilePhone::EPin1Verified): + { + // PIN1 has been verified, ignore if not applicable + // otherwise security event handler and security code verifier + // no longer needed + // (note that another client could have provided the PIN1) + if (iSecurityCode == RMobilePhone::ESecurityCodePin1) + { + iLockSettingState =ELockSettingRequested; + } + break; + } + case(RMobilePhone::EPhonePasswordVerified): + { + if (iSecurityCode == RMobilePhone::ESecurityCodePhonePassword) + { + iLockSettingState =ELockSettingRequested; + } + break; + } + case(RMobilePhone::ENoICCFound): + case(RMobilePhone::EICCTerminated): + { + // No SIM present or it is unusable, terminate the operation + Cancel(); + iCallback->CreateCMEReplyAndComplete(aError); + break; + } + default: + { + // other processes may trigger various security events, ignore them if not related + // and reissue the notification request + iSecurityEventHandler->Start(); + break; + } + } + break; + } + default: + { + // lock setting state value is out of boundies, complete with error + iCallback->CreateCMEReplyAndComplete(aError); + Cancel(); + break; + } + } + TRACE_FUNC_EXIT + } + +TInt CCLCKCommandHandler::ParseCCLCKCommand() + { + TRACE_FUNC_ENTRY + TCmdFacilityType facilityType = ECmdFacilityTypeUnknown; + TInt mode = 0; + TInt ret = KErrNone; + + TPtrC8 command = iATCmdParser.NextTextParam(ret); + if (!command.Compare(KNullDesC8) || ret != KErrNone) + { + TRACE_FUNC_EXIT + return KErrArgument; + } + + ret = iATCmdParser.NextIntParam(mode); + if (!command.Compare(KNullDesC8) || ret != KErrNone) + { + TRACE_FUNC_EXIT + return KErrArgument; + } + + iPassword.Create(iATCmdParser.NextTextParam(ret)); + Trace(KDebugPrintD, "NextTextParam returned: ", ret); + if (ret != KErrNone && ret != KErrNotFound) + { + TRACE_FUNC_EXIT + return KErrArgument; + } + + if (iPassword.Compare(KNullDesC8) != 0) + { + ret = iATCmdParser.NextIntParam(iInfoClass); + Trace(KDebugPrintD, "NextIntParam(iInfoClass): ", ret); + if (ret == KErrNotFound) + { + iInfoClass = 7; + } + if ((ret != KErrNone && ret != KErrNotFound ) || + iATCmdParser.NextParam().Compare(KNullDesC8) != 0) + { + TRACE_FUNC_EXIT + return KErrArgument; + } + } + + if (command.Compare(KATCLCKPS) == 0) + { + // Lock phone to SIM on/off + iSecurityCode = RMobilePhone::ESecurityCodePhonePassword; + iLockType = RMobilePhone::ELockPhoneToICC; + facilityType = ECmdFacilityTypeLock; + } + else if (command.Compare(KATCLCKSC) == 0) + { + // PIN on/off + iSecurityCode = RMobilePhone::ESecurityCodePin1; + iLockType = RMobilePhone::ELockICC; + facilityType = ECmdFacilityTypeLock; + } + else if (command.Compare(KATCLCKAO) == 0) + { + iCondition = RMobilePhone::EBarAllOutgoing; + facilityType = ECmdFacilityTypeBarring; + } + else if (command.Compare(KATCLCKOI) == 0) + { + iCondition = RMobilePhone::EBarOutgoingInternational; + facilityType = ECmdFacilityTypeBarring; + } + else if (command.Compare(KATCLCKOX) == 0) + { + iCondition = RMobilePhone::EBarOutgoingInternationalExHC; + facilityType = ECmdFacilityTypeBarring; + } + else if (command.Compare(KATCLCKAI) == 0) + { + iCondition = RMobilePhone::EBarAllIncoming; + facilityType = ECmdFacilityTypeBarring; + } + else if (command.Compare(KATCLCKIR) == 0) + { + iCondition = RMobilePhone::EBarIncomingRoaming; + facilityType = ECmdFacilityTypeBarring; + } + else if (command.Compare(KATCLCKAB) == 0) + { + iCondition = RMobilePhone::EBarAllCases; + facilityType = ECmdFacilityTypeAllBarring; + } + else if (command.Compare(KATCLCKAG) == 0) + { + iCondition = RMobilePhone::EBarAllOutgoingServices; + facilityType = ECmdFacilityTypeAllBarring; + } + else if (command.Compare(KATCLCKAC) == 0) + { + iCondition = RMobilePhone::EBarAllIncomingServices; + facilityType = ECmdFacilityTypeAllBarring; + } + else + { + TRACE_FUNC_EXIT + return KErrArgument; + } + + switch (facilityType) + { + case (ECmdFacilityTypeLock): + { + switch (mode) + { + case 0: // e.g. AT+CLCK="SC",0,"0000" + { + iCLCKCommandType = ECLCKLockSet; + iLockChange = RMobilePhone::ELockSetDisabled; + break; + } + case 1: // e.g. AT+CLCK="SC",1 + { + iCLCKCommandType = ECLCKLockSet; + iLockChange = RMobilePhone::ELockSetEnabled; + break; + } + case 2: // e.g. AT+CLCK="SC",2 + { + iCLCKCommandType = ECLCKLockGet; + break; + } + default: + { + TRACE_FUNC_EXIT + return KErrArgument; + } + } + break; + } + case (ECmdFacilityTypeBarring): + { + iCBInfo.iPassword.Copy(iPassword); + if (iInfoClass == 0) + { + iInfoClass = 7; // Default value, see ETSI TS 127 007 V6.9.0 (2007-06) + } + switch (mode) + { + case 0: // AT+CLCK="AO",0 + { + iCLCKCommandType = ECLCKBarringSet; + iCBInfo.iAction = RMobilePhone::EServiceActionDeactivate; + break; + } + case 1: // AT+CLCK="AO",1,"1919",1 + { + iCLCKCommandType = ECLCKBarringSet; + iCBInfo.iAction = RMobilePhone::EServiceActionActivate; + break; + } + case 2: // AT+CLCK="AO",2 + { + iCLCKCommandType = ECLCKBarringGet; + break; + } + default: + { + TRACE_FUNC_EXIT + return KErrArgument; + } + } + break; + } + case (ECmdFacilityTypeAllBarring): + { + iCBInfo.iPassword.Copy(iPassword); + if (iInfoClass == 0) + { + iInfoClass = 7; // Default value, see ETSI TS 127 007 V6.9.0 (2007-06) + } + + if ( mode == 0) + { + iCLCKCommandType = ECLCKBarringSet; + iCBInfo.iAction = RMobilePhone::EServiceActionDeactivate; + } + else + // only deactivation is supported + { + TRACE_FUNC_EXIT + return KErrArgument; + } + break; + } + default: + { + TRACE_FUNC_EXIT + return KErrArgument; + } + } + + // if phone password is required it needs to be hashed before verification + if (iSecurityCode == RMobilePhone::ESecurityCodePhonePassword + && iCLCKCommandType == ECLCKLockSet) + { + TBuf8 hashedPwd; + iATCmdParser.HashSecurityCode(iPassword, hashedPwd); + if (hashedPwd.Length() > iPassword.MaxLength()) + { + TInt ret = iPassword.ReAlloc(hashedPwd.Length()); + if (ret != KErrNone) + { + TRACE_FUNC_EXIT + return ret; + } + } + iPassword = hashedPwd; + } + + TRACE_FUNC_EXIT + return KErrNone; + }