gssettingsuis/Gs/GSCallDivertPlugin/Src/GSCallDivertModel.cpp
changeset 68 13e71d907dc3
parent 0 8c5d936e5675
equal deleted inserted replaced
40:6465d5bb863a 68:13e71d907dc3
       
     1 /*
       
     2 * Copyright (c) 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:  Model for call divert functionality. Tries to encapsulate
       
    15 *                 most of hw/engine related functionality from UI components.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // User includes:
       
    23 #include "featmgr.h"
       
    24 #include "GSCallDivertModel.h"
       
    25 #include "GSCallDivertView.h"
       
    26 #include "GsLogger.h"
       
    27 #include "GSPhoneSettingConstants.h"
       
    28 
       
    29 
       
    30 // System includes:
       
    31 #include <CPbkContactEngine.h>
       
    32 #include <CPhCltUssd.h>
       
    33 #include <MPsetDivertObs.h>
       
    34 #include <PhCltTypes.h>
       
    35 #include <PsetContainer.h>
       
    36 #include <PsuiContainer.h>
       
    37 #include <RPhCltServer.h>
       
    38 #include <RSSSettings.h>
       
    39 #include <centralrepository.h>
       
    40 #include <NumberGroupingCRKeys.h>
       
    41 #include <NumberGrouping.h>
       
    42 
       
    43 // Constants for restricted call divert
       
    44 const TInt KMaxLengthSendString = 40;
       
    45 _LIT( KOne, "1" );
       
    46 _LIT( KAsterisk, "*" );
       
    47 _LIT( KHashMark, "#" );
       
    48 _LIT( KOneHundredTwenty, "120" );
       
    49 
       
    50 // Class neme descriptor for panic descriptions
       
    51 _LIT( KGSCallDivertModel, "CGSCallDivertModel" );
       
    52 
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // CGSCallDivertModel::CGSCallDivertModel
       
    56 // ---------------------------------------------------------------------------
       
    57 CGSCallDivertModel::CGSCallDivertModel()
       
    58 {
       
    59 }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // CGSCallDivertModel::NewL
       
    63 // ---------------------------------------------------------------------------
       
    64 CGSCallDivertModel* CGSCallDivertModel::NewL()
       
    65 {
       
    66     CGSCallDivertModel* self = new( ELeave ) CGSCallDivertModel;
       
    67     CleanupStack::PushL( self );
       
    68     self->ConstructL();
       
    69     CleanupStack::Pop( self );
       
    70     return self;
       
    71 }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // CGSCallDivertModel::ConstructL
       
    75 // ---------------------------------------------------------------------------
       
    76 void CGSCallDivertModel::ConstructL()
       
    77 {
       
    78     iContactEngine = CPbkContactEngine::NewL();
       
    79     if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) )
       
    80         {
       
    81         iBasicClient = CPhCltUssd::NewL();
       
    82         }
       
    83     iSettings = CPsetContainer::NewL();
       
    84     iObsContainer = CPsuiContainer::NewL();
       
    85     iCfObserver = iObsContainer->CreateCFObsL();
       
    86     iForward = iSettings->CreateCFObjectL( *iCfObserver );
       
    87     iSsSettings = new (ELeave) RSSSettings;
       
    88     User::LeaveIfError( iSsSettings->Open() );
       
    89 }
       
    90 
       
    91 // ---------------------------------------------------------------------------
       
    92 // CGSCallDivertModel::~CGSCallDivertModel
       
    93 // ---------------------------------------------------------------------------
       
    94 CGSCallDivertModel::~CGSCallDivertModel()
       
    95 {
       
    96     // These objects have to be deleted in specific order or otherwise a access
       
    97     // violation will follow. So, if changing order, be very careful and test
       
    98     // thoroughly.
       
    99     delete iContactEngine;
       
   100     delete iObsContainer;
       
   101     delete iCfObserver;
       
   102     delete iForward;
       
   103     delete iSettings;
       
   104     if (FeatureManager::FeatureSupported ( KFeatureIdRestrictedCallDivert ) )
       
   105         {
       
   106         delete iBasicClient;
       
   107         }
       
   108     if( iSsSettings )
       
   109         {
       
   110         iSsSettings->Close ( );
       
   111         delete iSsSettings;
       
   112         }
       
   113     if( iNumberGroupingRepository )
       
   114         {
       
   115         delete iNumberGroupingRepository;
       
   116         iNumberGroupingRepository = NULL;
       
   117         }
       
   118 }
       
   119 
       
   120 // ---------------------------------------------------------------------------
       
   121 // CGSCallDivertModel::SendCallDivertRequestL
       
   122 // ---------------------------------------------------------------------------
       
   123 void CGSCallDivertModel::SendCallDivertRequestL(
       
   124     TCallDivertSetting& aCallDivertSetting,
       
   125     RMobilePhone::TMobilePhoneServiceAction aInfo,
       
   126     TBool& aVmbxDivert,
       
   127     TInt aCommand,
       
   128     TGSCallDivertServices aDivertService )
       
   129     {
       
   130     // Set Delay time if necessary.
       
   131     TInt retVal = KCFNoNeedToGetTimeValue;
       
   132 
       
   133     //User is doing activation
       
   134     if ( aCallDivertSetting.iSetting == EActivateDiverting )
       
   135         {
       
   136         if ( aCallDivertSetting.iNumber == KNullDesC )
       
   137             {
       
   138             return; //User started to activate, but cancelled.
       
   139             }
       
   140         //Delay time needs to be set for no answer, not available.
       
   141         if ( aDivertService == ECFDivertWhenNoAnswer ||
       
   142              aDivertService ==  ECFDivertWhenNotAvailable )
       
   143             {
       
   144             retVal = iDivertView->CreateTimeListL();
       
   145             }
       
   146         }
       
   147     if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) )
       
   148         {
       
   149         // Always ask for duration if it's restricted call divert
       
   150         retVal = iDivertView->CreateTimeListL();
       
   151         }
       
   152     //Call Phonesettings if all values have been set.
       
   153     if ( retVal )
       
   154         {
       
   155         if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) )
       
   156             {
       
   157             __GSLOGSTRING(  "[CGSCallDivertModel::SendCallDivertRequestL] -- Sending restricted call divert request: --" );
       
   158             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aCallDivertSetting.iNumber:%S",   &aCallDivertSetting.iNumber );
       
   159             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] iDivertServiceGroup:  %d",        iDivertServiceGroup );
       
   160 
       
   161             ActivateRestrictedCallDivertL( aCallDivertSetting.iNumber );
       
   162             }
       
   163         else
       
   164             {
       
   165             __GSLOGSTRING(  "[CGSCallDivertModel::SendCallDivertRequestL] -- Sending call divert request: --" );
       
   166             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aCallDivertSetting.iNumber:%S",   &aCallDivertSetting.iNumber );
       
   167             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aInfo:                %d",        aInfo );
       
   168             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aVmbxDivert:          %d",        aVmbxDivert );
       
   169             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aCommand:             %d",        aCommand );
       
   170             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] aDivertService:       %d",        aDivertService );
       
   171             __GSLOGSTRING1( "[CGSCallDivertModel::SendCallDivertRequestL] iDivertServiceGroup:  %d",        iDivertServiceGroup );
       
   172 
       
   173             // Make a call to PhoneSettings.
       
   174             EngineOperatorL( aCallDivertSetting, aInfo, aVmbxDivert, aCommand, aDivertService, iDivertServiceGroup );
       
   175             }
       
   176         }
       
   177     }
       
   178 
       
   179 
       
   180 // ---------------------------------------------------------------------------
       
   181 // CGSCallDivertModel::EngineOperatorL
       
   182 //
       
   183 // Seems to be a blocking function...
       
   184 // Handles the engine operating, arguments tell what to call and
       
   185 // the number if needed.
       
   186 // ---------------------------------------------------------------------------
       
   187 void CGSCallDivertModel::EngineOperatorL(
       
   188     TCallDivertSetting& aDivert,
       
   189     const RMobilePhone::TMobilePhoneServiceAction& aInfo,
       
   190     TBool& aVmbxValidNumber,
       
   191     TInt aCommand,
       
   192     TGSCallDivertServices aDivertService,
       
   193     TGSCallDivertServiceGroups aDivertServiceGroup )
       
   194     {
       
   195     __GSLOGSTRING("[CGSCallDivertModel::EngineOperatorL] Start...");
       
   196 
       
   197     TBasicServiceGroups bsc = EAllTeleAndBearer;
       
   198     aDivert.iNoReplyTimer = 0;
       
   199 
       
   200     if ( aCommand == ECFCmdCancelAll )
       
   201         {
       
   202         aDivert.iCondition = EDivertConditionAllCalls;
       
   203         aDivert.iSetting = EEraseDiverting;
       
   204         aDivert.iStatus = EDivertingStatusUnknown;
       
   205         aDivert.iServiceGroup = EServiceGroupAllTeleservices;
       
   206         aDivert.iNumber.Zero();
       
   207         iForward->SetDivertingL( aDivert, bsc );
       
   208 
       
   209         __GSLOGSTRING("[CGSCallDivertModel::EngineOperatorL] ECFCmdCancelAll");
       
   210         return;
       
   211         }
       
   212 
       
   213     SetDivertParametersL( aDivert, bsc, aDivertService, aDivertServiceGroup );
       
   214     __GSLOGSTRING1("[CGSCallDivertModel::EngineOperatorL] ServiceGroup: %d", bsc);
       
   215 
       
   216     switch ( aInfo )
       
   217         {
       
   218         case RMobilePhone::EServiceActionUnspecified:
       
   219             iForward->GetDivertingStatusL( aDivert.iServiceGroup,
       
   220                                            aDivert.iCondition,
       
   221                                            bsc );
       
   222             break;
       
   223         case RMobilePhone::EServiceActionActivate:
       
   224             aDivert.iSetting = EActivateDiverting;
       
   225             iForward->SetDivertingL( aDivert, bsc, aVmbxValidNumber );
       
   226             break;
       
   227         case RMobilePhone::EServiceActionErase:
       
   228             aDivert.iSetting = EEraseDiverting;
       
   229             iForward->SetDivertingL( aDivert, bsc );
       
   230             break;
       
   231         case RMobilePhone::EServiceActionDeactivate:
       
   232             aDivert.iSetting = ECancelDiverting;
       
   233             iForward->SetDivertingL( aDivert, bsc );
       
   234             break;
       
   235         case RMobilePhone::EServiceActionRegister:
       
   236             aDivert.iSetting = ERegisterDiverting;
       
   237             iForward->SetDivertingL( aDivert, bsc, aVmbxValidNumber );
       
   238             break;
       
   239         default:
       
   240             Panic ( KGSCallDivertModel, EInvalidDivertAction );
       
   241             break;
       
   242         }
       
   243     __GSLOGSTRING("[CGSCallDivertModel::EngineOperatorL] End.");
       
   244     }
       
   245 
       
   246 // ---------------------------------------------------------------------------
       
   247 // CGSCallDivertModel::VoiceMailActivationL
       
   248 //
       
   249 // Handles activation attempts to voicemail box.
       
   250 // ---------------------------------------------------------------------------
       
   251 TInt CGSCallDivertModel::VoiceMailActivationL( TDes& aTelNumber )
       
   252     {
       
   253     __GSLOGSTRING1("[CGSCallDivertModel::VoiceMailActivationL] aTelNumber: %S", &aTelNumber);
       
   254     TRAPD( err, iForward->VoiceMailQueryL( aTelNumber ) );
       
   255     if ( err )
       
   256         {
       
   257     	__GSLOGSTRING1("[CGSCallDivertModel::VoiceMailActivationL] err=%d", err);
       
   258     	// If application is killed via FSW, contact selection query
       
   259     	// returns KLeaveExit. This should propagate to "root"
       
   260     	// application where it reaches the active scheduler loop 
       
   261     	// and thus allows proper application exit when the loop exits.
       
   262     	// Therefore propagate the error to caller and do not ignore it.
       
   263     	if ( KLeaveExit == err )
       
   264     		{
       
   265     		__GSLOGSTRING("[CGSCallDivertModel::VoiceMailActivationL] KLeaveExit");
       
   266     		User::Leave( err );
       
   267     		}
       
   268         return KErrCancel;
       
   269         }
       
   270     //Vmbx number can be "invalid" from CF point of view, because they are allowed to
       
   271     //contain special characters. These must be removed before making a divert to the
       
   272     //vmbx number.
       
   273     //E.g. number +35850888#45 becomes +35850888 (end is dropped).
       
   274     TInt noOfInvalidChars = KCFInvalidChars().Length();
       
   275 
       
   276     for ( TInt index = 0; index < noOfInvalidChars; index++ )
       
   277         {
       
   278         RemoveSpecialChar( aTelNumber, KCFInvalidChars().Mid( index, 1 ) );
       
   279         }
       
   280     __GSLOGSTRING1("[CGSCallDivertModel::VoiceMailActivationL] aTelNumber: %S", &aTelNumber);
       
   281     return KErrNone;
       
   282     }
       
   283 
       
   284 // ---------------------------------------------------------------------------
       
   285 // CGSCallDivertModel::VideoMailActivationL
       
   286 //
       
   287 // Handles activation attempts to videomail box.
       
   288 // ---------------------------------------------------------------------------
       
   289 TInt CGSCallDivertModel::VideoMailActivationL( TDes& aTelNumber )
       
   290     {
       
   291     __GSLOGSTRING1("[CGSCallDivertModel::VideoMailActivationL] aTelNumber: %S", &aTelNumber);
       
   292     // Trapped to return KErrCancel in all cases in order to provide same
       
   293     // behaviour as in VoiceMailActivationL method (Both methods can be used
       
   294     // in the same manner)
       
   295     TRAPD( err, iForward->VideoMailQueryL( aTelNumber ) );
       
   296     if ( err )
       
   297         {
       
   298         return KErrCancel;
       
   299         }
       
   300     //Vmbx number can be "invalid" from CF point of view, because they are allowed to
       
   301     //contain special characters. These must be removed before making a divert to the
       
   302     //vmbx number.
       
   303     //E.g. number +35850888#45 becomes +35850888 (end is dropped).
       
   304     TInt noOfInvalidChars = KCFInvalidChars().Length();
       
   305     TPtrC invalidChars( KCFInvalidChars );
       
   306     for ( TInt index = 0; index < noOfInvalidChars; index++ )
       
   307         {
       
   308         RemoveSpecialChar( aTelNumber, TPtrC( &invalidChars[ index ] ) );
       
   309         }
       
   310     __GSLOGSTRING1("[CGSCallDivertModel::VideoMailActivationL] aTelNumber: %S", &aTelNumber);
       
   311     return KErrNone;
       
   312     }
       
   313 
       
   314 // ---------------------------------------------------------------------------
       
   315 // CGSCallDivertModel::ActivateRestrictedCallDivertL
       
   316 //
       
   317 // Handles attempts to activate call divert in restricted mode
       
   318 // ---------------------------------------------------------------------------
       
   319 void CGSCallDivertModel::ActivateRestrictedCallDivertL(
       
   320     TTelNumber& aDivertNumber )
       
   321     {
       
   322     if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) )
       
   323         {
       
   324         //Send Number and ringing time to network by using USSD.
       
   325         HBufC* sendString = HBufC::NewLC( KMaxLengthSendString );
       
   326         TPtr ptr = sendString->Des();
       
   327 
       
   328         //Start call forwarding has following syntax:
       
   329         //*120*SI1*SI2*SI3 # SEND(Start & Set CF number & Set the time (sec.))
       
   330         //where: S1 = 1
       
   331         //SI2:(CF number)
       
   332         //SI3: 0 - 120(ringing time (sec.))
       
   333         ptr.Append( KAsterisk );
       
   334         ptr.Append( KOneHundredTwenty );
       
   335         ptr.Append( KAsterisk );
       
   336         ptr.Append( KOne );
       
   337         ptr.Append( KAsterisk );
       
   338         ptr.Append( aDivertNumber );
       
   339         ptr.Append( KAsterisk );
       
   340         ptr.AppendNum( iForward->GetTimerValueL() );
       
   341         ptr.Append( KHashMark );
       
   342 
       
   343         iBasicClient->SendUssd( *sendString );
       
   344         CleanupStack::PopAndDestroy( sendString );
       
   345         }
       
   346     }
       
   347 
       
   348 
       
   349 // ---------------------------------------------------------------------------
       
   350 // CGSCallDivertModel::CheckStatusRestrictedCallDivertL
       
   351 //
       
   352 // Handles attempts to check divert status in restricted mode
       
   353 // ---------------------------------------------------------------------------
       
   354 void CGSCallDivertModel::CheckStatusRestrictedCallDivertL()
       
   355     {
       
   356     if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) )
       
   357         {
       
   358         //Check call forwarding: * # 120*SI1 # SEND
       
   359         HBufC* sendString = HBufC::NewLC( KMaxLengthSendString );
       
   360         TPtr ptr = sendString->Des();
       
   361         ptr.Append( KAsterisk );
       
   362         ptr.Append( KHashMark );
       
   363         ptr.Append( KOneHundredTwenty );
       
   364         ptr.Append( KAsterisk );
       
   365         ptr.Append( KOne );
       
   366         ptr.Append( KHashMark );
       
   367         iBasicClient->SendUssd( *sendString );
       
   368         CleanupStack::PopAndDestroy( sendString );
       
   369         }
       
   370     }
       
   371 
       
   372 
       
   373 // ---------------------------------------------------------------------------
       
   374 // CGSCallDivertModel::CancelRestrictedCallDivertL
       
   375 //
       
   376 // Handles attempts to cancel call divert in restricted mode
       
   377 // ---------------------------------------------------------------------------
       
   378 void CGSCallDivertModel::CancelRestrictedCallDivertL()
       
   379     {
       
   380     if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) )
       
   381         {
       
   382         //Cancel call forwarding: # 120*SI1 # SEND
       
   383         HBufC* sendString = HBufC::NewLC( KMaxLengthSendString );
       
   384         TPtr ptr = sendString->Des();
       
   385         ptr.Append( KHashMark );
       
   386         ptr.Append( KOneHundredTwenty );
       
   387         ptr.Append( KAsterisk );
       
   388         ptr.Append( KOne );
       
   389         ptr.Append( KHashMark );
       
   390         iBasicClient->SendUssd( *sendString );
       
   391         CleanupStack::PopAndDestroy( sendString );
       
   392         }
       
   393     }
       
   394 
       
   395 
       
   396 // ---------------------------------------------------------------------------
       
   397 // CGSCallDivertModel::SetDivertParametersL
       
   398 //
       
   399 // Sets parameters for EngineOperator function
       
   400 // ---------------------------------------------------------------------------
       
   401 void CGSCallDivertModel::SetDivertParametersL(
       
   402         TCallDivertSetting& aDivert,
       
   403         TBasicServiceGroups& aBsc,
       
   404         TGSCallDivertServices aDivertService,
       
   405         TGSCallDivertServiceGroups aDivertServiceGroup )
       
   406     {
       
   407     aDivert.iStatus = EDivertingStatusUnknown;
       
   408      //complains for ambiguous definition of EUnknown
       
   409      //need to correct in PhoneSettings.
       
   410     aBsc = ( TBasicServiceGroups )-1;
       
   411 
       
   412     if ( aDivertServiceGroup == EGSSettIdVoiceDivert )
       
   413         {
       
   414         aDivert.iServiceGroup = EServiceGroupVoice;
       
   415         }
       
   416     else
       
   417         {
       
   418         aDivert.iServiceGroup = EServiceGroupData;
       
   419         aBsc = EAllBearer;
       
   420         }
       
   421 
       
   422     switch ( aDivertService )
       
   423         {
       
   424         case ECFDivertVoiceCalls:
       
   425             {
       
   426             aDivert.iCondition = EDivertConditionUnconditional;
       
   427             TInt alsLine = ESSSettingsAlsNotSupported;
       
   428             TInt alsError = iSsSettings->Get( ESSSettingsAls, alsLine );
       
   429             if ( alsLine == ESSSettingsAlsNotSupported || ( alsLine == ESSSettingsAlsPrimary ) )
       
   430                 {
       
   431                 // Etelephony only activates voice service nothing else or causes
       
   432                 // voice service status request.
       
   433                 aBsc = ETelephony;
       
   434                 }
       
   435             else // ESSSettingsAlsAlternate
       
   436                 {
       
   437                 // EAltTele only activates alternate service nothing else or causes
       
   438                 // alternate service status request.
       
   439                 aBsc = EAltTele;
       
   440                 }
       
   441             break;
       
   442             }
       
   443         case ECFDivertWhenBusy:
       
   444             aDivert.iCondition = EDivertConditionBusy;
       
   445             break;
       
   446         case ECFDivertWhenNoAnswer:
       
   447             aDivert.iCondition = EDivertConditionNoReply;
       
   448             aDivert.iNoReplyTimer = iForward->GetTimerValueL();
       
   449             break;
       
   450         case ECFDivertWhenOutOfReach:
       
   451             aDivert.iCondition = EDivertConditionNotReachable;
       
   452             break;
       
   453         case ECFDivertWhenNotAvailable:
       
   454             aDivert.iCondition = EDivertConditionAllConditionalCases;
       
   455             aDivert.iNoReplyTimer = iForward->GetTimerValueL();
       
   456             break;
       
   457         case ECFDivertVideoCalls:
       
   458             aBsc = EAllBearer;
       
   459             aDivert.iCondition = EDivertConditionUnconditional;
       
   460             break;
       
   461         default:
       
   462             Panic ( KGSCallDivertModel, EInvalidCurrentItem );
       
   463             break;
       
   464         }
       
   465     }
       
   466 
       
   467 
       
   468 // ---------------------------------------------------------------------------
       
   469 // CGSCallDivertModel::MatchNumberToContactLC
       
   470 //
       
   471 // Returns the contact name matching the number, or the number if
       
   472 // no contact name is found.
       
   473 // Pushes the found (i.e. returned) name into Cleanupstack.
       
   474 // @see CContactDatabase::MatchPhoneNumberL(const TDesC&,const TInt)
       
   475 // ---------------------------------------------------------------------------
       
   476 HBufC* CGSCallDivertModel::MatchNumberToContactLC( const TDesC& aTelNum )
       
   477     {
       
   478     CContactIdArray* idArray = iContactEngine->MatchPhoneNumberL(
       
   479         aTelNum,
       
   480         KCFCharactersToMatch );
       
   481     CleanupStack::PushL( idArray );
       
   482     HBufC* contactTitle = NULL;
       
   483     // fill data only if only single match is found
       
   484     TInt matches = idArray->Count();
       
   485     TBool conflict = EFalse;
       
   486     if ( matches >= KCFSingleContact )
       
   487         {
       
   488         //several matches, have to check that id is the same
       
   489         if ( matches != KCFSingleContact )
       
   490             {
       
   491             for ( TInt i = 1 ; i < matches ; i++ )
       
   492                 {
       
   493                 //all have to have same ID
       
   494                 if ( (*idArray)[i] != (*idArray)[0] )
       
   495                     {
       
   496                     conflict = ETrue;
       
   497                     break; //stop comparing
       
   498                     }
       
   499                 }
       
   500             }
       
   501         //Contact names are only shown if single match with same ID.
       
   502         if ( !conflict )
       
   503             {
       
   504             CPbkContactItem* pbkItem =
       
   505                 iContactEngine->ReadContactLC( ( *idArray )[0] );
       
   506             contactTitle = iContactEngine->GetContactTitleL( *pbkItem );
       
   507             CleanupStack::PopAndDestroy( pbkItem );
       
   508             }
       
   509         }
       
   510     CleanupStack::PopAndDestroy( idArray );
       
   511     CleanupStack::PushL( contactTitle );
       
   512     if( contactTitle )
       
   513         {
       
   514         __GSLOGSTRING1("[CGSCallDivertModel::MatchNumberToContactLC] contactTitle: %S", &contactTitle);
       
   515         }
       
   516     return contactTitle;
       
   517     }
       
   518 
       
   519 
       
   520 // ---------------------------------------------------------------------------
       
   521 // Removes a special character from vmbx number.
       
   522 // ---------------------------------------------------------------------------
       
   523 void CGSCallDivertModel::RemoveSpecialChar( TDes& aVmbxNumber,
       
   524                                             const TDesC& aSpecChar )
       
   525     {
       
   526     TInt location = aVmbxNumber.Find( aSpecChar );
       
   527     if ( location != KErrNotFound )
       
   528         {
       
   529         aVmbxNumber = aVmbxNumber.Left( location );
       
   530         }
       
   531     }
       
   532 
       
   533 
       
   534 // ---------------------------------------------------------------------------
       
   535 // CGSCallDivertModel::DivertHandler
       
   536 // ---------------------------------------------------------------------------
       
   537 CPsetCallDiverting* CGSCallDivertModel::DivertHandler()
       
   538     {
       
   539     return iForward;
       
   540     }
       
   541 
       
   542 // ---------------------------------------------------------------------------
       
   543 // CGSCallDivertModel::SetDivertView
       
   544 // ---------------------------------------------------------------------------
       
   545 void CGSCallDivertModel::SetDivertView( CGSCallDivertView* aDivertView )
       
   546     {
       
   547     iDivertView = aDivertView;
       
   548     }
       
   549 
       
   550 // ---------------------------------------------------------------------------
       
   551 // CGSCallDivertModel::CGSCallDivertModel
       
   552 // ---------------------------------------------------------------------------
       
   553 TGSCallDivertServiceGroups CGSCallDivertModel::DivertServiceGroup()
       
   554     {
       
   555     return iDivertServiceGroup;
       
   556     }
       
   557 
       
   558 // ---------------------------------------------------------------------------
       
   559 // CGSCallDivertModel::SetDivertServiceGroup
       
   560 // ---------------------------------------------------------------------------
       
   561 void CGSCallDivertModel::SetDivertServiceGroup(
       
   562     TGSCallDivertServiceGroups aDivertServiceGroup )
       
   563     {
       
   564     iDivertServiceGroup = aDivertServiceGroup;
       
   565     __GSLOGSTRING1( "[CGSCallDivertModel::SetDivertServiceGroup] aDivertServiceGroup:%d ",
       
   566                     aDivertServiceGroup )
       
   567     }
       
   568 
       
   569 
       
   570 
       
   571 // ---------------------------------------------------------------------------
       
   572 // CGSCallDivertModel::NumberGroupingSupportedL
       
   573 //
       
   574 // ---------------------------------------------------------------------------
       
   575 TBool CGSCallDivertModel::NumberGroupingSupportedL()
       
   576     {
       
   577     TInt numberGroupingVal;
       
   578     TBool retVal = EFalse;
       
   579     if( !iNumberGroupingRepository )
       
   580         {
       
   581         iNumberGroupingRepository = CRepository::NewL( KCRUidNumberGrouping );
       
   582         }
       
   583     iNumberGroupingRepository->Get( KNumberGrouping, numberGroupingVal );
       
   584     switch( numberGroupingVal )
       
   585         {
       
   586         case CPNGNumberGrouping::ENumberGroupingDisabled:
       
   587             retVal = EFalse;
       
   588             break;
       
   589         case CPNGNumberGrouping::ENumberGroupingEnabled:
       
   590             retVal = ETrue;
       
   591             break;
       
   592         default:
       
   593             retVal = EFalse;
       
   594             break;
       
   595         }
       
   596     return retVal;
       
   597     }
       
   598