ncdengine/provider/server/src/ncdbaseoperation.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <s32mem.h>
       
    20 
       
    21 #include "ncdbaseoperation.h"
       
    22 #include "catalogsbasemessage.h"
       
    23 #include "catalogsdebug.h"
       
    24 #include "ncdqueryimpl.h"
       
    25 #include "ncd_cp_queryresponseimpl.h"
       
    26 #include "ncd_cp_query.h"
       
    27 #include "catalogsutils.h"
       
    28 #include "ncdoperationobserver.h"
       
    29 #include "ncd_pp_information.h"
       
    30 #include "catalogssession.h"
       
    31 #include "ncdoperationremovehandler.h"
       
    32 #include "ncd_pp_error.h"
       
    33 #include "ncd_pp_expiredcacheddata.h"
       
    34 #include "ncdnodeidentifier.h"
       
    35 #include "ncdnodemanager.h"
       
    36 #include "catalogscontext.h"
       
    37 #include "ncddeviceinteractionfactory.h"
       
    38 #include "ncddeviceservice.h"
       
    39 #include "ncdquerytextitem.h"
       
    40 #include "ncdparser.h"
       
    41 #include "ncdprotocoldefaultobserver.h"
       
    42 #include "catalogsconstants.h"
       
    43 #include "ncdexpirednode.h"
       
    44 #include "ncdrequestbase.h"
       
    45 #include "ncdproviderutils.h"
       
    46 #include "ncderrors.h"
       
    47 #include "ncdgeneralmanager.h"
       
    48 
       
    49 // ======== MEMBER FUNCTIONS ========
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // ?description_if_needed
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 CNcdBaseOperation::~CNcdBaseOperation()
       
    56     {
       
    57     DLTRACEIN((""));
       
    58     
       
    59     if ( iRemoveHandler ) 
       
    60         {
       
    61         iRemoveHandler->RemoveOperation( *this );
       
    62         }
       
    63     
       
    64     iObservers.Close();    
       
    65     if ( iActiveQuery )
       
    66         {
       
    67         iActiveQuery->InternalRelease();
       
    68         }
       
    69     if ( iPendingMessage )
       
    70         {
       
    71         DLTRACE(("Message pending"));
       
    72         // Operation destroyed unexpectedly when a message was still pending
       
    73         iPendingMessage->CompleteAndRelease( KErrDied );
       
    74         }    
       
    75     
       
    76     iEmbeddedDataQuerys.ResetAndDestroy();
       
    77     for( TInt i = 0 ; i < iPendingQuerys.Count() ; i++ )
       
    78         {
       
    79         iPendingQuerys[i]->InternalRelease();
       
    80         }
       
    81     iPendingQuerys.Close();
       
    82     delete iRunner;
       
    83     iExpiredNodes.ResetAndDestroy();
       
    84     for ( TInt i = 0 ; i < iCompletedQuerys.Count() ; i++ )
       
    85         {
       
    86         iCompletedQuerys[i]->InternalRelease();
       
    87         }
       
    88     iCompletedQuerys.Reset();
       
    89     DLTRACEOUT((""));
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // ?implementation_description
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 TInt CNcdBaseOperation::Start()
       
    97     {
       
    98     DLTRACEIN((""));
       
    99     if ( iOperationState == EStateStopped )
       
   100         {
       
   101         // Op not yet running, start it
       
   102         iOperationState = EStateRunning;
       
   103         TInt err = RunOperation();
       
   104         DLTRACE(("Returned from RunOperation()"));
       
   105         DLTRACEOUT((""));
       
   106         return err;
       
   107         }
       
   108     else
       
   109         {
       
   110         // Op already started.
       
   111         DLTRACEOUT((""));
       
   112         return KErrInUse;
       
   113         }
       
   114     }
       
   115     
       
   116 // ---------------------------------------------------------------------------
       
   117 // ?implementation_description
       
   118 // ---------------------------------------------------------------------------
       
   119 //
       
   120 void CNcdBaseOperation::AddObserverL( 
       
   121     MNcdOperationObserver* aObserver )
       
   122     {
       
   123     DLTRACEIN((""));
       
   124     DASSERT( aObserver );
       
   125     iObservers.AppendL( aObserver );
       
   126     }
       
   127 
       
   128 
       
   129 // ---------------------------------------------------------------------------
       
   130 // ?implementation_description
       
   131 // ---------------------------------------------------------------------------
       
   132 //
       
   133 TInt CNcdBaseOperation::RemoveObserver( 
       
   134     MNcdOperationObserver* aObserver )
       
   135     {
       
   136     DLTRACEIN((""));
       
   137     TInt index = iObservers.Find( aObserver );
       
   138     if ( index != KErrNotFound )
       
   139         {
       
   140         iObservers.Remove( index );
       
   141         return KErrNone;
       
   142         }
       
   143     else
       
   144         {
       
   145         return KErrNotFound;
       
   146         }
       
   147     }
       
   148 
       
   149 // ---------------------------------------------------------------------------
       
   150 // ?implementation_description
       
   151 // ---------------------------------------------------------------------------
       
   152 //
       
   153 TNcdOperationType CNcdBaseOperation::Type() const
       
   154     {
       
   155     DLTRACEIN((""));
       
   156     return iOperationType;
       
   157     }
       
   158     
       
   159 // ---------------------------------------------------------------------------
       
   160 // ?implementation_description
       
   161 // ---------------------------------------------------------------------------
       
   162 //
       
   163 void CNcdBaseOperation::HandleStartMessage( 
       
   164     MCatalogsBaseMessage* aMessage )    
       
   165     {
       
   166     DLTRACEIN((""));
       
   167     DASSERT( ! iPendingMessage );
       
   168     if ( iOperationState == EStateStopped )
       
   169         {        
       
   170         iPendingMessage = aMessage;
       
   171         TInt err = Start();
       
   172         DLTRACE(( "Start returned with: %d", err ));
       
   173         }
       
   174     else
       
   175         {
       
   176         DLTRACE(("Operation already started"));
       
   177         // Operation already started.
       
   178         TInt err = CompleteMessage( aMessage, ENCDOperationMessageCompletionError,
       
   179             KErrInUse );
       
   180         if ( err != KErrNone )
       
   181             {
       
   182             FailOperation( err );
       
   183             }
       
   184         }       
       
   185     DLTRACEOUT(("")); 
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // ?implementation_description
       
   190 // ---------------------------------------------------------------------------
       
   191 //
       
   192 void CNcdBaseOperation::HandleCancelMessage( 
       
   193     MCatalogsBaseMessage* aMessage )
       
   194     {
       
   195     DLTRACEIN((""));
       
   196     // release pending message if any
       
   197     if ( iPendingMessage )
       
   198         {
       
   199         DLTRACE(("Completing pending message"));
       
   200        
       
   201         // Completing the message so no memory is pending in the
       
   202         // framework because of it.            
       
   203         iPendingMessage->CompleteAndRelease( KErrCancel );            
       
   204         iPendingMessage = NULL;
       
   205         }
       
   206     
       
   207     // iOperationState has to be set to EStateCancelled before
       
   208     // cancelling purchase operation.
       
   209     // See CNcdPurchaseOperationImpl::HandleSmsEvent()
       
   210     iOperationState = EStateCancelled;
       
   211     Cancel();
       
   212 
       
   213     aMessage->CompleteAndRelease( KErrNone );
       
   214 
       
   215     DLTRACEOUT((""));
       
   216     }
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // ?implementation_description
       
   220 // ---------------------------------------------------------------------------
       
   221 //
       
   222 void CNcdBaseOperation::HandleContinueMessage( 
       
   223     MCatalogsBaseMessage* aMessage )
       
   224     {
       
   225     DLTRACEIN(( "iOperationState: %d", iOperationState ));
       
   226     DASSERT( ! iPendingMessage );
       
   227     if ( iOperationState == EStateRunning )
       
   228         {
       
   229         DLTRACE(("iOperationState == EStateRunning"));        
       
   230         // Message is just stored here, it will be completed 
       
   231         // when progress has been made.
       
   232         iPendingMessage = aMessage;
       
   233         iOperationState = EStateRunning;
       
   234         
       
   235         RunOperation();
       
   236         DLTRACE(("Returned from RunOperation()"));
       
   237         }
       
   238     else if ( iOperationState == EStateQuery )
       
   239         {
       
   240         DLTRACE(("iOperationState == EStateQuery"));
       
   241         // A query is pending and has not yet been sent to proxy        
       
   242         TInt err = CompleteMessage( aMessage, ENCDOperationMessageCompletionQuery,
       
   243             *iActiveQuery,
       
   244             KErrNone );
       
   245         if( err != KErrNone )
       
   246             {
       
   247             FailOperation( err );
       
   248             }
       
   249         }
       
   250     else if ( iOperationState == EStateSendExpirationInfo )
       
   251         {
       
   252         DLTRACE(("iOperationState == EStateSendExpirationInfo"));
       
   253         iOperationState = EStateRunning;
       
   254         iPendingMessage = aMessage;
       
   255         TInt err = SendExpirationInfo( iExpiredNodes );
       
   256         if( err != KErrNone )
       
   257             {
       
   258             FailOperation( err );            
       
   259             }
       
   260         else
       
   261             {
       
   262             iExpiredNodes.ResetAndDestroy();
       
   263             if ( iActiveQuery )
       
   264                 {
       
   265                 // there's a query pending, change state accordingly
       
   266                 iOperationState = EStateQuery;
       
   267                 }
       
   268             }
       
   269         }
       
   270     else
       
   271         {
       
   272         DLTRACE(("Not waiting for a continue message!"));
       
   273         // Fail operation can't complete the message if it's not set
       
   274         // to iPendingMessage
       
   275         iPendingMessage = aMessage;
       
   276         
       
   277         // Not waiting for a continue message.
       
   278         FailOperation( KErrNotReady );
       
   279         }
       
   280     DLTRACEOUT((""));
       
   281     }
       
   282     
       
   283 // ---------------------------------------------------------------------------
       
   284 // ?implementation_description
       
   285 // ---------------------------------------------------------------------------
       
   286 //
       
   287 void CNcdBaseOperation::HandleQueryResponseMessage( 
       
   288     MCatalogsBaseMessage* aMessage )
       
   289     {
       
   290     DLTRACEIN((""));
       
   291     DASSERT( ! iPendingMessage );
       
   292     if ( iOperationState == EStateQuery )
       
   293         {        
       
   294         DASSERT( iActiveQuery );
       
   295         // store message, it will be completed later
       
   296         iPendingMessage = aMessage;
       
   297         iOperationState = EStateRunning;
       
   298         
       
   299         DLINFO(("input length= %d",iPendingMessage->InputLength()));
       
   300         
       
   301         TRAPD( err,
       
   302             {            
       
   303             HBufC8* des = HBufC8::NewLC( iPendingMessage->InputLength() );
       
   304             TPtr8 ptr = des->Des();
       
   305             iPendingMessage->ReadInput( ptr );
       
   306             RDesReadStream stream( *des );
       
   307             CleanupReleasePushL( stream );
       
   308             iActiveQuery->InternalizeL( stream );
       
   309             CleanupStack::PopAndDestroy( &stream );
       
   310             CleanupStack::PopAndDestroy( des );
       
   311             QueryHandledL( iActiveQuery );
       
   312             }); // TRAP
       
   313             
       
   314         if( err != KErrNone )
       
   315             {
       
   316             FailOperation( err );
       
   317             }
       
   318         
       
   319             
       
   320         
       
   321         // Should handle cases where both expired info and querys have been received
       
   322         /*else if( iExpiredNodes.Count() > 0 )
       
   323             {
       
   324             DLTRACE(("Expired nodes received previously, send to proxy"));
       
   325             TInt err = SendExpirationInfo( iExpiredNodes );
       
   326             if( err != KErrNone )
       
   327                 {
       
   328                 FailOperation( err );
       
   329                 }
       
   330             }*/
       
   331         }
       
   332     else
       
   333         {
       
   334         DLTRACE(("Not waiting for a query"));
       
   335         // Not waiting for a query response message.
       
   336         TInt err = CompleteMessage( aMessage, ENCDOperationMessageCompletionError,
       
   337             KErrNotReady );
       
   338         if ( err != KErrNone )
       
   339             {
       
   340             FailOperation( err );
       
   341             }
       
   342         }
       
   343     DLTRACEOUT((""));
       
   344     }
       
   345 
       
   346 
       
   347 // ---------------------------------------------------------------------------
       
   348 // Handle initialization messages
       
   349 // ---------------------------------------------------------------------------
       
   350 //
       
   351 void CNcdBaseOperation::HandleInitMessage( MCatalogsBaseMessage* aMessage )
       
   352     {
       
   353     DLTRACEIN( ( "" ) );
       
   354     if ( iOperationState == EStateStopped )
       
   355         {
       
   356         // this will probably cause an error in the proxy, remove?
       
   357         if ( iPendingMessage )
       
   358             {
       
   359             DLTRACE( ( "MESSAGE PENDING! THIS CAN NOT BE!" ) );
       
   360             iPendingMessage->CompleteAndRelease( KErrAlreadyExists );
       
   361             DASSERT( 0 );
       
   362             }
       
   363         iPendingMessage = aMessage;
       
   364         Initialize();
       
   365         }
       
   366     else
       
   367         {
       
   368         // Operation already started.
       
   369         TInt err = CompleteMessage( aMessage, 
       
   370             ENCDOperationMessageCompletionError,
       
   371             KErrInUse );
       
   372         if ( err != KErrNone )
       
   373             {
       
   374             FailOperation( err );
       
   375             }
       
   376         }        
       
   377     DLTRACEOUT((""));
       
   378     }
       
   379     
       
   380     
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // Handles release messages
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 void CNcdBaseOperation::HandleReleaseMessage( MCatalogsBaseMessage* aMessage )    
       
   387     {
       
   388     DLTRACEIN((""));
       
   389     if ( iPendingMessage ) 
       
   390         {
       
   391         
       
   392         // Notice that because we complete the iPendingMessage here the
       
   393         // client has to say AsyncMessageSenderDown() to the
       
   394         // ClientServer so the client won't receive this
       
   395         // iPendingMessage. iPendingMessage is released here so no memory
       
   396         // is pending because of it.
       
   397         DLTRACE(("Releasing pending message"));
       
   398         iPendingMessage->CompleteAndRelease( KErrCancel );            
       
   399         iPendingMessage = NULL;        
       
   400         DLTRACE(("Message released"));
       
   401         }
       
   402         
       
   403     MCatalogsSession& requestSession( aMessage->Session() );
       
   404     DLTRACE(("Getting handle"));
       
   405     TInt handle( aMessage->Handle() );
       
   406     
       
   407     DLTRACE(("Completing message"));
       
   408     aMessage->CompleteAndRelease( KErrNone );
       
   409     DLTRACE(("Removing object"));
       
   410     requestSession.RemoveObject( handle );
       
   411     }
       
   412         
       
   413 
       
   414 
       
   415 // ---------------------------------------------------------------------------
       
   416 // ?implementation_description
       
   417 // ---------------------------------------------------------------------------
       
   418 //
       
   419 TInt CNcdBaseOperation::CompleteMessage( MCatalogsBaseMessage* & aMessage,
       
   420         TNcdOperationMessageCompletionId aId,
       
   421         const MNcdSendable& aSendableObject,
       
   422         TInt aStatus )
       
   423     {
       
   424     DLTRACEIN((""));
       
   425     DLTRACE(("Handle: %d", aMessage->Handle()));
       
   426     TRAPD(err,    
       
   427         {
       
   428         DLTRACE(("new buf"));
       
   429         CBufBase* buf = CBufFlat::NewL( 30 );
       
   430         CleanupStack::PushL( buf );
       
   431         RBufWriteStream stream( *buf );
       
   432         CleanupClosePushL( stream );
       
   433         stream.WriteInt32L( aId );
       
   434         aSendableObject.ExternalizeL( stream );
       
   435         CleanupStack::PopAndDestroy( &stream );
       
   436         TPtrC8 ptr = buf->Ptr( 0 );
       
   437         DLTRACE(("complete msg"));
       
   438         DASSERT((aMessage != NULL));
       
   439         aMessage->CompleteAndReleaseL( ptr, aStatus );
       
   440         DLTRACE(("pop buf"));
       
   441         CleanupStack::PopAndDestroy( buf );
       
   442         DLTRACE(("done"));
       
   443         });
       
   444     if( err != KErrNone )
       
   445         {
       
   446         aMessage->CompleteAndRelease( aStatus );
       
   447         }
       
   448     aMessage = NULL;
       
   449     DLTRACEOUT(("error=%d", err));
       
   450     return err;
       
   451     }
       
   452 
       
   453 // ---------------------------------------------------------------------------
       
   454 // ?implementation_description
       
   455 // ---------------------------------------------------------------------------
       
   456 //
       
   457 TInt CNcdBaseOperation::CompleteMessage(MCatalogsBaseMessage* & aMessage,
       
   458         TNcdOperationMessageCompletionId aId,
       
   459         TInt aStatus )
       
   460     {
       
   461     DLTRACEIN((""));
       
   462     DASSERT((aMessage));
       
   463     DLTRACE(("Handle: %d", aMessage->Handle()));
       
   464     TRAPD(err,
       
   465         {
       
   466         HBufC8* buffer = HBufC8::NewLC( sizeof(TInt) );
       
   467         TPtr8 bufferPtr( buffer->Des() );        
       
   468         RDesWriteStream desWriteStream( bufferPtr );
       
   469         CleanupClosePushL( desWriteStream );
       
   470         desWriteStream.WriteInt32L( aId );
       
   471         CleanupStack::PopAndDestroy( &desWriteStream );
       
   472         aMessage->CompleteAndReleaseL( *buffer, aStatus );
       
   473         CleanupStack::PopAndDestroy( buffer );
       
   474         });
       
   475     if( err != KErrNone )
       
   476         {
       
   477         aMessage->CompleteAndRelease( aStatus );
       
   478         }
       
   479     aMessage = NULL;
       
   480     DLTRACEOUT(("error=%d", err));
       
   481     return err;
       
   482     }
       
   483 
       
   484 // ---------------------------------------------------------------------------
       
   485 // ?implementation_description
       
   486 // ---------------------------------------------------------------------------
       
   487 //
       
   488 TInt CNcdBaseOperation::CompleteMessage( MCatalogsBaseMessage*& aMessage,
       
   489         TNcdOperationMessageCompletionId aId,
       
   490         const MNcdSendable& aSendableObject,
       
   491         RPointerArray<CNcdNodeIdentifier>& aNodes,
       
   492         TInt aStatus )
       
   493     {
       
   494     DLTRACEIN(("Handle: %i", aMessage->Handle()));
       
   495     
       
   496     TRAPD(err,    
       
   497         {
       
   498         CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   499         CleanupStack::PushL( buf );
       
   500         RBufWriteStream stream( *buf );
       
   501         CleanupClosePushL( stream );
       
   502         stream.WriteInt32L( aId );
       
   503         aSendableObject.ExternalizeL( stream );
       
   504         stream.WriteInt32L( aNodes.Count() );
       
   505         DLINFO(("Node loop: %d", aNodes.Count()));
       
   506         for ( TInt i = 0 ; i < aNodes.Count() ; i++ )
       
   507             {
       
   508             aNodes[i]->ExternalizeL( stream );
       
   509             }
       
   510         CleanupStack::PopAndDestroy( &stream );
       
   511         TPtrC8 ptr = buf->Ptr( 0 );
       
   512         aMessage->CompleteAndReleaseL( ptr, aStatus );
       
   513         CleanupStack::PopAndDestroy( buf );
       
   514         });
       
   515     if( err != KErrNone )
       
   516         {
       
   517         aMessage->CompleteAndRelease( aStatus );
       
   518         }
       
   519     aMessage = NULL;
       
   520     DLTRACEOUT((""));
       
   521             
       
   522     return err;
       
   523     }
       
   524     
       
   525 // ---------------------------------------------------------------------------
       
   526 // ?implementation_description
       
   527 // ---------------------------------------------------------------------------
       
   528 //
       
   529 TInt CNcdBaseOperation::CompleteMessage( MCatalogsBaseMessage*& aMessage,
       
   530         TNcdOperationMessageCompletionId aId,
       
   531         RPointerArray<CNcdExpiredNode>& aExpiredNodes,
       
   532         TInt aStatus )
       
   533     {
       
   534     DLTRACEIN(("Handle: %i", aMessage->Handle()));
       
   535     
       
   536     TRAPD(err,    
       
   537         {
       
   538         CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   539         CleanupStack::PushL( buf );
       
   540         RBufWriteStream stream( *buf );
       
   541         CleanupClosePushL( stream );
       
   542         stream.WriteInt32L( aId );
       
   543         stream.WriteInt32L( aExpiredNodes.Count() );
       
   544         for ( TInt i = 0 ; i < aExpiredNodes.Count() ; i++ )
       
   545             {
       
   546             aExpiredNodes[i]->ExternalizeL( stream );
       
   547             }
       
   548         CleanupStack::PopAndDestroy( &stream );
       
   549         TPtrC8 ptr = buf->Ptr( 0 );
       
   550         aMessage->CompleteAndReleaseL( ptr, aStatus );
       
   551         CleanupStack::PopAndDestroy( buf );
       
   552         });
       
   553     if( err != KErrNone )
       
   554         {
       
   555         aMessage->CompleteAndRelease( aStatus );
       
   556         }
       
   557     DLINFO(("message null"));    
       
   558     aMessage = NULL;
       
   559     DLTRACEOUT((""));
       
   560             
       
   561     return err;
       
   562     }
       
   563 
       
   564 MCatalogsSession& CNcdBaseOperation::Session()
       
   565     {
       
   566     return iSession;
       
   567     }
       
   568 
       
   569 TBool CNcdBaseOperation::IsSubOperation()
       
   570     {
       
   571     return iIsSubOperation;
       
   572     }
       
   573 
       
   574 
       
   575 // ---------------------------------------------------------------------------
       
   576 // Progress getter
       
   577 // ---------------------------------------------------------------------------
       
   578 //
       
   579 const TNcdSendableProgress& CNcdBaseOperation::Progress() const
       
   580     {
       
   581     return iProgress;
       
   582     }
       
   583 
       
   584 
       
   585 // ---------------------------------------------------------------------------
       
   586 // Handle setter
       
   587 // ---------------------------------------------------------------------------
       
   588 //
       
   589 void CNcdBaseOperation::SetHandle( TInt aHandle )
       
   590     {
       
   591     iHandle = aHandle;
       
   592     }
       
   593 
       
   594 
       
   595 // ---------------------------------------------------------------------------
       
   596 // Handle getter
       
   597 // ---------------------------------------------------------------------------
       
   598 //
       
   599 TInt CNcdBaseOperation::Handle() const
       
   600     {
       
   601     return iHandle;
       
   602     }
       
   603 
       
   604 // ---------------------------------------------------------------------------
       
   605 // From class CCatalogsCommunicable
       
   606 // ?implementation_description
       
   607 // ---------------------------------------------------------------------------
       
   608 //
       
   609 void CNcdBaseOperation::ReceiveMessage( 
       
   610         MCatalogsBaseMessage* aMessage,
       
   611         TInt aFunctionNumber )
       
   612     {
       
   613     DLTRACEIN((_L("Handle: %i, aFunctionNumber=%d"), aMessage->Handle(),
       
   614         aFunctionNumber));
       
   615     
       
   616     
       
   617     switch ( aFunctionNumber )
       
   618         {
       
   619         case ENCDOperationFunctionStart:
       
   620             {
       
   621             HandleStartMessage( aMessage );
       
   622             break;
       
   623             }
       
   624         case ENCDOperationFunctionCancel:
       
   625             {
       
   626             HandleCancelMessage( aMessage );
       
   627             break;
       
   628             }
       
   629         case ENCDOperationFunctionContinue:
       
   630             {
       
   631             HandleContinueMessage( aMessage );
       
   632             break;
       
   633             }
       
   634         case ENCDOperationFunctionQueryResponse:
       
   635             {
       
   636             HandleQueryResponseMessage( aMessage );
       
   637             break;
       
   638             }
       
   639         case ENCDOperationFunctionInit:
       
   640             {
       
   641             HandleInitMessage( aMessage );
       
   642             break;
       
   643             }
       
   644             
       
   645         case ENCDOperationFunctionRelease:
       
   646             {
       
   647             HandleReleaseMessage( aMessage );
       
   648             break;
       
   649             }
       
   650             
       
   651         }
       
   652     DLTRACEOUT((""));
       
   653     }
       
   654     
       
   655     
       
   656 // ---------------------------------------------------------------------------
       
   657 // ?implementation_description
       
   658 // ---------------------------------------------------------------------------
       
   659 //
       
   660 void CNcdBaseOperation::CounterPartLost( const MCatalogsSession& aSession ) 
       
   661     {
       
   662     DLTRACEIN((""));
       
   663     Cancel();
       
   664     if ( iPendingMessage )
       
   665         {
       
   666         // This function may be called whenever -- when the message is waiting
       
   667         // response or when the message does not exist. The life time of the message
       
   668         // ends shortly after CompleteAndRelease is called.
       
   669         iPendingMessage->CounterPartLost( aSession );        
       
   670         }
       
   671     }
       
   672 
       
   673 void CNcdBaseOperation::QueryL( MNcdConfigurationProtocolQuery* aData )
       
   674     {
       
   675     DLTRACEIN((""));    
       
   676     // querys from embedded data end up here, just store them
       
   677 	
       
   678     // maybe this should not be added to the array if it's an autenthication
       
   679     // query? on the other hand it could be referred from somewhere else.
       
   680     CleanupDeletePushL( aData );
       
   681     iEmbeddedDataQuerys.AppendL( aData );    
       
   682     CleanupStack::Pop( aData );
       
   683     // special case: authentication query, should actually come in
       
   684     // information/Messages according to protocol but CGW sends it in
       
   685     // embeddedData/Queries.
       
   686     // 
       
   687     if( aData->Semantics() == MNcdQuery::ESemanticsAuthenticationQuery )
       
   688         {
       
   689         iPendingQuerys.AppendL( CNcdQuery::NewLC( *aData ) );
       
   690         CleanupStack::Pop();
       
   691         }
       
   692     DLTRACEOUT((""));
       
   693     }
       
   694 
       
   695 void CNcdBaseOperation::InformationL(
       
   696     MNcdPreminetProtocolInformation* aData )
       
   697     {
       
   698     DLTRACEIN(("aData: %X", aData));    
       
   699     CleanupDeletePushL( aData );
       
   700     DLTRACE(("Handling queries"));
       
   701     // store querys from information response
       
   702     // the inheriting operation will handle these if needed
       
   703     for ( TInt i = 0 ; i < aData->MessageCount() ; i++ )
       
   704         {
       
   705         CNcdQuery* query = CNcdQuery::NewLC( aData->MessageL(i) );
       
   706         iPendingQuerys.AppendL( query );
       
   707         CleanupStack::Pop( query );
       
   708         }
       
   709     
       
   710     DLTRACE(("Checking for expired cached data"));
       
   711     
       
   712     // handle expired cached data
       
   713     const MNcdPreminetProtocolExpiredCachedData* expiredData = 
       
   714         aData->ExpiredCachedData();
       
   715     
       
   716     if ( expiredData )
       
   717         {
       
   718         DLTRACE(("Handling expired data"));
       
   719         RPointerArray<CNcdExpiredNode> expiredNodes;
       
   720         CleanupResetAndDestroyPushL( expiredNodes );
       
   721         iNodeManager->SetNodesExpiredByMetadataL( *expiredData,
       
   722             iSession.Context().FamilyId(),
       
   723             aData->Namespace(),
       
   724             expiredNodes );
       
   725         ExpirationInfoReceived( this, expiredNodes );
       
   726         CleanupStack::PopAndDestroy( &expiredNodes );
       
   727                     }
       
   728                 
       
   729     DLTRACE(("Should handle stuff"));
       
   730     
       
   731     DASSERT( iParser );
       
   732     CleanupStack::Pop( aData );
       
   733     iParser->DefaultObserver().InformationL( aData );
       
   734     DLTRACEOUT((""));
       
   735     }
       
   736 
       
   737 void CNcdBaseOperation::ErrorL( MNcdPreminetProtocolError* /* aData */ )
       
   738     {
       
   739     DLTRACEIN((""));
       
   740     //switch 
       
   741     
       
   742     }
       
   743 
       
   744 void CNcdBaseOperation::Progress( CNcdBaseOperation& /*aOperation*/ )
       
   745     {
       
   746     DLTRACEIN(("default implementation, does nothing"));
       
   747     }
       
   748     
       
   749 void CNcdBaseOperation::QueryReceived( CNcdBaseOperation& /*aOperation*/,
       
   750     CNcdQuery* /*aQuery*/ )
       
   751     {
       
   752     DLTRACEIN(("default implementation, does nothing"));
       
   753     }
       
   754 
       
   755 void CNcdBaseOperation::OperationComplete( CNcdBaseOperation* /*aOperation*/,
       
   756     TInt /*aError*/ )
       
   757     {
       
   758     DLTRACEIN(("default implementation, does nothing"));
       
   759     }
       
   760                                     
       
   761 void CNcdBaseOperation::ExpirationInfoReceived( CNcdBaseOperation* /*aOperation*/,
       
   762         RPointerArray<CNcdExpiredNode>& aExpiredNodes )
       
   763     {
       
   764     DLTRACEIN((""));
       
   765     if ( iIsSubOperation )
       
   766         {
       
   767         DLINFO(( "Subop, inform observers of expiration info" ));
       
   768         // send to observer
       
   769         for( TInt i = 0 ; i < iObservers.Count() ; i++ )
       
   770             {
       
   771             iObservers[i]->ExpirationInfoReceived( this, aExpiredNodes );
       
   772             }
       
   773         }
       
   774     else
       
   775         {
       
   776         if( iPendingMessage )
       
   777             {
       
   778             DLINFO(( "Message exists, send expiration info" ));
       
   779             // message available, send
       
   780             TInt err = SendExpirationInfo( aExpiredNodes );
       
   781             if( err != KErrNone )
       
   782                 {
       
   783                 FailOperation( err );
       
   784                 }
       
   785             }
       
   786         else
       
   787             {
       
   788             DLINFO(( "Message does not exist, cannot send expiration info" ));
       
   789             // no message, store
       
   790             iOperationState = EStateSendExpirationInfo;
       
   791             for( TInt i = 0 ; i < aExpiredNodes.Count() ; i++ )
       
   792                 {
       
   793                 TRAPD( err, iExpiredNodes.AppendL( aExpiredNodes[i] ) );//TRAPD
       
   794                 if( err != KErrNone )
       
   795                     {
       
   796                     FailOperation( err );
       
   797                     }
       
   798                 }
       
   799             aExpiredNodes.Reset();
       
   800             }
       
   801         }
       
   802     }
       
   803 
       
   804 // ---------------------------------------------------------------------------
       
   805 // ?description_if_needed
       
   806 // ---------------------------------------------------------------------------
       
   807 //
       
   808 CNcdBaseOperation::CNcdBaseOperation( 
       
   809     CNcdGeneralManager& aGeneralManager,    
       
   810     MNcdOperationRemoveHandler* aRemoveHandler,
       
   811     TNcdOperationType aOperationType, 
       
   812     MCatalogsSession& aSession, 
       
   813     TBool aIsSubOperation )
       
   814     : iGeneralManager( aGeneralManager ),
       
   815       iError( KErrNone ), 
       
   816       iRemoveHandler( aRemoveHandler ),
       
   817       iOperationType( aOperationType ), 
       
   818       iOperationState( EStateStopped ),
       
   819       iSession( aSession ),
       
   820       iIsSubOperation( aIsSubOperation ), 
       
   821       iNodeManager( &aGeneralManager.NodeManager() )      
       
   822     {
       
   823     DLTRACEIN((""));    
       
   824     }
       
   825 
       
   826 
       
   827 // ---------------------------------------------------------------------------
       
   828 // ?description_if_needed
       
   829 // ---------------------------------------------------------------------------
       
   830 //
       
   831 void CNcdBaseOperation::ConstructL()
       
   832     {
       
   833     DLTRACEIN((""));
       
   834     }
       
   835     
       
   836 // ---------------------------------------------------------------------------
       
   837 // Empty initializer
       
   838 // ---------------------------------------------------------------------------
       
   839 //
       
   840 TInt CNcdBaseOperation::Initialize()
       
   841     {
       
   842     DLTRACEIN( ( "THIS SHOULD NOT BE CALLED" ) );
       
   843     DASSERT( 0 );
       
   844     return KErrNone;
       
   845     }
       
   846 
       
   847 void CNcdBaseOperation::ChangeToPreviousStateL()
       
   848     {
       
   849     DLTRACEIN(("SHOULD NEVER BE CALLED, ERROR!"))
       
   850     DASSERT(0);
       
   851     }
       
   852 
       
   853 void CNcdBaseOperation::HandleEngineQueryItemsL( CNcdQuery* aQuery )
       
   854     {
       
   855     DLTRACEIN((""));
       
   856     aQuery->InternalAddRef();
       
   857     for ( TInt i = 0 ; i < aQuery->ItemCount() ; i++ )
       
   858         {
       
   859         CNcdQueryItem& queryItem = aQuery->QueryItemL( i );
       
   860         switch ( queryItem.Semantics() )
       
   861             {
       
   862             case MNcdQueryItem::ESemanticsImei:
       
   863                 {
       
   864                 MNcdQueryTextItem* textQueryItem = NULL;
       
   865                 textQueryItem = queryItem.QueryInterfaceLC< MNcdQueryTextItem >();
       
   866                 DASSERT( textQueryItem );
       
   867                 // get imei from device service
       
   868                 MNcdDeviceService* deviceService =
       
   869                     NcdDeviceInteractionFactory::CreateDeviceServiceLC();
       
   870                 textQueryItem->SetTextL( deviceService->ImeiL() );
       
   871                 CleanupStack::PopAndDestroy( deviceService );
       
   872                 CleanupStack::PopAndDestroy( textQueryItem );
       
   873                 break;
       
   874                 }
       
   875             default:
       
   876                 {
       
   877                 // not an engine query item
       
   878                 break;
       
   879                 }
       
   880             }
       
   881         }
       
   882     aQuery->InternalRelease();
       
   883     }
       
   884 
       
   885 MNcdConfigurationProtocolQueryResponse* CNcdBaseOperation::CreateResponseL(
       
   886     CNcdQuery& aQuery )
       
   887     {
       
   888     DLTRACEIN((""));
       
   889     if ( aQuery.Response() == MNcdQuery::ENoResponse )
       
   890         {
       
   891         User::Leave( KErrNotReady );
       
   892         }
       
   893     CNcdConfigurationProtocolQueryResponseImpl* queryResponse = 
       
   894         CNcdConfigurationProtocolQueryResponseImpl::NewLC();
       
   895     AssignDesL( queryResponse->iId, aQuery.Id() );
       
   896     DLINFO((_L("Added query id=%S"), queryResponse->iId ));
       
   897     
       
   898     if( aQuery.Response() == MNcdQuery::ERejected )
       
   899         {
       
   900         // query has been cancelled
       
   901         queryResponse->iCancel = ETrue;
       
   902         }
       
   903     else
       
   904         {        
       
   905         // query has been accepted, add response values
       
   906         for ( TInt i = 0 ; i < aQuery.ItemCount() ; i++ )
       
   907             {
       
   908             CNcdQueryItem& item = aQuery.QueryItemL( i );
       
   909             if ( item.IsOptional() && ! item.IsSet() )
       
   910                 {
       
   911                 continue;
       
   912                 }
       
   913             if ( !item.IsSet() )
       
   914                 {
       
   915                 User::Leave( KErrNotReady );
       
   916                 }
       
   917             CNcdConfigurationProtocolQueryResponseValueImpl* value = 
       
   918                 CNcdConfigurationProtocolQueryResponseValueImpl::NewLC();
       
   919             AssignDesL( value->iId, item.Id() );
       
   920             HBufC* valueDes = item.ValueL().AllocLC();
       
   921             value->iValues.AppendL( valueDes );
       
   922             CleanupStack::Pop( valueDes );
       
   923             queryResponse->iResponses.AppendL( value );
       
   924             CleanupStack::Pop( value );
       
   925             DLINFO((_L("Added query item response id=%S, value=%S"),
       
   926                 value->iId, valueDes ));
       
   927             }
       
   928         }
       
   929     
       
   930     CleanupStack::Pop( queryResponse );
       
   931 
       
   932     return queryResponse;
       
   933     }
       
   934 
       
   935 
       
   936 void CNcdBaseOperation::QueryReceivedL( CNcdQuery* aQuery )
       
   937     {
       
   938     DLTRACEIN((""));
       
   939     aQuery->InternalAddRef();
       
   940     iOperationState = EStateQuery;
       
   941     DASSERT( ! iActiveQuery );
       
   942     iActiveQuery = aQuery;
       
   943     HandleEngineQueryItemsL( iActiveQuery );
       
   944     if ( iActiveQuery->ItemCount() > 0 && iActiveQuery->AllItemsSet() )
       
   945         {
       
   946         // all items set by engine, accept and complete
       
   947         DLTRACEIN(("all items set by engine -> complete"));
       
   948         iActiveQuery->SetResponseL( MNcdQuery::EAccepted );
       
   949         iOperationState = EStateRunning;
       
   950         QueryHandledL( iActiveQuery );
       
   951         DLTRACEOUT((""));
       
   952         return;
       
   953         }
       
   954     else if ( iIsSubOperation )
       
   955         {
       
   956         DASSERT( iObservers.Count() > 0 )
       
   957         // this is a sub operation send the query to observer
       
   958         // maybe there should be only one observer/parent
       
   959         iObservers[0]->QueryReceived( *this, aQuery );
       
   960         }
       
   961     else if ( iPendingMessage )
       
   962         {
       
   963         TInt err = CompleteMessage( iPendingMessage, ENCDOperationMessageCompletionQuery,
       
   964             *iActiveQuery, KErrNone );
       
   965         if ( err != KErrNone )
       
   966             {
       
   967             FailOperation( err );
       
   968             }
       
   969         }
       
   970     DLTRACEOUT((""));
       
   971     }
       
   972     
       
   973 void CNcdBaseOperation::CompleteCallback()
       
   974     {
       
   975     for ( TInt i = 0 ; i < iObservers.Count() ; i++ )
       
   976         {
       
   977         iObservers[i]->OperationComplete( this, iError );
       
   978         }
       
   979     }
       
   980     
       
   981 void CNcdBaseOperation::ContinueOperationL()
       
   982     {
       
   983     DLTRACEIN((""));
       
   984     if( !iRunner )
       
   985         {
       
   986         iRunner = CNcdAsyncRunner::NewL( this );
       
   987         }
       
   988     iRunner->Start();
       
   989     }
       
   990 
       
   991 TInt CNcdBaseOperation::SendExpirationInfo(
       
   992     RPointerArray<CNcdExpiredNode>& aExpiredNodes )
       
   993     {
       
   994     DLTRACEIN((""));
       
   995     if( iPendingMessage )
       
   996         {
       
   997         return CompleteMessage( iPendingMessage, 
       
   998             ENCDOperationMessageCompletionExpirationInfo,
       
   999             aExpiredNodes,
       
  1000             iError );
       
  1001         }
       
  1002     return KErrNotFound;
       
  1003     }
       
  1004 
       
  1005 TBool CNcdBaseOperation::QueryCompletedL( CNcdQuery* /*aQuery*/ )
       
  1006     {
       
  1007     DLTRACEIN(("THIS SHOULD NOT BE CALLED! ERROR!"));
       
  1008     DASSERT( 0 );
       
  1009     return EFalse;
       
  1010     }
       
  1011 
       
  1012 CNcdQuery* CNcdBaseOperation::ActiveQuery()
       
  1013     {
       
  1014     if( iActiveQuery )
       
  1015         {
       
  1016         iActiveQuery->InternalAddRef();
       
  1017         return iActiveQuery;
       
  1018         }
       
  1019     return NULL;
       
  1020     }
       
  1021 
       
  1022 TInt CNcdBaseOperation::QueryEntityCount()
       
  1023     {
       
  1024     return iEmbeddedDataQuerys.Count();
       
  1025     }
       
  1026 
       
  1027 const MNcdConfigurationProtocolQuery& CNcdBaseOperation::QueryEntityL(
       
  1028     const TDesC& aId )
       
  1029     {    
       
  1030     MNcdConfigurationProtocolQuery* query = NULL;
       
  1031     for ( TInt i = 0 ; i < iEmbeddedDataQuerys.Count() ; i++ )
       
  1032         {
       
  1033         if( iEmbeddedDataQuerys[i]->Id() == aId )
       
  1034             {
       
  1035             query = iEmbeddedDataQuerys[i];
       
  1036             break;
       
  1037             }
       
  1038         }
       
  1039     if ( query == NULL )
       
  1040         {
       
  1041         User::Leave( KErrNotFound );
       
  1042         }   
       
  1043     return *query;
       
  1044     }
       
  1045 
       
  1046 void CNcdBaseOperation::ContinueOperation()
       
  1047     {
       
  1048     RunOperation();
       
  1049     }
       
  1050 
       
  1051 void CNcdBaseOperation::FailOperation( TInt aError )
       
  1052     {
       
  1053     DLTRACEIN(("aError: %d",aError));
       
  1054     iError = aError;
       
  1055     Cancel();
       
  1056     if( iIsSubOperation )
       
  1057         {
       
  1058         // send to observer
       
  1059         for( TInt i = 0 ; i < iObservers.Count() ; i++ )
       
  1060             {
       
  1061             iObservers[i]->OperationComplete( this, iError );
       
  1062             }
       
  1063         }
       
  1064     else if ( iPendingMessage )
       
  1065         {
       
  1066         // complete message with error code, possible error message is ignored
       
  1067         // as the operation has already failed
       
  1068         CompleteMessage( iPendingMessage, 
       
  1069             ENCDOperationMessageCompletionError,
       
  1070             iError );
       
  1071         }
       
  1072     }
       
  1073     
       
  1074 void CNcdBaseOperation::AddQueryResponsesL( CNcdRequestBase* aRequest )
       
  1075     {
       
  1076     DLTRACEIN((""));
       
  1077     // add querys        
       
  1078     for ( TInt i = 0 ; i < iCompletedQuerys.Count() ; i++ )
       
  1079         {
       
  1080         CNcdQuery* query = iCompletedQuerys[i];
       
  1081         DASSERT(( query->Response() == MNcdQuery::EAccepted || 
       
  1082             query->Response() == MNcdQuery::ERejected ));
       
  1083         MNcdConfigurationProtocolQueryResponse* queryResponse =
       
  1084             CreateResponseL( *query );
       
  1085         CleanupStack::PushL( queryResponse );
       
  1086         aRequest->AddQueryResponseL( queryResponse );
       
  1087         CleanupStack::Pop( queryResponse );
       
  1088         }
       
  1089     }
       
  1090     
       
  1091 void CNcdBaseOperation::HandleQuerysL()
       
  1092     {
       
  1093     DLTRACEIN((""));
       
  1094     if ( iPendingQuerys.Count() > 0 )
       
  1095         {
       
  1096         // still a query left, send it to proxy
       
  1097         CNcdQuery* query = iPendingQuerys[0];
       
  1098         // Should set "is secure uri" flag
       
  1099         // remove from array
       
  1100         iPendingQuerys.Remove(0);
       
  1101         // handle query
       
  1102         CNcdBaseOperation::QueryReceivedL( query );
       
  1103         // release own reference
       
  1104         query->InternalRelease();
       
  1105         }
       
  1106     else
       
  1107         {
       
  1108         if( iCompletedQuerys.Count() > 0 )
       
  1109             {
       
  1110             // there are completed querys that need to be responded to
       
  1111             // -> resend request with the query responses
       
  1112             ResendRequestL();
       
  1113             }
       
  1114         else
       
  1115             {
       
  1116             // all queries handled, continue operation normally
       
  1117             ContinueOperationL();
       
  1118             }
       
  1119         }
       
  1120     }
       
  1121     
       
  1122 void CNcdBaseOperation::QueryHandledL( CNcdQuery* aQuery )
       
  1123     {
       
  1124     DLTRACEIN((""));
       
  1125     DASSERT( aQuery == iActiveQuery )
       
  1126     DASSERT( aQuery->Response() == MNcdQuery::EAccepted ||
       
  1127     aQuery->Response() == MNcdQuery::ERejected )
       
  1128 
       
  1129     // this may leave (e.g. in some cases when the query has been rejected )
       
  1130     TBool handled = QueryCompletedL( aQuery );
       
  1131     if ( !handled && aQuery->ItemCount() > 0 )
       
  1132         {
       
  1133         if( aQuery->Response() == MNcdQuery::EAccepted )
       
  1134             {
       
  1135             // query was not handled in the inheriting op, but was accepted
       
  1136             // add it to the list for later retrieval
       
  1137             iCompletedQuerys.AppendL( aQuery );
       
  1138             }
       
  1139         else if( aQuery->Semantics() == MNcdQuery::ESemanticsAuthenticationQuery &&
       
  1140             aQuery->Response() == MNcdQuery::ERejected )
       
  1141             {
       
  1142             // special case; server want's query responses for rejected authentication
       
  1143             // queries, so add it to the list
       
  1144             iCompletedQuerys.AppendL( aQuery );
       
  1145             }
       
  1146         else if( aQuery->Response() == MNcdQuery::ERejected 
       
  1147             && !aQuery->IsOptional() )
       
  1148             {
       
  1149             // a rejected, and mandatory, query was not handled -> fail the operation
       
  1150             User::Leave( KNcdErrorMandatoryQueryRejected );
       
  1151             }
       
  1152         else
       
  1153             {
       
  1154             // optional query rejected, release own reference to it
       
  1155             iActiveQuery->InternalRelease();
       
  1156             }
       
  1157         }
       
  1158     else
       
  1159         {
       
  1160         // query has been handled or has no items (i.e. server message)
       
  1161         // release own reference to it
       
  1162         iActiveQuery->InternalRelease();
       
  1163         }
       
  1164     // active query is now handled, set to null
       
  1165     iActiveQuery = NULL;
       
  1166     // handle querys if some are still left
       
  1167     HandleQuerysL();
       
  1168     }
       
  1169     
       
  1170 TInt CNcdBaseOperation::QueriesPending()
       
  1171     {
       
  1172     DLTRACEIN((""));
       
  1173     return iPendingQuerys.Count();
       
  1174     }
       
  1175     
       
  1176 void CNcdBaseOperation::ResendRequestL()
       
  1177     {
       
  1178     DLTRACEIN((""));
       
  1179     ChangeToPreviousStateL();
       
  1180     ContinueOperationL();
       
  1181     }
       
  1182 
       
  1183 void CNcdBaseOperation::ClearCompletedQueries()
       
  1184     {
       
  1185     DLTRACEIN((""));
       
  1186     for ( TInt i = 0 ; i < iCompletedQuerys.Count() ; i++ )
       
  1187         {
       
  1188         iCompletedQuerys[i]->InternalRelease();
       
  1189         }
       
  1190     iCompletedQuerys.Reset();
       
  1191     }