htiui/HtiServicePlugins/HtiPIMServicePlugin/src/HtiSimDirHandlerVPbk.cpp
changeset 0 d6fe6244b863
child 11 4df3a095718c
equal deleted inserted replaced
-1:000000000000 0:d6fe6244b863
       
     1 /*
       
     2 * Copyright (c) 2009 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 SIM card contacts handling using the new
       
    15 *                Virtual Phonebook API
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "HtiSimDirHandlerVPbk.h"
       
    22 #include "HtiPIMServicePlugin.h"
       
    23 
       
    24 #include <CVPbkContactManager.h>
       
    25 #include <CVPbkContactLinkArray.h>
       
    26 #include <CVPbkContactStoreUriArray.h>
       
    27 #include <CVPbkContactViewDefinition.h>
       
    28 #include <CVPbkSortOrder.h>
       
    29 #include <MVPbkContactFieldTextData.h>
       
    30 #include <MVPbkContactLink.h>
       
    31 #include <MVPbkContactOperationBase.h>
       
    32 #include <MVPbkContactStore.h>
       
    33 #include <MVPbkContactStoreInfo.h>
       
    34 #include <MVPbkContactStoreList.h>
       
    35 #include <MVPbkContactStoreProperties.h>
       
    36 #include <MVPbkContactView.h>
       
    37 #include <MVPbkContactViewBase.h>
       
    38 #include <MVPbkFieldType.h>
       
    39 #include <MVPbkStoreContact.h>
       
    40 #include <MVPbkStoreContactField.h>
       
    41 #include <MVPbkContactStoreObserver.h>
       
    42 #include <TVPbkContactStoreUriPtr.h>
       
    43 #include <TVPbkFieldVersitProperty.h>
       
    44 #include <VPbkContactStoreUris.h>
       
    45 #include <VPbkContactView.hrh>
       
    46 #include <VPbkFieldType.hrh>
       
    47 #include <VPbkEng.rsg>
       
    48 
       
    49 #include <HtiDispatcherInterface.h>
       
    50 #include <HTILogging.h>
       
    51 
       
    52 // EXTERNAL DATA STRUCTURES
       
    53 
       
    54 // EXTERNAL FUNCTION PROTOTYPES
       
    55 
       
    56 // CONSTANTS
       
    57 const TInt KSimInfoResponseLength = 12;
       
    58 
       
    59 // MACROS
       
    60 
       
    61 // LOCAL CONSTANTS AND MACROS
       
    62 _LIT8( KErrorUnrecognizedCommand, "Unrecognized command" );
       
    63 _LIT8( KErrorInvalidParameters, "Invalid command parameters" );
       
    64 _LIT8( KErrorImportFailed, "Contact import failed" );
       
    65 _LIT8( KErrorDeleteFailed, "Failed to delete contact" );
       
    66 _LIT8( KErrorSimCardInfoFailed, "Failed to get SIM card info" );
       
    67 _LIT8( KErrorSimStoreOpenFailed, "Failed to open SIM contact store" );
       
    68 _LIT8( KErrorSimStoreUnavailable, "SIM contact store unavailable" );
       
    69 
       
    70 // MODULE DATA STRUCTURES
       
    71 
       
    72 // LOCAL FUNCTION PROTOTYPES
       
    73 
       
    74 // FORWARD DECLARATIONS
       
    75 
       
    76 // ============================ MEMBER FUNCTIONS ===============================
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // CHtiSimDirHandlerVPbk::NewL
       
    80 // Two-phased constructor.
       
    81 // -----------------------------------------------------------------------------
       
    82 CHtiSimDirHandlerVPbk* CHtiSimDirHandlerVPbk::NewL()
       
    83     {
       
    84     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::NewL" );
       
    85     CHtiSimDirHandlerVPbk* self = new (ELeave) CHtiSimDirHandlerVPbk();
       
    86     CleanupStack::PushL ( self );
       
    87     self->ConstructL();
       
    88     CleanupStack::Pop();
       
    89     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::NewL" );
       
    90     return self;
       
    91     }
       
    92 
       
    93 
       
    94 // ----------------------------------------------------------------------------
       
    95 // CHtiSimDirHandlerVPbk::CHtiSimDirHandlerVPbk
       
    96 // C++ default constructor can NOT contain any code, that
       
    97 // might leave.
       
    98 // ----------------------------------------------------------------------------
       
    99 CHtiSimDirHandlerVPbk::CHtiSimDirHandlerVPbk():iIsBusy( EFalse ),
       
   100                                                iIsStoreOpen( EFalse )
       
   101     {
       
   102     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::CHtiSimDirHandlerVPbk" );
       
   103 
       
   104     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::CHtiSimDirHandlerVPbk" );
       
   105     }
       
   106 
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CHtiSimDirHandlerVPbk::~CHtiSimDirHandlerVPbk
       
   110 // Destructor.
       
   111 // -----------------------------------------------------------------------------
       
   112 CHtiSimDirHandlerVPbk::~CHtiSimDirHandlerVPbk()
       
   113     {
       
   114     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::~CHtiSimDirHandlerVPbk" );
       
   115 
       
   116     if ( iContactView )
       
   117         {
       
   118         HTI_LOG_TEXT( "Deleting iContactView" );
       
   119         iContactView->RemoveObserver( *this );
       
   120         delete iContactView;
       
   121         }
       
   122     if ( iSimStore )
       
   123         {
       
   124         HTI_LOG_TEXT( "Closing iSimStore" );
       
   125         iSimStore->Close( *this );
       
   126         }
       
   127     if ( iContactManager )
       
   128         {
       
   129         HTI_LOG_TEXT( "Deleting iContactManager" );
       
   130         delete iContactManager;
       
   131         }
       
   132     if ( iMessage )
       
   133         {
       
   134         HTI_LOG_TEXT( "Deleting iMessage" );
       
   135         delete iMessage;
       
   136         }
       
   137 
       
   138     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::~CHtiSimDirHandlerVPbk" );
       
   139     }
       
   140 
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CHtiSimDirHandlerVPbk::ConstructL
       
   144 // Symbian 2nd phase constructor can leave.
       
   145 // -----------------------------------------------------------------------------
       
   146 void CHtiSimDirHandlerVPbk::ConstructL()
       
   147     {
       
   148     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ConstructL" );
       
   149 
       
   150     CVPbkContactStoreUriArray* uriArray = CVPbkContactStoreUriArray::NewLC();
       
   151     uriArray->AppendL( TVPbkContactStoreUriPtr(
       
   152         VPbkContactStoreUris::SimGlobalAdnUri() ) );
       
   153 
       
   154     iContactManager = CVPbkContactManager::NewL( *uriArray );
       
   155     CleanupStack::PopAndDestroy( uriArray );
       
   156 
       
   157     MVPbkContactStoreList& storeList = iContactManager->ContactStoresL();
       
   158     iSimStore = storeList.Find( TVPbkContactStoreUriPtr(
       
   159         VPbkContactStoreUris::SimGlobalAdnUri() ) );
       
   160 
       
   161     if ( !iSimStore )
       
   162         {
       
   163         HTI_LOG_TEXT( "SIM ADN store not found - leaving" );
       
   164         User::Leave( KErrNotFound );
       
   165         }
       
   166 
       
   167     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ConstructL" );
       
   168     }
       
   169 
       
   170 
       
   171 // -----------------------------------------------------------------------------
       
   172 // CHtiSimDirHandlerVPbk::SetDispatcher
       
   173 // Sets the dispatcher pointer.
       
   174 // -----------------------------------------------------------------------------
       
   175 
       
   176 void CHtiSimDirHandlerVPbk::SetDispatcher( MHtiDispatcher* aDispatcher )
       
   177     {
       
   178     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::SetDispatcher" );
       
   179     iDispatcher = aDispatcher;
       
   180     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::SetDispatcher" );
       
   181     }
       
   182 
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CHtiSimDirHandlerVPbk::ProcessMessageL
       
   186 // Parses the received message and calls handler functions.
       
   187 // -----------------------------------------------------------------------------
       
   188 void CHtiSimDirHandlerVPbk::ProcessMessageL( const TDesC8& aMessage,
       
   189     THtiMessagePriority /*aPriority*/ )
       
   190     {
       
   191     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ProcessMessageL" );
       
   192 
       
   193     if ( iIsBusy )
       
   194         {
       
   195         HTI_LOG_TEXT( "HtiSimDirHandlerVPbk is busy - leaving" );
       
   196         User::Leave( KErrInUse );
       
   197         }
       
   198 
       
   199     // Will be set to EFalse in the SendOkMsgL or SendErrorMessageL methods.
       
   200     iIsBusy = ETrue;
       
   201 
       
   202     delete iMessage;
       
   203     iMessage = NULL;
       
   204 
       
   205     // Zero legth of aMessage tested already in CHtiPIMServicePlugin.
       
   206     // Other sanity checks must be done here.
       
   207 
       
   208     // Trap the AllocL to be able to set iIsBusy false before leaving.
       
   209     TRAPD( err, iMessage = aMessage.Right( aMessage.Length() - 1 ).AllocL() );
       
   210     if ( err != KErrNone )
       
   211         {
       
   212         iIsBusy = EFalse;
       
   213         User::Leave( err );
       
   214         }
       
   215 
       
   216     iCommand = aMessage.Ptr()[0];
       
   217 
       
   218     // Do basic validity checking for message
       
   219     TBool isParamsOk = ETrue;
       
   220     switch ( iCommand )
       
   221         {
       
   222         case CHtiPIMServicePlugin::ESimCardInfo:
       
   223             {
       
   224             if ( iMessage->Length() != 0 )
       
   225                 {
       
   226                 isParamsOk = EFalse;
       
   227                 }
       
   228             break;
       
   229             }
       
   230         case CHtiPIMServicePlugin::EImportSimContact:
       
   231             {
       
   232             if ( !CheckImportMsg() )
       
   233                 {
       
   234                 isParamsOk = EFalse;
       
   235                 }
       
   236             break;
       
   237             }
       
   238         case CHtiPIMServicePlugin::EDeleteSimContact:
       
   239             {
       
   240             if ( iMessage->Length() != 4 && iMessage->Length() != 0 )
       
   241                 {
       
   242                 isParamsOk = EFalse;
       
   243                 }
       
   244             break;
       
   245             }
       
   246         default:
       
   247             {
       
   248             SendErrorMessageL( KErrArgument, KErrorUnrecognizedCommand );
       
   249             return;
       
   250             }
       
   251         }
       
   252 
       
   253     if ( !isParamsOk )
       
   254         {
       
   255         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
   256         }
       
   257 
       
   258     else
       
   259         {
       
   260         if ( iIsStoreOpen )
       
   261             {
       
   262             StoreReady( *iSimStore );
       
   263             }
       
   264         else
       
   265             {
       
   266             // Start async open operation.
       
   267             // StoreReady callback will be called when opening is complete.
       
   268             TRAPD( err, iSimStore->OpenL( *this ) );
       
   269             if ( err != KErrNone )
       
   270                 {
       
   271                 HTI_LOG_FORMAT(
       
   272                         "Leave from CHtiSimDirHandler::OpenL() %d", err );
       
   273                 SendErrorMessageL( err, KErrorSimStoreOpenFailed );
       
   274                 }
       
   275             }
       
   276         }
       
   277 
       
   278     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ProcessMessageL" );
       
   279     }
       
   280 
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // CHtiSimDirHandlerVPbk::IsBusy
       
   284 // -----------------------------------------------------------------------------
       
   285 //
       
   286 TBool CHtiSimDirHandlerVPbk::IsBusy()
       
   287     {
       
   288     return iIsBusy;
       
   289     }
       
   290 
       
   291 
       
   292 // ----------------------------------------------------------------------------
       
   293 // CHtiSimDirHandlerVPbk::OpenComplete
       
   294 // Called when the opening process is complete.
       
   295 // From MVPbkContactStoreListObserver
       
   296 // ----------------------------------------------------------------------------
       
   297 /*
       
   298 void CHtiSimDirHandlerVPbk::OpenComplete()
       
   299     {
       
   300     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::OpenComplete" );
       
   301 
       
   302     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::OpenComplete" );
       
   303     }
       
   304 */
       
   305 
       
   306 // ----------------------------------------------------------------------------
       
   307 // CHtiSimDirHandlerVPbk::StoreReady
       
   308 // Called when a contact store is ready to use.
       
   309 // From MVPbkContactStoreObserver
       
   310 // ----------------------------------------------------------------------------
       
   311 void CHtiSimDirHandlerVPbk::StoreReady( MVPbkContactStore& aContactStore )
       
   312     {
       
   313     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::StoreReady" );
       
   314 
       
   315     if ( !iIsBusy || iSimStore != &aContactStore )
       
   316         {
       
   317         return;
       
   318         }
       
   319 
       
   320     iIsStoreOpen = ETrue;
       
   321 
       
   322     if ( iCommand == CHtiPIMServicePlugin::ESimCardInfo )
       
   323         {
       
   324         TRAPD( err, HandleSimCardInfoL() );
       
   325         if ( err != KErrNone )
       
   326             {
       
   327             TRAP_IGNORE( SendErrorMessageL( err, KErrorSimCardInfoFailed ) );
       
   328             }
       
   329         }
       
   330 
       
   331     else if ( iCommand == CHtiPIMServicePlugin::EImportSimContact )
       
   332         {
       
   333         TRAPD( err, HandleSimContactImportL() );
       
   334         if ( err != KErrNone )
       
   335             {
       
   336             TRAP_IGNORE( SendErrorMessageL( err, KErrorImportFailed ) );
       
   337             }
       
   338         }
       
   339 
       
   340     else if ( iCommand == CHtiPIMServicePlugin::EDeleteSimContact )
       
   341         {
       
   342         TRAPD( err, HandleSimContactDeleteL() );
       
   343         if ( err != KErrNone )
       
   344             {
       
   345             TRAP_IGNORE( SendErrorMessageL( err, KErrorDeleteFailed ) );
       
   346             }
       
   347         }
       
   348 
       
   349     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::StoreReady" );
       
   350     }
       
   351 
       
   352 
       
   353 // ----------------------------------------------------------------------------
       
   354 // CHtiSimDirHandlerVPbk::StoreUnavailable
       
   355 // Called when a contact store becomes unavailable.
       
   356 // From MVPbkContactStoreObserver
       
   357 // ----------------------------------------------------------------------------
       
   358 void CHtiSimDirHandlerVPbk::StoreUnavailable( MVPbkContactStore& aContactStore,
       
   359                                               TInt aReason )
       
   360     {
       
   361     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::StoreUnavailable" );
       
   362 
       
   363     if ( iIsBusy && iSimStore == &aContactStore )
       
   364         {
       
   365         TRAP_IGNORE( SendErrorMessageL( aReason, KErrorSimStoreUnavailable ) );
       
   366         }
       
   367 
       
   368     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::StoreUnavailable" );
       
   369     }
       
   370 
       
   371 
       
   372 // ----------------------------------------------------------------------------
       
   373 // CHtiSimDirHandlerVPbk::HandleStoreEventL
       
   374 // Called when changes occur in the contact store.
       
   375 // From MVPbkContactStoreObserver
       
   376 // ----------------------------------------------------------------------------
       
   377 void CHtiSimDirHandlerVPbk::HandleStoreEventL( MVPbkContactStore& aContactStore,
       
   378                         TVPbkContactStoreEvent aStoreEvent )
       
   379     {
       
   380     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::HandleStoreEventL" );
       
   381 
       
   382     if ( iIsBusy && iSimStore == &aContactStore &&
       
   383          aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactAdded )
       
   384         {
       
   385         HTI_LOG_TEXT( "Contact added" );
       
   386         TInt entryId = 0;
       
   387         TBuf8<4> idBuf;
       
   388         idBuf.Append( ( TUint8* ) &entryId, 4 );
       
   389         TRAP_IGNORE( SendOkMsgL( idBuf ) );
       
   390         }
       
   391 
       
   392     else if ( iIsBusy && iSimStore == &aContactStore &&
       
   393               aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactDeleted )
       
   394         {
       
   395         HTI_LOG_TEXT( "Contact deleted" );
       
   396         if ( iMessage->Length() > 0 )  // This is a single deletion
       
   397             {
       
   398             TRAP_IGNORE( SendOkMsgL( KNullDesC8 ) );
       
   399             }
       
   400         }
       
   401 
       
   402     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::HandleStoreEventL" );
       
   403     }
       
   404 
       
   405 // ----------------------------------------------------------------------------
       
   406 // CHtiSimDirHandlerVPbk::ContactOperationCompleted
       
   407 // Called when a contact operation has succesfully completed.
       
   408 // From MVPbkContactObserver
       
   409 // ----------------------------------------------------------------------------
       
   410 void CHtiSimDirHandlerVPbk::ContactOperationCompleted( TContactOpResult /*aResult*/ )
       
   411     {
       
   412     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactOperationCompleted" );
       
   413 
       
   414     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactOperationCompleted" );
       
   415     }
       
   416 
       
   417 
       
   418 // ----------------------------------------------------------------------------
       
   419 // CHtiSimDirHandlerVPbk::ContactOperationFailed
       
   420 // Called when a contact operation has failed.
       
   421 // From MVPbkContactObserver
       
   422 // ----------------------------------------------------------------------------
       
   423 void CHtiSimDirHandlerVPbk::ContactOperationFailed( TContactOp /*aOpCode*/,
       
   424                                                     TInt /*aErrorCode*/,
       
   425                                                     TBool /*aErrorNotified*/ )
       
   426     {
       
   427 
       
   428     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactOperationFailed" );
       
   429 
       
   430     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactOperationFailed" );
       
   431     }
       
   432 
       
   433 
       
   434 // ----------------------------------------------------------------------------
       
   435 // CHtiSimDirHandlerVPbk::ContactViewReady
       
   436 // Called when a view is ready for use.
       
   437 // From MVPbkContactViewObserver
       
   438 // ----------------------------------------------------------------------------
       
   439 void CHtiSimDirHandlerVPbk::ContactViewReady( MVPbkContactViewBase& aView )
       
   440     {
       
   441     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactViewReady" );
       
   442 
       
   443     if ( iContactView == &aView && iIsBusy &&
       
   444             iCommand == CHtiPIMServicePlugin::EDeleteSimContact )
       
   445         {
       
   446         TRAPD( err, DeleteContactsInViewL() );
       
   447         if ( err != KErrNone )
       
   448             {
       
   449             TRAP_IGNORE( SendErrorMessageL( err, KErrorDeleteFailed ) );
       
   450             }
       
   451         }
       
   452 
       
   453     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactViewReady" );
       
   454     }
       
   455 
       
   456 
       
   457 // ----------------------------------------------------------------------------
       
   458 // CHtiSimDirHandlerVPbk::ContactViewUnavailable
       
   459 // Called when a view is unavailable for a while.
       
   460 // From MVPbkContactViewObserver
       
   461 // ----------------------------------------------------------------------------
       
   462 void CHtiSimDirHandlerVPbk::ContactViewUnavailable( MVPbkContactViewBase& /*aView*/ )
       
   463     {
       
   464     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactViewUnavailable" );
       
   465 
       
   466     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactViewUnavailable" );
       
   467     }
       
   468 
       
   469 
       
   470 // ----------------------------------------------------------------------------
       
   471 // CHtiSimDirHandlerVPbk::ContactAddedToView
       
   472 // Called when a contact has been added to the view.
       
   473 // From MVPbkContactViewObserver
       
   474 // ----------------------------------------------------------------------------
       
   475 void CHtiSimDirHandlerVPbk::ContactAddedToView( MVPbkContactViewBase& /*aView*/,
       
   476         TInt /*aIndex*/, const MVPbkContactLink& /*aContactLink*/ )
       
   477     {
       
   478     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactAddedToView" );
       
   479 
       
   480     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactAddedToView" );
       
   481     }
       
   482 
       
   483 
       
   484 // ----------------------------------------------------------------------------
       
   485 // CHtiSimDirHandlerVPbk::ContactRemovedFromView
       
   486 // Called when a contact has been removed from a view.
       
   487 // From MVPbkContactViewObserver
       
   488 // ----------------------------------------------------------------------------
       
   489 void CHtiSimDirHandlerVPbk::ContactRemovedFromView( MVPbkContactViewBase& /*aView*/,
       
   490         TInt /*aIndex*/, const MVPbkContactLink& /*aContactLink*/ )
       
   491     {
       
   492     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactRemovedFromView" );
       
   493 
       
   494     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactRemovedFromView" );
       
   495     }
       
   496 
       
   497 
       
   498 // ----------------------------------------------------------------------------
       
   499 // CHtiSimDirHandlerVPbk::ContactViewError
       
   500 // Called when an error occurs in the view.
       
   501 // From MVPbkContactViewObserver
       
   502 // ----------------------------------------------------------------------------
       
   503 void CHtiSimDirHandlerVPbk::ContactViewError( MVPbkContactViewBase& aView,
       
   504                                               TInt aError,
       
   505                                               TBool aErrorNotified )
       
   506     {
       
   507     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::ContactViewError" );
       
   508     HTI_LOG_FORMAT( "CHtiSimDirHandlerVPbk::ContactViewError: %d", aError );
       
   509     HTI_LOG_FORMAT( "ErrorNotified = %d", aErrorNotified );
       
   510     if ( iContactView == &aView )
       
   511         {
       
   512         iContactView->RemoveObserver( *this );
       
   513         if ( iIsBusy && iCommand == CHtiPIMServicePlugin::EDeleteSimContact )
       
   514             {
       
   515             SendErrorMessageL( aError, KErrorDeleteFailed );
       
   516             }
       
   517         }
       
   518     aErrorNotified = aErrorNotified;  // avoid compiler warning
       
   519     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::ContactViewError" );
       
   520     }
       
   521 
       
   522 
       
   523 // ----------------------------------------------------------------------------
       
   524 // CHtiSimDirHandlerVPbk::StepComplete
       
   525 // Called when one step of the batch operation is complete.
       
   526 // From MVPbkBatchOperationObserver
       
   527 // ----------------------------------------------------------------------------
       
   528 void CHtiSimDirHandlerVPbk::StepComplete( MVPbkContactOperationBase& /*aOperation*/,
       
   529                            TInt aStepSize )
       
   530     {
       
   531     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::StepComplete" );
       
   532     HTI_LOG_FORMAT( "Step size = %d", aStepSize );
       
   533     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::StepComplete" );
       
   534     aStepSize = aStepSize; // avoid compiler warning
       
   535     }
       
   536 
       
   537 
       
   538 // ----------------------------------------------------------------------------
       
   539 // CHtiSimDirHandlerVPbk::StepFailed
       
   540 // Called when one step of the batch operation fails.
       
   541 // From MVPbkBatchOperationObserver
       
   542 // ----------------------------------------------------------------------------
       
   543 TBool CHtiSimDirHandlerVPbk::StepFailed( MVPbkContactOperationBase& aOperation,
       
   544                                          TInt aStepSize, TInt aError )
       
   545     {
       
   546     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::StepFailed" );
       
   547     HTI_LOG_FORMAT( "Error %d", aError );
       
   548     if ( iCurrentOperation == &aOperation )
       
   549         {
       
   550         // We are returning EFalse (= do not continue) we can delete
       
   551         // the operation. OperationComplete() won't be called.
       
   552         delete iCurrentOperation;
       
   553         iCurrentOperation = NULL;
       
   554         TRAP_IGNORE( SendErrorMessageL( aError, KErrorDeleteFailed ) );
       
   555         }
       
   556     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::StepFailed" );
       
   557     aStepSize = aStepSize; // avoid compiler warning
       
   558     return EFalse; // do not continue
       
   559     }
       
   560 
       
   561 
       
   562 // ----------------------------------------------------------------------------
       
   563 // CHtiSimDirHandlerVPbk::OperationComplete
       
   564 // Called when operation is completed.
       
   565 // From MVPbkBatchOperationObserver
       
   566 // ----------------------------------------------------------------------------
       
   567 void CHtiSimDirHandlerVPbk::OperationComplete(
       
   568             MVPbkContactOperationBase& aOperation )
       
   569     {
       
   570     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::OperationComplete" );
       
   571     // Operation is complete -> delete it
       
   572     if ( iCurrentOperation == &aOperation )
       
   573         {
       
   574         delete iCurrentOperation;
       
   575         iCurrentOperation = NULL;
       
   576         if ( iIsBusy && iCommand == CHtiPIMServicePlugin::EDeleteSimContact )
       
   577             {
       
   578             // Delete operation has completed
       
   579             TRAP_IGNORE( SendOkMsgL( KNullDesC8 ) );
       
   580             }
       
   581         }
       
   582     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::OperationComplete" );
       
   583     }
       
   584 
       
   585 
       
   586 // ----------------------------------------------------------------------------
       
   587 // CHtiSimDirHandlerVPbk::HandleSimCardInfoL
       
   588 // Gets information about the SIM card.
       
   589 // ----------------------------------------------------------------------------
       
   590 void CHtiSimDirHandlerVPbk::HandleSimCardInfoL()
       
   591     {
       
   592     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::HandleSimCardInfoL" );
       
   593 
       
   594     // Get entry counts
       
   595     const MVPbkContactStoreInfo& info = iSimStore->StoreInfo();
       
   596     TInt maxEntries = info.MaxNumberOfContactsL();
       
   597     TInt currentEntries = info.NumberOfContactsL();
       
   598     HTI_LOG_FORMAT( "Current entries = %d", currentEntries );
       
   599     HTI_LOG_FORMAT( "Max entries = %d", maxEntries );
       
   600 
       
   601     // Create new entry object to get field informations
       
   602     MVPbkStoreContact* entry = iSimStore->CreateNewContactLC();
       
   603     TVPbkFieldVersitProperty prop;
       
   604     TVPbkFieldTypeParameters param;
       
   605 
       
   606     // Resolve field types
       
   607     prop.SetName( EVPbkVersitNameN );
       
   608     const MVPbkFieldType* nameFieldType =
       
   609         iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   610 
       
   611     const MVPbkFieldType* secNameFieldType =
       
   612         iContactManager->FieldTypes().Find( R_VPBK_FIELD_TYPE_SECONDNAME );
       
   613 
       
   614     param.Reset();
       
   615     param.Add( EVPbkVersitParamCELL );
       
   616     prop.SetName( EVPbkVersitNameTEL );
       
   617     prop.SetParameters( param );
       
   618     const MVPbkFieldType* numberFieldType =
       
   619         iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   620 
       
   621     param.Reset();
       
   622     param.Add( EVPbkVersitParamINTERNET );
       
   623     prop.SetName( EVPbkVersitNameEMAIL );
       
   624     prop.SetParameters( param );
       
   625     const MVPbkFieldType* mailFieldType =
       
   626         iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   627 
       
   628     // Get max field counts
       
   629     TInt maxNumbers = entry->MaxNumberOfFieldL( *numberFieldType );
       
   630     TInt maxSecondNames = entry->MaxNumberOfFieldL( *secNameFieldType );
       
   631     TInt maxEmails = entry->MaxNumberOfFieldL( *mailFieldType );
       
   632 
       
   633     HTI_LOG_FORMAT( "Max numbers = %d", maxNumbers );
       
   634     HTI_LOG_FORMAT( "Max second names = %d", maxSecondNames );
       
   635     HTI_LOG_FORMAT( "Max emails = %d", maxEmails );
       
   636 
       
   637     // Create field objects to get field data max lengths and verify that
       
   638     // fields can be created. It is assumed that all SIM cards support name
       
   639     // and number fields but e-mail and second name fields are TRAP:ed as
       
   640     // creating them would cause a leave if not supported by the SIM card.
       
   641     // It was noticed that with a SIM card not supporting the second name
       
   642     // field the MaxNumberOfFieldL method for that field returns 1 but then
       
   643     // the CreateFieldLC leaves with KErrNotSupported.
       
   644     MVPbkStoreContactField* nameField = entry->CreateFieldLC( *nameFieldType );
       
   645     MVPbkContactFieldTextData& nameFieldData =
       
   646         MVPbkContactFieldTextData::Cast( nameField->FieldData() );
       
   647     TInt maxNameLength = nameFieldData.MaxLength();
       
   648     CleanupStack::PopAndDestroy(); // nameField
       
   649 
       
   650     MVPbkStoreContactField* numberField = entry->CreateFieldLC( *numberFieldType );
       
   651     MVPbkContactFieldTextData& numberFieldData =
       
   652         MVPbkContactFieldTextData::Cast( numberField->FieldData() );
       
   653     TInt maxNumberLength = numberFieldData.MaxLength();
       
   654     CleanupStack::PopAndDestroy(); // numberField
       
   655 
       
   656     MVPbkStoreContactField* mailField = NULL;
       
   657     TInt maxMailLength = 0;
       
   658     if ( maxEmails > 0 )
       
   659         {
       
   660         TRAPD( err, mailField = entry->CreateFieldLC( *mailFieldType );
       
   661             CleanupStack::Pop(); ); // Popping inside the TRAP
       
   662         if ( err != KErrNone )
       
   663             {
       
   664             maxEmails = 0;
       
   665             }
       
   666         else
       
   667             {
       
   668             MVPbkContactFieldTextData& mailFieldData =
       
   669                 MVPbkContactFieldTextData::Cast( mailField->FieldData() );
       
   670             maxMailLength = mailFieldData.MaxLength();
       
   671             delete mailField;
       
   672             mailField = NULL;
       
   673             }
       
   674         }
       
   675 
       
   676     MVPbkStoreContactField* secNameField = NULL;
       
   677     TInt maxSecNameLength = 0;
       
   678     if ( maxSecondNames > 0 )
       
   679         {
       
   680         TRAPD( err, secNameField = entry->CreateFieldLC( *secNameFieldType );
       
   681             CleanupStack::Pop(); ); // Popping inside the TRAP
       
   682         if ( err != KErrNone )
       
   683             {
       
   684             maxSecondNames = 0;
       
   685             }
       
   686         else
       
   687             {
       
   688             MVPbkContactFieldTextData& secNameFieldData =
       
   689                 MVPbkContactFieldTextData::Cast( secNameField->FieldData() );
       
   690             maxSecNameLength = secNameFieldData.MaxLength();
       
   691             delete secNameField;
       
   692             secNameField = NULL;
       
   693             }
       
   694         }
       
   695 
       
   696     HTI_LOG_FORMAT( "Max name length = %d", maxNameLength );
       
   697     HTI_LOG_FORMAT( "Max 2nd name length = %d", maxSecNameLength );
       
   698     HTI_LOG_FORMAT( "Max number length = %d", maxNumberLength );
       
   699     HTI_LOG_FORMAT( "Max mail length = %d", maxMailLength );
       
   700 
       
   701     CleanupStack::PopAndDestroy(); // entry
       
   702 
       
   703     // Create and send response message
       
   704     TBuf8<KSimInfoResponseLength> reply;
       
   705     reply.Append( maxSecondNames );
       
   706     reply.Append( maxNumbers - 1 ); // max num of additional numbers, so -1
       
   707     reply.Append( maxEmails );
       
   708     reply.Append( maxNameLength );
       
   709     reply.Append( maxNumberLength );
       
   710     reply.Append( maxSecNameLength );
       
   711     reply.Append( maxNumberLength ); // additional number uses same field type
       
   712     reply.Append( maxMailLength );
       
   713     reply.Append( ( TUint8* ) ( &maxEntries ), 2 );
       
   714     reply.Append( ( TUint8* ) ( &currentEntries ), 2 );
       
   715 
       
   716     SendOkMsgL( reply );
       
   717 
       
   718     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::HandleSimCardInfoL" );
       
   719     }
       
   720 
       
   721 
       
   722 // ----------------------------------------------------------------------------
       
   723 // CHtiSimDirHandlerVPbk::HandleSimContactImportL
       
   724 // Imports the contact to SIM card.
       
   725 // ----------------------------------------------------------------------------
       
   726 void CHtiSimDirHandlerVPbk::HandleSimContactImportL()
       
   727     {
       
   728     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::HandleSimContactImportL" );
       
   729 
       
   730     MVPbkStoreContact* newEntry = iSimStore->CreateNewContactLC();
       
   731 
       
   732     TInt offset = 0;
       
   733     TInt fieldCount = iMessage->Des()[offset];
       
   734     offset++;
       
   735 
       
   736     for ( TInt i = 0; i < fieldCount; i++ )
       
   737         {
       
   738         HTI_LOG_FORMAT( "Processing field %d", i + 1 );
       
   739 
       
   740         MVPbkStoreContactField* field = NULL;
       
   741         TVPbkFieldVersitProperty prop;
       
   742         TVPbkFieldTypeParameters param;
       
   743         const MVPbkFieldType* fieldType = NULL;
       
   744         TContactFieldType type = ( TContactFieldType ) iMessage->Des()[offset];
       
   745         offset++;
       
   746         switch ( type )
       
   747             {
       
   748             case ENameField:
       
   749                 prop.SetName( EVPbkVersitNameN );
       
   750                 fieldType = iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   751                 break;
       
   752             case ESecondNameField:
       
   753                 fieldType = iContactManager->FieldTypes().Find(
       
   754                     R_VPBK_FIELD_TYPE_SECONDNAME );
       
   755                 break;
       
   756             case EPhoneNumberField:
       
   757                 param.Add( EVPbkVersitParamCELL );
       
   758                 prop.SetName( EVPbkVersitNameTEL );
       
   759                 prop.SetParameters( param );
       
   760                 fieldType = iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   761                 break;
       
   762             case EEMailField:
       
   763                 param.Add( EVPbkVersitParamINTERNET );
       
   764                 prop.SetName( EVPbkVersitNameEMAIL );
       
   765                 prop.SetParameters( param );
       
   766                 fieldType = iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   767                 break;
       
   768             case EAdditNumberField:
       
   769                 param.Add( EVPbkVersitParamCELL );
       
   770                 prop.SetName( EVPbkVersitNameTEL );
       
   771                 prop.SetParameters( param );
       
   772                 fieldType = iContactManager->FieldTypes().FindMatch( prop, 0 );
       
   773                 break;
       
   774             default:
       
   775                 HTI_LOG_FORMAT( "Unknown field type %d", type );
       
   776                 User::Leave( KErrArgument );
       
   777                 break;
       
   778             }
       
   779 
       
   780         if ( fieldType == NULL )
       
   781             {
       
   782             User::Leave( KErrArgument );
       
   783             }
       
   784 
       
   785         HTI_LOG_FORMAT( "Field type res id %d", fieldType->FieldTypeResId() );
       
   786 
       
   787         field = newEntry->CreateFieldLC( *fieldType );
       
   788 
       
   789         TInt fieldLength = iMessage->Des()[offset];
       
   790         offset++;
       
   791         HBufC* fieldData = HBufC::NewLC( fieldLength );
       
   792         fieldData->Des().Copy( iMessage->Mid( offset, fieldLength ) );
       
   793         HTI_LOG_FORMAT( "Field created - adding data: %S", fieldData );
       
   794 
       
   795         MVPbkContactFieldTextData& targetData =
       
   796             MVPbkContactFieldTextData::Cast( field->FieldData() );
       
   797         targetData.SetTextL( *fieldData );
       
   798 
       
   799         CleanupStack::PopAndDestroy(); // fieldData
       
   800 
       
   801         HTI_LOG_TEXT( "Data set - Adding the field" );
       
   802         newEntry->AddFieldL( field );
       
   803         CleanupStack::Pop(); // field
       
   804 
       
   805         offset += fieldLength;
       
   806         }
       
   807 
       
   808     HTI_LOG_TEXT( "Entry created - Commiting" );
       
   809     // Starts the async commit operation. Takes ownership of newEntry.
       
   810     newEntry->CommitL( *this );
       
   811     CleanupStack::Pop(); // newEntry
       
   812 
       
   813     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::HandleSimContactImportL" );
       
   814     }
       
   815 
       
   816 
       
   817 // ----------------------------------------------------------------------------
       
   818 // CHtiSimDirHandlerVPbk::HandleSimContactDeleteL
       
   819 // Creates a contact view containing the contacts to be deleted.
       
   820 // ----------------------------------------------------------------------------
       
   821 void CHtiSimDirHandlerVPbk::HandleSimContactDeleteL()
       
   822     {
       
   823     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::HandleSimContactDeleteL" );
       
   824 
       
   825     if ( iContactView )
       
   826         {
       
   827         iContactView->RemoveObserver( *this );
       
   828         delete iContactView;
       
   829         iContactView = NULL;
       
   830         }
       
   831 
       
   832     // Delete one entry based on ID
       
   833     if ( iMessage->Length() == 4 )
       
   834         {
       
   835         TPtr8 msgPtr = iMessage->Des();
       
   836         TInt id = msgPtr[0] + ( msgPtr[1] << 8 )
       
   837                             + ( msgPtr[2] << 16 )
       
   838                             + ( msgPtr[3] << 24 );
       
   839         HTI_LOG_FORMAT( "Delete with id %d", id );
       
   840 
       
   841         User::Leave( KErrNotSupported );
       
   842         }
       
   843 
       
   844     // Delete all
       
   845     else
       
   846         {
       
   847         CVPbkContactViewDefinition* viewDef = CVPbkContactViewDefinition::NewL();
       
   848         CleanupStack::PushL( viewDef );
       
   849         viewDef->SetType( EVPbkContactsView );
       
   850         viewDef->SetSharing( EVPbkLocalView );
       
   851         viewDef->SetSortPolicy( EVPbkUnsortedContactView ); // in SIM index order
       
   852         CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL(
       
   853                 iSimStore->StoreProperties().SupportedFields() );
       
   854         CleanupStack::PushL( sortOrder );
       
   855         iContactView = iSimStore->CreateViewLC( *viewDef, *this, *sortOrder );
       
   856         CleanupStack::Pop(); // view;
       
   857         CleanupStack::PopAndDestroy( 2 ); // sortOrder, viewDef
       
   858         }
       
   859 
       
   860     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::HandleSimContactDeleteL" );
       
   861     }
       
   862 
       
   863 // ----------------------------------------------------------------------------
       
   864 // CHtiSimDirHandlerVPbk::DeleteContactsInViewL
       
   865 // Deletes the contacts that are currently in iContactView.
       
   866 // ----------------------------------------------------------------------------
       
   867 void CHtiSimDirHandlerVPbk::DeleteContactsInViewL()
       
   868     {
       
   869     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::DeleteContactsInViewL" );
       
   870 
       
   871     TInt cntCount( iContactView->ContactCountL() );
       
   872     HTI_LOG_FORMAT( "Contact count in view = %d", cntCount );
       
   873     if ( cntCount > 0 )
       
   874         {
       
   875         CVPbkContactLinkArray* contactLinks = CVPbkContactLinkArray::NewLC();
       
   876         for ( TInt i = 0; i < cntCount; ++i )
       
   877             {
       
   878             MVPbkContactLink* link =
       
   879                 iContactView->ContactAtL( i ).CreateLinkLC();
       
   880             contactLinks->AppendL( link );
       
   881             CleanupStack::Pop(); // link
       
   882             }
       
   883         // Following DeleteContactsL will result in calls to StepComplete
       
   884         // and finally OperationComplete (StepFailed if error occurs)
       
   885         iCurrentOperation = iContactManager->DeleteContactsL(
       
   886                 *contactLinks, *this );
       
   887         CleanupStack::PopAndDestroy(); // contactLinks
       
   888         }
       
   889     else
       
   890         {
       
   891         // Nothing to delete
       
   892         SendOkMsgL( KNullDesC8 );
       
   893         }
       
   894 
       
   895     // We don't need the view anymore
       
   896     HTI_LOG_TEXT( "Deleting the contact view" );
       
   897     iContactView->RemoveObserver( *this );
       
   898     delete iContactView;
       
   899     iContactView = NULL;
       
   900 
       
   901     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::DeleteContactsInViewL" );
       
   902     }
       
   903 
       
   904 // ----------------------------------------------------------------------------
       
   905 // CHtiSimDirHandlerVPbk::CheckImportMsg
       
   906 // Validates the syntax of import contact message.
       
   907 // ----------------------------------------------------------------------------
       
   908 TBool CHtiSimDirHandlerVPbk::CheckImportMsg()
       
   909     {
       
   910     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::CheckImportMsg" );
       
   911     // Import command syntax:
       
   912     //   amount of fields     (1 byte)   __
       
   913     //   type of field        (1 byte)     |
       
   914     //   length of data field (1 byte)     | repeated <amount of fields> times
       
   915     //   field data           (variable) __|
       
   916 
       
   917     TInt length = iMessage->Length();
       
   918     if ( length < 4 ) // min length 4 bytes
       
   919         {
       
   920         HTI_LOG_FORMAT( "Message too short %d", length );
       
   921         return EFalse;
       
   922         }
       
   923 
       
   924     TInt offset = 0;
       
   925     TInt fieldCount = iMessage->Des()[offset];
       
   926     HTI_LOG_FORMAT( "Fields %d", fieldCount );
       
   927     if ( fieldCount < 1 ) // must be at least one field
       
   928         {
       
   929         return EFalse;
       
   930         }
       
   931 
       
   932     offset++;
       
   933     TInt fieldsFound = 0;
       
   934     while ( offset < length )
       
   935         {
       
   936         fieldsFound++;
       
   937         TInt fieldType = iMessage->Des()[offset];
       
   938         HTI_LOG_FORMAT( "Field type %d", fieldType );
       
   939         if ( fieldType < ENameField || fieldType > EAdditNumberField )
       
   940             {
       
   941             return EFalse; // invalid field type
       
   942             }
       
   943         offset++; // the type of field byte
       
   944         if ( offset >= length )
       
   945             {
       
   946             return EFalse;
       
   947             }
       
   948         TInt fieldLength = iMessage->Des()[offset];
       
   949         HTI_LOG_FORMAT( "Field length %d", fieldLength );
       
   950         if ( fieldLength < 1 )
       
   951             {
       
   952             return EFalse; // Field data can not be empty
       
   953             }
       
   954         offset++; // advance over the length of data byte
       
   955         offset += fieldLength; // and the field data
       
   956         }
       
   957 
       
   958     if ( offset == length && fieldsFound == fieldCount )
       
   959         {
       
   960         HTI_LOG_TEXT( "Message OK" );
       
   961         return ETrue;
       
   962         }
       
   963 
       
   964     return EFalse;
       
   965     }
       
   966 
       
   967 
       
   968 // ----------------------------------------------------------------------------
       
   969 // CHtiSimDirHandlerVPbk::SendOkMsgL
       
   970 // Helper function for sending response messages.
       
   971 // ----------------------------------------------------------------------------
       
   972 void CHtiSimDirHandlerVPbk::SendOkMsgL( const TDesC8& aData )
       
   973     {
       
   974     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::SendOkMsgL" );
       
   975     iIsBusy = EFalse; // Done with the current request
       
   976     User::LeaveIfNull( iDispatcher );
       
   977     HBufC8* temp = HBufC8::NewL( aData.Length() + 1 );
       
   978     TPtr8 response = temp->Des();
       
   979     response.Append( ( TChar ) CHtiPIMServicePlugin::EResultOk );
       
   980     response.Append( aData );
       
   981     User::LeaveIfError( iDispatcher->DispatchOutgoingMessage(
       
   982         temp, KPIMServiceUid ) );
       
   983     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::SendOkMsgL" );
       
   984     }
       
   985 
       
   986 
       
   987 // ----------------------------------------------------------------------------
       
   988 // CHtiSimDirHandlerVPbk::SendErrorMessageL
       
   989 // Helper function for sending error response messages.
       
   990 // ----------------------------------------------------------------------------
       
   991 void CHtiSimDirHandlerVPbk::SendErrorMessageL( TInt aError, const TDesC8& aDescription )
       
   992     {
       
   993     HTI_LOG_FUNC_IN( "CHtiSimDirHandlerVPbk::SendErrorMessageL" );
       
   994     iIsBusy = EFalse; // Done with the current request
       
   995     User::LeaveIfNull( iDispatcher );
       
   996     User::LeaveIfError( iDispatcher->DispatchOutgoingErrorMessage(
       
   997         aError, aDescription, KPIMServiceUid ) );
       
   998     HTI_LOG_FUNC_OUT( "CHtiSimDirHandlerVPbk::SendErrorMessageL" );
       
   999     }
       
  1000 
       
  1001 
       
  1002 // End of file