cellular/telephonysettings/src/PSetCallDivertingBase.cpp
changeset 0 ff3b6d0fd310
child 3 a4a774cb6ea7
equal deleted inserted replaced
-1:000000000000 0:ff3b6d0fd310
       
     1 /*
       
     2 * Copyright (c) 2008-2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Implementation of CPSetCallDivertingBase class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "PSetCallDivertingBasicImpl.h"
       
    21 
       
    22 #include <badesca.h>
       
    23 #include <etelmm.h>           
       
    24 #include <e32math.h>
       
    25 #include <vmnumber.h>
       
    26 #include <e32svr.h>
       
    27 #include <featmgr.h>
       
    28 #include <centralrepository.h>
       
    29 #include <SettingsInternalCRKeys.h>
       
    30 
       
    31 #include "PsetCallDiverting.h"
       
    32 #include "PsetContainer.h"
       
    33 #include "MPsetDivertObs.h"
       
    34 #include "PsetTelephony.h"
       
    35 #include "PSetPanic.h"
       
    36 #include "MPsetRequestObs.h"
       
    37 #include "PSetUtility.h"
       
    38 #include "PhoneSettingsLogger.h"
       
    39 #include "PsetSAObserver.h"
       
    40 #include "PSetCallDivertingBase.h"
       
    41 
       
    42 //  LOCAL CONSTANTS AND MACROS
       
    43 
       
    44 // ============================ MEMBER FUNCTIONS ===============================
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 // CPSetCallDivertingBase::NewL
       
    48 // Two-phased constructor.
       
    49 // -----------------------------------------------------------------------------
       
    50 //
       
    51 CPSetCallDivertingBase* CPSetCallDivertingBase::NewL( 
       
    52         MPsetDivertObserver& aObserver, 
       
    53         RMobilePhone& aPhone,
       
    54         CPsetCallDiverting* aDivert )
       
    55     {
       
    56     CPSetCallDivertingBase* self = new ( ELeave ) CPSetCallDivertingBase( aPhone, aDivert );
       
    57     CleanupStack::PushL( self );
       
    58     self->ConstructL( aObserver );
       
    59     CleanupStack::Pop( self );
       
    60     return self;
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CPSetCallDivertingBase::~CPSetCallDivertingBase
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CPSetCallDivertingBase::~CPSetCallDivertingBase()
       
    68     {
       
    69     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::~CPSetCallDivertingBase");
       
    70     Cancel();
       
    71 
       
    72     if ( iLine )
       
    73         {
       
    74         iLine->Close();
       
    75         }
       
    76     delete iLine;   
       
    77 
       
    78     if ( iSsSettings )
       
    79         {
       
    80         iSsSettings->Cancel( ESSSettingsAls, *this ); 
       
    81         iSsSettings->Close();
       
    82         }
       
    83     delete iSsSettings;
       
    84     delete iCfInterrogator;
       
    85 
       
    86     iReqObserver = NULL;
       
    87 
       
    88     delete iRepository;
       
    89     
       
    90     if ( iFeatureManagerInitialized )
       
    91         {
       
    92         FeatureManager::UnInitializeLib();
       
    93         }
       
    94 
       
    95     __PHSLOGSTRING("[PHS]<-- CPSetCallDivertingBase::~CPSetCallDivertingBase");
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // CPSetCallDivertingBase::CPSetCallDivertingBase
       
   100 // C++ constructor can NOT contain any code, that
       
   101 // might leave.
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 CPSetCallDivertingBase::CPSetCallDivertingBase( RMobilePhone& aPhone,  CPsetCallDiverting* aDivert  ) : 
       
   105                     CActive ( EPriorityStandard ),
       
   106                     iPhone ( aPhone ),
       
   107                     iDivert( aDivert )
       
   108     {
       
   109     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::CPSetCallDivertingBase");
       
   110     iFeatureManagerInitialized = EFalse;
       
   111     __PHSLOGSTRING("[PHS]<-- CPSetCallDivertingBase::CPSetCallDivertingBase");
       
   112     }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // CPSetCallDivertingBase::ConstructL
       
   116 // Symbian 2nd phase constructor can leave.
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 void CPSetCallDivertingBase::ConstructL( MPsetDivertObserver& aObserver )
       
   120     {
       
   121     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::ConstructL" );
       
   122     iLine = new ( ELeave ) RMobileLine;
       
   123 
       
   124     //Copy received information to member variable.
       
   125     iObserver = &aObserver;
       
   126     
       
   127     CActiveScheduler::Add( this );
       
   128 
       
   129     //Check which line is used, or if ALS is not active.
       
   130     TInt usedLine = ESSSettingsAlsNotSupported;
       
   131 
       
   132     iSsSettings = new (ELeave) RSSSettings;
       
   133     User::LeaveIfError( iSsSettings->Open() );
       
   134     TRAPD( err, iSsSettings->Register( ESSSettingsAls, *this ) );
       
   135     if ( err == KErrNone )
       
   136         {
       
   137         iSsSettings->Get( ESSSettingsAls, usedLine );
       
   138         }
       
   139 
       
   140     iAls = static_cast <TSSSettingsAlsValue> ( usedLine );
       
   141     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::ConstructL: usedLine: %d", usedLine );
       
   142 
       
   143     iRepository = CRepository::NewL( KCRUidCallForwarding );
       
   144 
       
   145     // Sets up TLS, must be done before FeatureManager is used.
       
   146     FeatureManager::InitializeLibL();
       
   147     iFeatureManagerInitialized = ETrue;
       
   148     
       
   149     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::ConstructL" );
       
   150     }
       
   151 
       
   152 // ---------------------------------------------------------------------------
       
   153 // RunL
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 void CPSetCallDivertingBase::RunL()
       
   157     {
       
   158     // Empty implementation.
       
   159     }
       
   160        
       
   161 // ---------------------------------------------------------------------------
       
   162 // DoCancel
       
   163 // ---------------------------------------------------------------------------
       
   164 //
       
   165 void CPSetCallDivertingBase::DoCancel()
       
   166     {
       
   167     // Empty implementation.
       
   168     }
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // SetDivertingL
       
   172 // ---------------------------------------------------------------------------
       
   173 //
       
   174 void CPSetCallDivertingBase::SetDivertingL( const TCallDivertSetting& /*aDivert*/,  
       
   175                             TBasicServiceGroups /*aBsc*/ )
       
   176     {
       
   177     //Empty implementation.
       
   178     }
       
   179 
       
   180 // ---------------------------------------------------------------------------
       
   181 // CancelCurrentRequest
       
   182 // ---------------------------------------------------------------------------
       
   183 //
       
   184 TInt CPSetCallDivertingBase::CancelCurrentRequest()
       
   185     {
       
   186     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::CancelCurrentRequest" );
       
   187     // Set PSUI so that correct observer is used and hide requesting note.
       
   188     // When interrupting a note, does not leave.
       
   189     // This needs to be done first, since notes must be cleared from screen
       
   190     // even though request is not active.
       
   191     iObserver->SetEngineContact( iDivert );
       
   192     // Does not leave
       
   193     TRAPD( err, iObserver->HandleCFRequestingL( EFalse, ETrue ) );
       
   194 
       
   195     if ( !IsActive() || err != KErrNone )
       
   196         {
       
   197         __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::CancelCurrentRequest: KErrGeneral" );
       
   198         return KErrGeneral;
       
   199         }
       
   200     
       
   201     if ( iCFStatusCheck )
       
   202         {
       
   203         iCFStatusCheck = EFalse;
       
   204         Cancel();
       
   205         }
       
   206 
       
   207     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::CancelCurrentRequest: KErrNone" );
       
   208     return KErrNone;
       
   209     }
       
   210 
       
   211 // ---------------------------------------------------------------------------
       
   212 // Sets new default number the the default numbers list, erases the oldest one.
       
   213 // ---------------------------------------------------------------------------
       
   214 //
       
   215 TInt CPSetCallDivertingBase::SetNewDefaultNumberL( TDes& aNumber )
       
   216     {
       
   217     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::SetNewDefaultNumberL" );    
       
   218     TTelNumber oldFirst;
       
   219     TTelNumber oldSecond; 
       
   220 
       
   221     CDesC16ArrayFlat* defNumberArray = 
       
   222         new ( ELeave ) CDesC16ArrayFlat( KPSetDefaultNumberMax );
       
   223     CleanupStack::PushL( defNumberArray );
       
   224 
       
   225     TInt defNumbers = GetNumbersFromSharedDataL( iAls, *defNumberArray );
       
   226     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::SetNewDefaultNumberL: defNumbers: %d", defNumbers);
       
   227 
       
   228     if ( defNumbers > 0 ) //at least one number was fetched
       
   229         {
       
   230         //save latest divert no.
       
   231        oldFirst = defNumberArray->MdcaPoint( 0 );
       
   232         }
       
   233     if ( defNumbers > 1 ) //at least two numbers were fetched
       
   234         {
       
   235         //save second latest divert no.
       
   236         oldSecond = defNumberArray->MdcaPoint( 1 );
       
   237         }
       
   238     CleanupStack::PopAndDestroy( defNumberArray );
       
   239 
       
   240     if ( iAls != ESSSettingsAlsAlternate )
       
   241         {
       
   242         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::SetNewDefaultNumberL: !ESSSettingsAlsAlternate" );
       
   243         switch ( defNumbers ) // cases flow through
       
   244             {
       
   245             case 3:
       
   246             case 2://two default numbers
       
   247                 User::LeaveIfError( 
       
   248                     SaveKey( KSettingsCFDefaultNumber3, oldSecond ) );
       
   249             case 1://one default number
       
   250                 User::LeaveIfError( 
       
   251                     SaveKey( KSettingsCFDefaultNumber2, oldFirst ) );
       
   252             case 0://no default numbers
       
   253                 User::LeaveIfError( 
       
   254                     SaveKey( KSettingsCFDefaultNumber1, aNumber ) );
       
   255                 break;
       
   256             }
       
   257         }
       
   258     else//aux line
       
   259         {
       
   260         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::SetNewDefaultNumberL: Aux line" );
       
   261         switch ( defNumbers ) // cases flow through
       
   262             {
       
   263             case 3:
       
   264             case 2://two default numbers
       
   265                 User::LeaveIfError( 
       
   266                     SaveKey( KSettingsCFDefaultNumberAls3, oldSecond ) );
       
   267             case 1://one default number
       
   268                 User::LeaveIfError( 
       
   269                     SaveKey( KSettingsCFDefaultNumberAls2, oldFirst ) );
       
   270             case 0://no default numbers
       
   271                 User::LeaveIfError( 
       
   272                     SaveKey( KSettingsCFDefaultNumberAls1, aNumber ) );
       
   273                 break;
       
   274             default:
       
   275                 User::Leave( KErrArgument );
       
   276                 break;
       
   277             }
       
   278         } 
       
   279 
       
   280     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::SetNewDefaultNumberL" );
       
   281     return KErrNone; //return value is not used
       
   282     }
       
   283 
       
   284 // --------------------------------------------------------------------------- 
       
   285 // Saves a single value to central repository. Make sure that repository
       
   286 // is open before calling this function.
       
   287 // ---------------------------------------------------------------------------
       
   288 //
       
   289 TInt CPSetCallDivertingBase::SaveKey(
       
   290     TUint32 aKeyId,
       
   291     const TDesC& aKeyValue )
       
   292     {
       
   293     TInt error = KErrUnknown;
       
   294 
       
   295     error = iRepository->Set( aKeyId, aKeyValue );
       
   296 
       
   297     return error;
       
   298     }
       
   299 
       
   300 // ---------------------------------------------------------------------------
       
   301 // Reads used divert numbers (0-3) from shared data and fills array with them.
       
   302 // ---------------------------------------------------------------------------
       
   303 //
       
   304 TInt CPSetCallDivertingBase::GetNumbersFromSharedDataL( TInt aType, 
       
   305                 CDesC16ArrayFlat& aArray )
       
   306     {
       
   307     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::GetNumbersFromSharedDataL" );
       
   308 
       
   309     TInt amount = 0;
       
   310     TTelNumber readValue;
       
   311     aType = iAls;
       
   312     
       
   313     RArray<TUint32> keyArray( KPSetDefaultNumberMax ); 
       
   314     CleanupClosePushL( keyArray );
       
   315     //to simplify reading, append needed values to an array    
       
   316     if ( aType != ESSSettingsAlsAlternate )
       
   317         {
       
   318         keyArray.AppendL( KSettingsCFDefaultNumber1 );
       
   319         keyArray.AppendL( KSettingsCFDefaultNumber2 );
       
   320         keyArray.AppendL( KSettingsCFDefaultNumber3 );
       
   321         }
       
   322     else //auxiliary line
       
   323         {
       
   324         keyArray.AppendL( KSettingsCFDefaultNumberAls1 );
       
   325         keyArray.AppendL( KSettingsCFDefaultNumberAls2 );
       
   326         keyArray.AppendL( KSettingsCFDefaultNumberAls3 );
       
   327         }    
       
   328 
       
   329     TInt i = KErrNone;
       
   330     TInt loc = KErrNone;
       
   331     while ( i == KErrNone && loc < KPSetDefaultNumberMax )
       
   332         {
       
   333         i = iRepository->Get( keyArray.operator[]( loc ), readValue );
       
   334         if ( i == KErrNone )
       
   335             {
       
   336             HBufC16* string = static_cast <HBufC16*> ( readValue.AllocLC() );
       
   337             if ( string->Length() > 0 )
       
   338                 {
       
   339                 aArray.AppendL( *string );
       
   340                 amount++;
       
   341                 }
       
   342             CleanupStack::PopAndDestroy( string );
       
   343             }
       
   344         loc++;
       
   345         }
       
   346     CleanupStack::PopAndDestroy(); // keyArray.
       
   347 
       
   348     __PHSLOGSTRING1("[PHS] <--CPSetCallDivertingBase::GetNumbersFromSharedDataL: amount: %d", amount );
       
   349     return amount;
       
   350     }
       
   351 
       
   352 // ---------------------------------------------------------------------------
       
   353 // Gets the timer value index related to "cfnry" from shared data
       
   354 // In error cases, return default value (30).
       
   355 // ---------------------------------------------------------------------------
       
   356 //
       
   357 TInt CPSetCallDivertingBase::GetTimerValueL()
       
   358     {
       
   359     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::GetTimerValueL" );
       
   360     
       
   361     TInt timerValue = 0;
       
   362     TInt error = KErrNone;
       
   363 
       
   364     if ( iAls == ESSSettingsAlsAlternate )
       
   365         {
       
   366         error = iRepository->Get( KSettingsCFTimerValueAls, timerValue );
       
   367         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetTimerValueL: KSettingsCFTimerValueAls: %d", timerValue );
       
   368         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetTimerValueL: error: %d", error );
       
   369         }
       
   370     else
       
   371         {
       
   372         error = iRepository->Get( KSettingsCFTimerValue, timerValue );
       
   373 
       
   374         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetTimerValueL: KPsetCFTimerValue: %d", timerValue );
       
   375         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetTimerValueL: error: %d", error );
       
   376         }
       
   377     
       
   378     if ( error != KErrNone || !VerifyDelayTime( timerValue ) )
       
   379         {
       
   380         __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::GetTimerValueL: KPsetDefaultTimerValue" );
       
   381         return KPsetDefaultTimerValue;
       
   382         }
       
   383     else
       
   384         {
       
   385         __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::GetTimerValueL: timerValue" );
       
   386         return timerValue;
       
   387         }
       
   388     }
       
   389 
       
   390 // ---------------------------------------------------------------------------
       
   391 // Sets the default time for "divert when not answered" to .ini file 
       
   392 // ---------------------------------------------------------------------------
       
   393 TInt CPSetCallDivertingBase::SetTimerValueL( const TInt& aValue )
       
   394     {
       
   395     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::SetTimerValueL" );
       
   396 
       
   397     TInt retValue = KErrNone;
       
   398 
       
   399     // If delay time is not divisable by five, return.
       
   400     if ( !VerifyDelayTime( aValue ) )
       
   401         {
       
   402         return KErrArgument;
       
   403         }
       
   404 
       
   405     if ( iAls != ESSSettingsAlsAlternate )
       
   406         {
       
   407         retValue = iRepository->Set( KSettingsCFTimerValue, aValue );
       
   408         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::SetTimerValueL: KPsetCFTimerValue: %d", aValue );
       
   409         }
       
   410     else
       
   411         {
       
   412         retValue = iRepository->Set( KSettingsCFTimerValueAls, aValue );
       
   413         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::SetTimerValueL: KPsetCFTimerValueAls: %d", aValue );
       
   414         }
       
   415 
       
   416     __PHSLOGSTRING1("[PHS] <--CPSetCallDivertingBase::SetTimerValueL: retValue: %d", retValue );
       
   417     return retValue;
       
   418     }
       
   419 
       
   420 // ---------------------------------------------------------------------------
       
   421 // Verifies that delay time is divisible by five.
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 TBool CPSetCallDivertingBase::VerifyDelayTime( const TInt& aDelayTime )
       
   425     {
       
   426     TReal res = 0;
       
   427     Math::Mod( res, aDelayTime, KPsetDelayTimeDivider ); 
       
   428     return res == 0;
       
   429     }
       
   430 
       
   431 // ---------------------------------------------------------------------------
       
   432 // Swaps the most recently used number to first in the shared data file.
       
   433 // ---------------------------------------------------------------------------
       
   434 //
       
   435 void CPSetCallDivertingBase::SwapDefaultNumberL( const TInt& aLocation )
       
   436     {
       
   437     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::SwapDefaultNumberL" );
       
   438 
       
   439     if ( aLocation == KPSetFirstDefNumber )
       
   440         {
       
   441         return; //no need to reorganize, number is already first
       
   442         }
       
   443     else if ( 
       
   444         !( aLocation == KPSetSecondDefNumber || 
       
   445            aLocation == KPSetThirdDefNumber ) )
       
   446         {
       
   447         User::Leave( KErrArgument );
       
   448         }
       
   449 
       
   450     CDesC16ArrayFlat* defNumbers = 
       
   451         new ( ELeave ) CDesC16ArrayFlat( KPSetDefaultNumberMax );
       
   452     CleanupStack::PushL( defNumbers );
       
   453 
       
   454     GetNumbersFromSharedDataL( iAls, *defNumbers );
       
   455 
       
   456     if ( iAls != ESSSettingsAlsAlternate ) 
       
   457     //EGetAlsLinePrimary or Not supported or Unknown
       
   458         {
       
   459         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::SwapDefaultNumberL: !ESSSettingsAlsAlternate" );
       
   460         switch( aLocation )
       
   461             {
       
   462             case KPSetSecondDefNumber:
       
   463                 User::LeaveIfError( 
       
   464                     SaveKey( 
       
   465                         KSettingsCFDefaultNumber2, 
       
   466                         defNumbers->MdcaPoint(0) ) );
       
   467                 User::LeaveIfError( 
       
   468                     SaveKey( 
       
   469                         KSettingsCFDefaultNumber1, 
       
   470                         defNumbers->MdcaPoint(1) ) );
       
   471                 break;
       
   472             case KPSetThirdDefNumber:
       
   473                 User::LeaveIfError( 
       
   474                     SaveKey( 
       
   475                         KSettingsCFDefaultNumber2, 
       
   476                         defNumbers->MdcaPoint(0) ) );
       
   477                 User::LeaveIfError( 
       
   478                     SaveKey( 
       
   479                         KSettingsCFDefaultNumber3, 
       
   480                         defNumbers->MdcaPoint(1) ) );
       
   481                 User::LeaveIfError( 
       
   482                     SaveKey( 
       
   483                         KSettingsCFDefaultNumber1, 
       
   484                         defNumbers->MdcaPoint(2) ) );
       
   485                 break;
       
   486             default:
       
   487                 break;
       
   488             }
       
   489         }            
       
   490     else //alternate line
       
   491         {
       
   492         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::SwapDefaultNumberL: ESSSettingsAlsAlternate" );
       
   493         switch( aLocation )
       
   494             {
       
   495             case KPSetSecondDefNumber:
       
   496                 User::LeaveIfError( 
       
   497                     SaveKey( 
       
   498                         KSettingsCFDefaultNumberAls1, 
       
   499                         defNumbers->MdcaPoint(0) ) );
       
   500                 User::LeaveIfError( 
       
   501                     SaveKey( 
       
   502                         KSettingsCFDefaultNumberAls2, 
       
   503                         defNumbers->MdcaPoint(1) ) );
       
   504                 break;
       
   505             case KPSetThirdDefNumber:
       
   506                 User::LeaveIfError( 
       
   507                     SaveKey( 
       
   508                         KSettingsCFDefaultNumberAls2, 
       
   509                         defNumbers->MdcaPoint(0) ) );
       
   510                 User::LeaveIfError( 
       
   511                     SaveKey( 
       
   512                         KSettingsCFDefaultNumberAls3, 
       
   513                         defNumbers->MdcaPoint(1) ) );
       
   514                 User::LeaveIfError( 
       
   515                     SaveKey( 
       
   516                         KSettingsCFDefaultNumberAls1, 
       
   517                         defNumbers->MdcaPoint(2) ) );
       
   518                 break;
       
   519             default:
       
   520                 break;
       
   521             }
       
   522         }
       
   523     CleanupStack::PopAndDestroy( defNumbers );
       
   524     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::SwapDefaultNumberL" );
       
   525     }
       
   526 
       
   527 // ---------------------------------------------------------------------------
       
   528 // Request diverting status from network asynhronously.
       
   529 // ---------------------------------------------------------------------------
       
   530 void CPSetCallDivertingBase::GetDivertingStatusL( 
       
   531     const TServiceGroup aServiceGroup,
       
   532     const TCallDivertingCondition aCondition, 
       
   533     TBasicServiceGroups aBsc ) 
       
   534     {
       
   535     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::GetDivertingStatusL" );
       
   536 
       
   537     if ( IsActive() )
       
   538         {
       
   539         User::Leave( KErrInUse );
       
   540         }
       
   541     
       
   542     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetDivertingStatusL: aServiceGroup: %d", aServiceGroup );
       
   543     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetDivertingStatusL: aCondition: %d", aCondition );
       
   544     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetDivertingStatusL: aBsc: %d", aBsc );
       
   545 
       
   546     iCFStatusCheck = ETrue;
       
   547 
       
   548     CPsetTelephony::CheckLineModeL( aServiceGroup, &iPhone, iLine );    
       
   549     if ( !iLine->SubSessionHandle() )
       
   550         {
       
   551         User::Leave( KErrBadHandle );
       
   552         }
       
   553 
       
   554     // in these cases basic service group will not be set
       
   555     if ( !( aCondition == EDivertConditionAllCalls || 
       
   556             aCondition == EDivertConditionAllConditionalCases ) )
       
   557         {
       
   558         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::GetDivertingStatusL: CancelAll should not come here" );
       
   559         ValidateBsc( aBsc );
       
   560         }
       
   561 
       
   562     iReason = PSetUtility::GetDivertReason( aCondition );    
       
   563 
       
   564     // Start to request for status.
       
   565     if (iCfInterrogator)
       
   566         {
       
   567         delete iCfInterrogator;
       
   568         iCfInterrogator = NULL;
       
   569         }
       
   570     iCfInterrogator = CRetrieveMobilePhoneCFList::NewL( iPhone );
       
   571     iCfInterrogator->Start( 
       
   572         iStatus, 
       
   573         iReason, 
       
   574         PSetUtility::ChangeToEtelInternal( aBsc ) );
       
   575 
       
   576     StartRequestingL( EPSetGetDivertStatus );
       
   577 
       
   578     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::GetDivertingStatusL" );
       
   579     }
       
   580 
       
   581 // ---------------------------------------------------------------------------
       
   582 // Creates param list for NotifyDivertChange method.
       
   583 // ---------------------------------------------------------------------------
       
   584 //
       
   585 TCallDivertNotifySetting CPSetCallDivertingBase::CreateDivertNotifySetting( 
       
   586     TUnconditionalCFStatus aCurrentDivert, TBool aDivertChanged, 
       
   587     TBool aVoiceMbxDivert, TInt aBasic )
       
   588     {
       
   589     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase iVideoDivert    = %d", iVideoDivert );
       
   590     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase iVoiceDivert    = %d", iVoiceDivert );
       
   591     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase aVoiceMbxDivert = %d", aVoiceMbxDivert );
       
   592     
       
   593     TCallDivertNotifySetting divertNotify;
       
   594     divertNotify.Initialize();
       
   595 
       
   596     divertNotify.iPreviousCfStatus = aCurrentDivert;
       
   597     divertNotify.iCfActivated = aDivertChanged;
       
   598     
       
   599     divertNotify.iBasicServiceCode = aBasic;
       
   600 
       
   601     if ( aVoiceMbxDivert )
       
   602         {
       
   603         divertNotify.iVmbxDivert = ETrue;
       
   604         }
       
   605                
       
   606     return divertNotify;
       
   607     }
       
   608 
       
   609 // ---------------------------------------------------------------------------
       
   610 // Gets Als information
       
   611 // ---------------------------------------------------------------------------
       
   612 //
       
   613 TSelectedLine CPSetCallDivertingBase::GetSAAls()
       
   614     {
       
   615     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::GetSAAls" );
       
   616     __PHSLOGSTRING2("[PHS] iAls: %d iBsc: %d", iAls, iBsc  );
       
   617     TSelectedLine alsValue = ENotSupportedLine;
       
   618     switch ( iAls )
       
   619         {
       
   620         case ESSSettingsAlsNotSupported:
       
   621             alsValue = ENotSupportedLine;
       
   622             break;
       
   623         case ESSSettingsAlsPrimary:
       
   624             iChangeInfo.iServiceGroup == RMobilePhone::EAuxVoiceService 
       
   625                 ? ( alsValue = EAuxiliaryLine )  
       
   626                 : ( alsValue = EPrimaryLine );
       
   627             break;
       
   628         case ESSSettingsAlsAlternate:
       
   629             alsValue = EAuxiliaryLine;
       
   630             break;
       
   631         default:
       
   632             alsValue = ENotSupportedLine;
       
   633             break;
       
   634         }
       
   635     
       
   636     // If user checks/activates divert to line which is not selected currently than we have
       
   637     // to change returned alsvalue accordinly, if this is not done divert icon status is updated to wrong status.
       
   638     // Example case: Line 2 active user activates divert to line 1: **21*phonenumber*11#.
       
   639     if ( iBsc == EAltTele && iAls == ESSSettingsAlsPrimary )
       
   640         {
       
   641         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::GetSAAls - Line 2 divert activation/check from Line 1" );
       
   642         alsValue = EAuxiliaryLine;
       
   643         }
       
   644     else if ( iBsc == ETelephony && iAls == ESSSettingsAlsAlternate )
       
   645         {
       
   646         __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::GetSAAls - Line 1 divert activation/check from Line 2" );
       
   647         alsValue = EPrimaryLine;
       
   648         }
       
   649     
       
   650     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::GetSAAls: alsValue: %d", alsValue );
       
   651     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::GetSAAls" );
       
   652     return alsValue;
       
   653     }
       
   654 
       
   655 // ---------------------------------------------------------------------------
       
   656 // Validates used bsc, if EUnknown, updates to real value
       
   657 // ---------------------------------------------------------------------------
       
   658 //
       
   659 void CPSetCallDivertingBase::ValidateBsc( TBasicServiceGroups& aBsc )
       
   660     {
       
   661     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::ValidateBsc" );
       
   662     if ( aBsc == EUnknown )
       
   663     // if bsc is unknown, update it
       
   664         {
       
   665         if ( iAls == ESSSettingsAlsAlternate )
       
   666             {
       
   667             aBsc = EAltTele;
       
   668             }
       
   669         else
       
   670             {
       
   671             aBsc = ETelephony;
       
   672             }
       
   673         }    
       
   674     else
       
   675     // If no specific line is indicated
       
   676         {
       
   677         if ( aBsc == EAllTeleAndBearer ||
       
   678              aBsc == EAllTele )
       
   679             {
       
   680             // if ALS is used, use 89 bsc
       
   681             if ( iAls == ESSSettingsAlsAlternate )
       
   682                 {
       
   683                 aBsc = EAltTele;
       
   684                 }
       
   685             }
       
   686         }
       
   687     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::ValidateBsc" );
       
   688     }
       
   689 
       
   690 // ---------------------------------------------------------------------------
       
   691 // Starts requesting
       
   692 // ---------------------------------------------------------------------------
       
   693 //
       
   694 void CPSetCallDivertingBase::StartRequestingL( const TInt& aRequest )
       
   695     {
       
   696     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::StartRequestingL" );
       
   697     if ( aRequest != KPsetRequestAlreadySet )
       
   698         {
       
   699         SetRequestStatus( static_cast <TPSetDivertRequest> ( aRequest ) );
       
   700         }
       
   701     
       
   702     SetActive();
       
   703 
       
   704     iObserver->SetEngineContact( iDivert );
       
   705 
       
   706     CleanupLeavePushL();    
       
   707     iObserver->HandleCFRequestingL( ETrue, EFalse );
       
   708     CleanupStack::Pop(); // CleanupCancelPushL
       
   709     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::StartRequestingL" );
       
   710     }
       
   711 
       
   712 // ---------------------------------------------------------------------------
       
   713 // Inform request observer that request status has changed.
       
   714 // ---------------------------------------------------------------------------
       
   715 //
       
   716 void CPSetCallDivertingBase::SetRequestStatus( TPSetDivertRequest aStatus )
       
   717     {
       
   718     iCurrentReq = aStatus;
       
   719     if ( iReqObserver )
       
   720         {
       
   721         iReqObserver->RequestStatusChanged( aStatus );
       
   722         }
       
   723     }
       
   724 
       
   725 // ---------------------------------------------------------------------------
       
   726 // If divert activation/cancellation/etc. affects more than one bsc, 
       
   727 //  inform PSUI about it.
       
   728 // ---------------------------------------------------------------------------
       
   729 TBool CPSetCallDivertingBase::IsMultiAffectingDivert( 
       
   730     const TCallDivertSetting& aDivert, TBasicServiceGroups aBsc )
       
   731     {
       
   732     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::IsMultiAffectingDivert" );
       
   733     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::IsMultiAffectingDivert: aBsc = %d", aBsc );
       
   734     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::IsMultiAffectingDivert: aDivert.iCondition = %d", aDivert.iCondition );
       
   735     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::IsMultiAffectingDivert: aDivert.iStatus = %d", aDivert.iStatus );
       
   736     __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::IsMultiAffectingDivert: aDivert.iServiceGroup = %d", aDivert.iServiceGroup );
       
   737 
       
   738     if ( iReason == RMobilePhone::ECallForwardingAllCases ||
       
   739          iReason == RMobilePhone::ECallForwardingAllConditionalCases ||
       
   740          iReason == RMobilePhone::ECallForwardingNotReachable )
       
   741         {
       
   742         __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::IsMultiAffectingDivert1" );
       
   743          return ETrue;
       
   744         }
       
   745     if ( iReason == RMobilePhone::ECallForwardingUnconditional )
       
   746         {
       
   747         //it is a MMI string
       
   748         if ( ( aBsc != EUnknown && aBsc != ETelephony ) && aDivert.iServiceGroup == EServiceGroupVoice ) 
       
   749             {
       
   750             __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::IsMultiAffectingDivert2" );
       
   751             return ETrue;
       
   752             }
       
   753         }
       
   754     
       
   755     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::IsMultiAffectingDivert3" );
       
   756     return EFalse;
       
   757     }
       
   758 
       
   759 // ---------------------------------------------------------------------------
       
   760 // Push object into cleanupstack to catch leaving.
       
   761 // ---------------------------------------------------------------------------
       
   762 //
       
   763 void CPSetCallDivertingBase::CleanupLeavePushL()
       
   764       {
       
   765       CleanupStack::PushL( TCleanupItem( DoHandleLeave, this ) );
       
   766       }
       
   767 
       
   768 // ---------------------------------------------------------------------------
       
   769 // Object has caused a leave.
       
   770 // ---------------------------------------------------------------------------
       
   771 //
       
   772 void CPSetCallDivertingBase::DoHandleLeave( TAny* aAny )
       
   773       {
       
   774       REINTERPRET_CAST( CPSetCallDivertingBasicImpl*, aAny )->HandleLeave();
       
   775       }
       
   776 
       
   777 // ---------------------------------------------------------------------------
       
   778 // Things to do when leave occurs.
       
   779 // ---------------------------------------------------------------------------
       
   780 //
       
   781 void CPSetCallDivertingBase::HandleLeave()
       
   782     {
       
   783     CancelCurrentRequest();
       
   784     }
       
   785 
       
   786 // ---------------------------------------------------------------------------
       
   787 // Inform the request observer that request has been completed.
       
   788 // ---------------------------------------------------------------------------
       
   789 //
       
   790 void CPSetCallDivertingBase::RequestCompleted( const TInt& aError )
       
   791     {
       
   792     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::RequestCompleted" );
       
   793     if ( aError != KErrNone )
       
   794         {
       
   795         SetRequestStatus( static_cast <TPSetDivertRequest> (aError) );
       
   796         }
       
   797     SetRequestStatus( EPSetNone );    
       
   798     iVoiceDivert = EFalse;
       
   799 
       
   800     if ( iReqObserver )
       
   801         {
       
   802         iReqObserver->RequestComplete(); 
       
   803         }
       
   804     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::RequestCompleted" );
       
   805     }
       
   806 
       
   807 // ---------------------------------------------------------------------------
       
   808 // Verifies whether the divert-to number is to voice mail box.
       
   809 // ---------------------------------------------------------------------------
       
   810 //
       
   811 TBool CPSetCallDivertingBase::IsVMBXDivertL( TDesC& aTelNumber )
       
   812     {
       
   813     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::IsVMBXDivertL" );
       
   814     
       
   815     TBool result = EFalse;
       
   816     
       
   817     if ( FeatureManager::FeatureSupported ( KFeatureIdVmbxCallDivertIcon ) )
       
   818         {
       
   819         RVmbxNumber vmbxConnection;
       
   820         TTelNumber telNumber;
       
   821         TInt retValue = OpenVmbxLC( telNumber, vmbxConnection );
       
   822         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::IsVMBXDivertL: telNumber = %S", &telNumber );
       
   823         __PHSLOGSTRING1("[PHS]    CPSetCallDivertingBase::IsVMBXDivertL: retValue = %d", retValue );
       
   824 
       
   825         CleanupStack::PopAndDestroy(); //vmbxConnection is closed when popped    
       
   826         if ( retValue == KErrNone ) //VMBX number found
       
   827             {
       
   828             
       
   829             //Concatenate the existing number and add '*' to the beginning
       
   830             TTelNumber tempStr;
       
   831             tempStr.Zero();
       
   832             tempStr.Append( KPSetAsterisk );
       
   833         
       
   834             //Match with seven characters
       
   835             TInt matchChars = KPsetMatchingChars;
       
   836             if ( telNumber.Length() < matchChars )
       
   837                 {                
       
   838                 matchChars = telNumber.Length();
       
   839                 }
       
   840             tempStr.Append( telNumber.Right( matchChars ) );
       
   841         
       
   842             //Compare value with divert-to number
       
   843             if ( aTelNumber.Match ( tempStr ) != KErrNotFound )
       
   844                 {
       
   845                 __PHSLOGSTRING("[PHS]    CPSetCallDivertingBase::IsVMBXDivertL: Match found" );
       
   846                 result = ETrue;
       
   847                 }
       
   848             }
       
   849         }
       
   850     __PHSLOGSTRING("[PHS] <--CPSetCallDivertingBase::IsVMBXDivertL" );
       
   851     return result;
       
   852     }
       
   853 
       
   854 // ---------------------------------------------------------------------------
       
   855 // Opens Vmbx. Leaves vmbx to the stack.  
       
   856 // ---------------------------------------------------------------------------
       
   857 TInt CPSetCallDivertingBase::OpenVmbxLC( TDes& aTelNumber, RVmbxNumber& aVmbx )
       
   858     {
       
   859     __PHSLOGSTRING("[PHS]--> CPSetCallDivertingBase::OpenVmbxLC" );
       
   860     User::LeaveIfError( aVmbx.Open( iPhone ) );
       
   861     CleanupClosePushL( aVmbx );         
       
   862     __PHSLOGSTRING("[PHS]<-- CPSetCallDivertingBase::OpenVmbxLC" );
       
   863     return aVmbx.GetVmbxNumber( aTelNumber );
       
   864     }
       
   865 
       
   866 // ---------------------------------------------------------------------------
       
   867 // If SsSettings notifies of settings change, copy new value to member variable. 
       
   868 // ---------------------------------------------------------------------------
       
   869 void CPSetCallDivertingBase::PhoneSettingChanged( 
       
   870     TSSSettingsSetting aSetting, TInt aNewValue )
       
   871     {
       
   872     __PHSLOGSTRING2("[PHS]--> CPSetCallDivertingBase::PhoneSettingChanged ESSSettingsAls: %d, aNewValue: %d", aSetting, aNewValue );
       
   873     if ( aSetting == ESSSettingsAls )
       
   874         {
       
   875         iAls = static_cast <TSSSettingsAlsValue> (aNewValue);
       
   876         }
       
   877     __PHSLOGSTRING("[PHS]<-- CPSetCallDivertingBase::PhoneSettingChanged" );
       
   878     }
       
   879 
       
   880 // End of File