diff -r 8bda91a87a00 -r 8ee96d21d9bf gssettingsuis/Gs/GSCallDivertPlugin/Src/GSCallDivertModel.cpp --- a/gssettingsuis/Gs/GSCallDivertPlugin/Src/GSCallDivertModel.cpp Thu Aug 19 10:12:30 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,598 +0,0 @@ -/* -* Copyright (c) 2008 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: Model for call divert functionality. Tries to encapsulate -* most of hw/engine related functionality from UI components. -* -*/ - - - - -// User includes: -#include "featmgr.h" -#include "GSCallDivertModel.h" -#include "GSCallDivertView.h" -#include "GsLogger.h" -#include "GSPhoneSettingConstants.h" - - -// System includes: -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Constants for restricted call divert -const TInt KMaxLengthSendString = 40; -_LIT( KOne, "1" ); -_LIT( KAsterisk, "*" ); -_LIT( KHashMark, "#" ); -_LIT( KOneHundredTwenty, "120" ); - -// Class neme descriptor for panic descriptions -_LIT( KGSCallDivertModel, "CGSCallDivertModel" ); - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::CGSCallDivertModel -// --------------------------------------------------------------------------- -CGSCallDivertModel::CGSCallDivertModel() -{ -} - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::NewL -// --------------------------------------------------------------------------- -CGSCallDivertModel* CGSCallDivertModel::NewL() -{ - CGSCallDivertModel* self = new( ELeave ) CGSCallDivertModel; - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; -} - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::ConstructL -// --------------------------------------------------------------------------- -void CGSCallDivertModel::ConstructL() -{ - iContactEngine = CPbkContactEngine::NewL(); - if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) - { - iBasicClient = CPhCltUssd::NewL(); - } - iSettings = CPsetContainer::NewL(); - iObsContainer = CPsuiContainer::NewL(); - iCfObserver = iObsContainer->CreateCFObsL(); - iForward = iSettings->CreateCFObjectL( *iCfObserver ); - iSsSettings = new (ELeave) RSSSettings; - User::LeaveIfError( iSsSettings->Open() ); -} - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::~CGSCallDivertModel -// --------------------------------------------------------------------------- -CGSCallDivertModel::~CGSCallDivertModel() -{ - // These objects have to be deleted in specific order or otherwise a access - // violation will follow. So, if changing order, be very careful and test - // thoroughly. - delete iContactEngine; - delete iObsContainer; - delete iCfObserver; - delete iForward; - delete iSettings; - if (FeatureManager::FeatureSupported ( KFeatureIdRestrictedCallDivert ) ) - { - delete iBasicClient; - } - if( iSsSettings ) - { - iSsSettings->Close ( ); - delete iSsSettings; - } - if( iNumberGroupingRepository ) - { - delete iNumberGroupingRepository; - iNumberGroupingRepository = NULL; - } -} - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::SendCallDivertRequestL -// --------------------------------------------------------------------------- -void CGSCallDivertModel::SendCallDivertRequestL( - TCallDivertSetting& aCallDivertSetting, - RMobilePhone::TMobilePhoneServiceAction aInfo, - TBool& aVmbxDivert, - TInt aCommand, - TGSCallDivertServices aDivertService ) - { - // Set Delay time if necessary. - TInt retVal = KCFNoNeedToGetTimeValue; - - //User is doing activation - if ( aCallDivertSetting.iSetting == EActivateDiverting ) - { - if ( aCallDivertSetting.iNumber == KNullDesC ) - { - return; //User started to activate, but cancelled. - } - //Delay time needs to be set for no answer, not available. - if ( aDivertService == ECFDivertWhenNoAnswer || - aDivertService == ECFDivertWhenNotAvailable ) - { - retVal = iDivertView->CreateTimeListL(); - } - } - if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) - { - // Always ask for duration if it's restricted call divert - retVal = iDivertView->CreateTimeListL(); - } - //Call Phonesettings if all values have been set. - if ( retVal ) - { - if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) - { - __GSLOGSTRING( "[CGSCallDivertModel::SendCallDivertRequestL] -- Sending restricted call divert request: --" ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aCallDivertSetting.iNumber:%S", &aCallDivertSetting.iNumber ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] iDivertServiceGroup: %d", iDivertServiceGroup ); - - ActivateRestrictedCallDivertL( aCallDivertSetting.iNumber ); - } - else - { - __GSLOGSTRING( "[CGSCallDivertModel::SendCallDivertRequestL] -- Sending call divert request: --" ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aCallDivertSetting.iNumber:%S", &aCallDivertSetting.iNumber ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aInfo: %d", aInfo ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aVmbxDivert: %d", aVmbxDivert ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aCommand: %d", aCommand ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aDivertService: %d", aDivertService ); - __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] iDivertServiceGroup: %d", iDivertServiceGroup ); - - // Make a call to PhoneSettings. - EngineOperatorL( aCallDivertSetting, aInfo, aVmbxDivert, aCommand, aDivertService, iDivertServiceGroup ); - } - } - } - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::EngineOperatorL -// -// Seems to be a blocking function... -// Handles the engine operating, arguments tell what to call and -// the number if needed. -// --------------------------------------------------------------------------- -void CGSCallDivertModel::EngineOperatorL( - TCallDivertSetting& aDivert, - const RMobilePhone::TMobilePhoneServiceAction& aInfo, - TBool& aVmbxValidNumber, - TInt aCommand, - TGSCallDivertServices aDivertService, - TGSCallDivertServiceGroups aDivertServiceGroup ) - { - __GSLOGSTRING("[CGSCallDivertModel::EngineOperatorL] Start..."); - - TBasicServiceGroups bsc = EAllTeleAndBearer; - aDivert.iNoReplyTimer = 0; - - if ( aCommand == ECFCmdCancelAll ) - { - aDivert.iCondition = EDivertConditionAllCalls; - aDivert.iSetting = EEraseDiverting; - aDivert.iStatus = EDivertingStatusUnknown; - aDivert.iServiceGroup = EServiceGroupAllTeleservices; - aDivert.iNumber.Zero(); - iForward->SetDivertingL( aDivert, bsc ); - - __GSLOGSTRING("[CGSCallDivertModel::EngineOperatorL] ECFCmdCancelAll"); - return; - } - - SetDivertParametersL( aDivert, bsc, aDivertService, aDivertServiceGroup ); - __GSLOGSTRING1("[CGSCallDivertModel::EngineOperatorL] ServiceGroup: %d", bsc); - - switch ( aInfo ) - { - case RMobilePhone::EServiceActionUnspecified: - iForward->GetDivertingStatusL( aDivert.iServiceGroup, - aDivert.iCondition, - bsc ); - break; - case RMobilePhone::EServiceActionActivate: - aDivert.iSetting = EActivateDiverting; - iForward->SetDivertingL( aDivert, bsc, aVmbxValidNumber ); - break; - case RMobilePhone::EServiceActionErase: - aDivert.iSetting = EEraseDiverting; - iForward->SetDivertingL( aDivert, bsc ); - break; - case RMobilePhone::EServiceActionDeactivate: - aDivert.iSetting = ECancelDiverting; - iForward->SetDivertingL( aDivert, bsc ); - break; - case RMobilePhone::EServiceActionRegister: - aDivert.iSetting = ERegisterDiverting; - iForward->SetDivertingL( aDivert, bsc, aVmbxValidNumber ); - break; - default: - Panic ( KGSCallDivertModel, EInvalidDivertAction ); - break; - } - __GSLOGSTRING("[CGSCallDivertModel::EngineOperatorL] End."); - } - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::VoiceMailActivationL -// -// Handles activation attempts to voicemail box. -// --------------------------------------------------------------------------- -TInt CGSCallDivertModel::VoiceMailActivationL( TDes& aTelNumber ) - { - __GSLOGSTRING1("[CGSCallDivertModel::VoiceMailActivationL] aTelNumber: %S", &aTelNumber); - TRAPD( err, iForward->VoiceMailQueryL( aTelNumber ) ); - if ( err ) - { - __GSLOGSTRING1("[CGSCallDivertModel::VoiceMailActivationL] err=%d", err); - // If application is killed via FSW, contact selection query - // returns KLeaveExit. This should propagate to "root" - // application where it reaches the active scheduler loop - // and thus allows proper application exit when the loop exits. - // Therefore propagate the error to caller and do not ignore it. - if ( KLeaveExit == err ) - { - __GSLOGSTRING("[CGSCallDivertModel::VoiceMailActivationL] KLeaveExit"); - User::Leave( err ); - } - return KErrCancel; - } - //Vmbx number can be "invalid" from CF point of view, because they are allowed to - //contain special characters. These must be removed before making a divert to the - //vmbx number. - //E.g. number +35850888#45 becomes +35850888 (end is dropped). - TInt noOfInvalidChars = KCFInvalidChars().Length(); - - for ( TInt index = 0; index < noOfInvalidChars; index++ ) - { - RemoveSpecialChar( aTelNumber, KCFInvalidChars().Mid( index, 1 ) ); - } - __GSLOGSTRING1("[CGSCallDivertModel::VoiceMailActivationL] aTelNumber: %S", &aTelNumber); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::VideoMailActivationL -// -// Handles activation attempts to videomail box. -// --------------------------------------------------------------------------- -TInt CGSCallDivertModel::VideoMailActivationL( TDes& aTelNumber ) - { - __GSLOGSTRING1("[CGSCallDivertModel::VideoMailActivationL] aTelNumber: %S", &aTelNumber); - // Trapped to return KErrCancel in all cases in order to provide same - // behaviour as in VoiceMailActivationL method (Both methods can be used - // in the same manner) - TRAPD( err, iForward->VideoMailQueryL( aTelNumber ) ); - if ( err ) - { - return KErrCancel; - } - //Vmbx number can be "invalid" from CF point of view, because they are allowed to - //contain special characters. These must be removed before making a divert to the - //vmbx number. - //E.g. number +35850888#45 becomes +35850888 (end is dropped). - TInt noOfInvalidChars = KCFInvalidChars().Length(); - TPtrC invalidChars( KCFInvalidChars ); - for ( TInt index = 0; index < noOfInvalidChars; index++ ) - { - RemoveSpecialChar( aTelNumber, TPtrC( &invalidChars[ index ] ) ); - } - __GSLOGSTRING1("[CGSCallDivertModel::VideoMailActivationL] aTelNumber: %S", &aTelNumber); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::ActivateRestrictedCallDivertL -// -// Handles attempts to activate call divert in restricted mode -// --------------------------------------------------------------------------- -void CGSCallDivertModel::ActivateRestrictedCallDivertL( - TTelNumber& aDivertNumber ) - { - if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) - { - //Send Number and ringing time to network by using USSD. - HBufC* sendString = HBufC::NewLC( KMaxLengthSendString ); - TPtr ptr = sendString->Des(); - - //Start call forwarding has following syntax: - //*120*SI1*SI2*SI3 # SEND(Start & Set CF number & Set the time (sec.)) - //where: S1 = 1 - //SI2:(CF number) - //SI3: 0 - 120(ringing time (sec.)) - ptr.Append( KAsterisk ); - ptr.Append( KOneHundredTwenty ); - ptr.Append( KAsterisk ); - ptr.Append( KOne ); - ptr.Append( KAsterisk ); - ptr.Append( aDivertNumber ); - ptr.Append( KAsterisk ); - ptr.AppendNum( iForward->GetTimerValueL() ); - ptr.Append( KHashMark ); - - iBasicClient->SendUssd( *sendString ); - CleanupStack::PopAndDestroy( sendString ); - } - } - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::CheckStatusRestrictedCallDivertL -// -// Handles attempts to check divert status in restricted mode -// --------------------------------------------------------------------------- -void CGSCallDivertModel::CheckStatusRestrictedCallDivertL() - { - if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) - { - //Check call forwarding: * # 120*SI1 # SEND - HBufC* sendString = HBufC::NewLC( KMaxLengthSendString ); - TPtr ptr = sendString->Des(); - ptr.Append( KAsterisk ); - ptr.Append( KHashMark ); - ptr.Append( KOneHundredTwenty ); - ptr.Append( KAsterisk ); - ptr.Append( KOne ); - ptr.Append( KHashMark ); - iBasicClient->SendUssd( *sendString ); - CleanupStack::PopAndDestroy( sendString ); - } - } - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::CancelRestrictedCallDivertL -// -// Handles attempts to cancel call divert in restricted mode -// --------------------------------------------------------------------------- -void CGSCallDivertModel::CancelRestrictedCallDivertL() - { - if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) - { - //Cancel call forwarding: # 120*SI1 # SEND - HBufC* sendString = HBufC::NewLC( KMaxLengthSendString ); - TPtr ptr = sendString->Des(); - ptr.Append( KHashMark ); - ptr.Append( KOneHundredTwenty ); - ptr.Append( KAsterisk ); - ptr.Append( KOne ); - ptr.Append( KHashMark ); - iBasicClient->SendUssd( *sendString ); - CleanupStack::PopAndDestroy( sendString ); - } - } - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::SetDivertParametersL -// -// Sets parameters for EngineOperator function -// --------------------------------------------------------------------------- -void CGSCallDivertModel::SetDivertParametersL( - TCallDivertSetting& aDivert, - TBasicServiceGroups& aBsc, - TGSCallDivertServices aDivertService, - TGSCallDivertServiceGroups aDivertServiceGroup ) - { - aDivert.iStatus = EDivertingStatusUnknown; - //complains for ambiguous definition of EUnknown - //need to correct in PhoneSettings. - aBsc = ( TBasicServiceGroups )-1; - - if ( aDivertServiceGroup == EGSSettIdVoiceDivert ) - { - aDivert.iServiceGroup = EServiceGroupVoice; - } - else - { - aDivert.iServiceGroup = EServiceGroupData; - aBsc = EAllBearer; - } - - switch ( aDivertService ) - { - case ECFDivertVoiceCalls: - { - aDivert.iCondition = EDivertConditionUnconditional; - TInt alsLine = ESSSettingsAlsNotSupported; - TInt alsError = iSsSettings->Get( ESSSettingsAls, alsLine ); - if ( alsLine == ESSSettingsAlsNotSupported || ( alsLine == ESSSettingsAlsPrimary ) ) - { - // Etelephony only activates voice service nothing else or causes - // voice service status request. - aBsc = ETelephony; - } - else // ESSSettingsAlsAlternate - { - // EAltTele only activates alternate service nothing else or causes - // alternate service status request. - aBsc = EAltTele; - } - break; - } - case ECFDivertWhenBusy: - aDivert.iCondition = EDivertConditionBusy; - break; - case ECFDivertWhenNoAnswer: - aDivert.iCondition = EDivertConditionNoReply; - aDivert.iNoReplyTimer = iForward->GetTimerValueL(); - break; - case ECFDivertWhenOutOfReach: - aDivert.iCondition = EDivertConditionNotReachable; - break; - case ECFDivertWhenNotAvailable: - aDivert.iCondition = EDivertConditionAllConditionalCases; - aDivert.iNoReplyTimer = iForward->GetTimerValueL(); - break; - case ECFDivertVideoCalls: - aBsc = EAllBearer; - aDivert.iCondition = EDivertConditionUnconditional; - break; - default: - Panic ( KGSCallDivertModel, EInvalidCurrentItem ); - break; - } - } - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::MatchNumberToContactLC -// -// Returns the contact name matching the number, or the number if -// no contact name is found. -// Pushes the found (i.e. returned) name into Cleanupstack. -// @see CContactDatabase::MatchPhoneNumberL(const TDesC&,const TInt) -// --------------------------------------------------------------------------- -HBufC* CGSCallDivertModel::MatchNumberToContactLC( const TDesC& aTelNum ) - { - CContactIdArray* idArray = iContactEngine->MatchPhoneNumberL( - aTelNum, - KCFCharactersToMatch ); - CleanupStack::PushL( idArray ); - HBufC* contactTitle = NULL; - // fill data only if only single match is found - TInt matches = idArray->Count(); - TBool conflict = EFalse; - if ( matches >= KCFSingleContact ) - { - //several matches, have to check that id is the same - if ( matches != KCFSingleContact ) - { - for ( TInt i = 1 ; i < matches ; i++ ) - { - //all have to have same ID - if ( (*idArray)[i] != (*idArray)[0] ) - { - conflict = ETrue; - break; //stop comparing - } - } - } - //Contact names are only shown if single match with same ID. - if ( !conflict ) - { - CPbkContactItem* pbkItem = - iContactEngine->ReadContactLC( ( *idArray )[0] ); - contactTitle = iContactEngine->GetContactTitleL( *pbkItem ); - CleanupStack::PopAndDestroy( pbkItem ); - } - } - CleanupStack::PopAndDestroy( idArray ); - CleanupStack::PushL( contactTitle ); - if( contactTitle ) - { - __GSLOGSTRING1("[CGSCallDivertModel::MatchNumberToContactLC] contactTitle: %S", &contactTitle); - } - return contactTitle; - } - - -// --------------------------------------------------------------------------- -// Removes a special character from vmbx number. -// --------------------------------------------------------------------------- -void CGSCallDivertModel::RemoveSpecialChar( TDes& aVmbxNumber, - const TDesC& aSpecChar ) - { - TInt location = aVmbxNumber.Find( aSpecChar ); - if ( location != KErrNotFound ) - { - aVmbxNumber = aVmbxNumber.Left( location ); - } - } - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::DivertHandler -// --------------------------------------------------------------------------- -CPsetCallDiverting* CGSCallDivertModel::DivertHandler() - { - return iForward; - } - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::SetDivertView -// --------------------------------------------------------------------------- -void CGSCallDivertModel::SetDivertView( CGSCallDivertView* aDivertView ) - { - iDivertView = aDivertView; - } - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::CGSCallDivertModel -// --------------------------------------------------------------------------- -TGSCallDivertServiceGroups CGSCallDivertModel::DivertServiceGroup() - { - return iDivertServiceGroup; - } - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::SetDivertServiceGroup -// --------------------------------------------------------------------------- -void CGSCallDivertModel::SetDivertServiceGroup( - TGSCallDivertServiceGroups aDivertServiceGroup ) - { - iDivertServiceGroup = aDivertServiceGroup; - __GSLOGSTRING1( "[CGSCallDivertModel::SetDivertServiceGroup] aDivertServiceGroup:%d ", - aDivertServiceGroup ) - } - - - -// --------------------------------------------------------------------------- -// CGSCallDivertModel::NumberGroupingSupportedL -// -// --------------------------------------------------------------------------- -TBool CGSCallDivertModel::NumberGroupingSupportedL() - { - TInt numberGroupingVal; - TBool retVal = EFalse; - if( !iNumberGroupingRepository ) - { - iNumberGroupingRepository = CRepository::NewL( KCRUidNumberGrouping ); - } - iNumberGroupingRepository->Get( KNumberGrouping, numberGroupingVal ); - switch( numberGroupingVal ) - { - case CPNGNumberGrouping::ENumberGroupingDisabled: - retVal = EFalse; - break; - case CPNGNumberGrouping::ENumberGroupingEnabled: - retVal = ETrue; - break; - default: - retVal = EFalse; - break; - } - return retVal; - } -