diff -r 000000000000 -r ba25891c3a9e ncdengine/provider/server/src/ncdsubscriptionoperationimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ncdengine/provider/server/src/ncdsubscriptionoperationimpl.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,1047 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include + +#include "ncdsubscriptionoperationimpl.h" +#include "catalogsbasemessage.h" +#include "catalogshttpincludes.h" +#include "ncdsubscriptionmanagerimpl.h" +#include "catalogsutils.h" +#include "catalogscontext.h" +#include "ncdproviderdefines.h" +#include "ncddescriptordownloadsuboperation.h" +#include "ncdrequestmanagesubscriptions.h" +#include "ncdrequestgenerator.h" +#include "ncdrequestconfigurationdata.h" +#include "ncdprotocol.h" +#include "ncdparser.h" +#include "ncdprotocoldefaultobserver.h" +#include "ncd_pp_error.h" +#include "ncd_pp_subscription.h" +#include "ncdsubscriptionimpl.h" +#include "ncdpurchaseoperationimpl.h" +#include "ncdsubscriptiongroup.h" +#include "ncdnodeidentifier.h" +#include "ncdserverdetails.h" +#include "ncdconfigurationmanager.h" +#include "ncdcapabilities.h" +#include "ncderrors.h" +#include "ncdsessionhandler.h" +#include "ncdproviderutils.h" +#include "ncdhttputils.h" +#include "ncdgeneralmanager.h" + +#include "catalogsdebug.h" + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +// +CNcdSubscriptionOperation* CNcdSubscriptionOperation::NewL( + MNcdSubscriptionOperation::TType aSubscriptionOperationType, + CNcdGeneralManager& aGeneralManager, + CNcdSubscriptionManager& aSubscriptionManager, + MCatalogsHttpSession& aHttpSession, + MNcdOperationRemoveHandler& aRemoveHandler, + MCatalogsSession& aSession ) + { + CNcdSubscriptionOperation* self = CNcdSubscriptionOperation::NewLC( + aSubscriptionOperationType, + aGeneralManager, + aSubscriptionManager, + aHttpSession, + aRemoveHandler, + aSession ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// NewLC +// --------------------------------------------------------------------------- +// +CNcdSubscriptionOperation* CNcdSubscriptionOperation::NewLC( + MNcdSubscriptionOperation::TType aSubscriptionOperationType, + CNcdGeneralManager& aGeneralManager, + CNcdSubscriptionManager& aSubscriptionManager, + MCatalogsHttpSession& aHttpSession, + MNcdOperationRemoveHandler& aRemoveHandler, + MCatalogsSession& aSession ) + { + CNcdSubscriptionOperation* self = + new( ELeave ) CNcdSubscriptionOperation( + aSubscriptionOperationType, + aGeneralManager, + aSubscriptionManager, + aHttpSession, + aRemoveHandler, + aSession ); + CleanupClosePushL( *self ); + self->ConstructL( NULL, KNullDesC, KNullDesC, KNullDesC, KNullDesC ); + return self; + } + + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +// +CNcdSubscriptionOperation* CNcdSubscriptionOperation::NewL( + MNcdSubscriptionOperation::TType aSubscriptionOperationType, + const TDesC& aPurchaseOptionId, + const TDesC& aEntityId, + const TDesC& aNamespace, + const TDesC& aServerUri, + CNcdGeneralManager& aGeneralManager, + CNcdSubscriptionManager& aSubscriptionManager, + MCatalogsHttpSession& aHttpSession, + MNcdOperationRemoveHandler& aRemoveHandler, + MCatalogsSession& aSession ) + { + CNcdSubscriptionOperation* self = CNcdSubscriptionOperation::NewLC( + aSubscriptionOperationType, + aPurchaseOptionId, + aEntityId, + aNamespace, + aServerUri, + aGeneralManager, + aSubscriptionManager, + aHttpSession, + aRemoveHandler, + aSession ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// NewLC +// --------------------------------------------------------------------------- +// +CNcdSubscriptionOperation* CNcdSubscriptionOperation::NewLC( + MNcdSubscriptionOperation::TType aSubscriptionOperationType, + const TDesC& aPurchaseOptionId, + const TDesC& aEntityId, + const TDesC& aNamespace, + const TDesC& aServerUri, + CNcdGeneralManager& aGeneralManager, + CNcdSubscriptionManager& aSubscriptionManager, + MCatalogsHttpSession& aHttpSession, + MNcdOperationRemoveHandler& aRemoveHandler, + MCatalogsSession& aSession ) + { + CNcdSubscriptionOperation* self = + new( ELeave ) CNcdSubscriptionOperation( + aSubscriptionOperationType, + aGeneralManager, + aSubscriptionManager, + aHttpSession, + aRemoveHandler, + aSession ); + CleanupClosePushL( *self ); + self->ConstructL( + NULL, + aPurchaseOptionId, + aEntityId, + aNamespace, + aServerUri ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CNcdSubscriptionOperation::~CNcdSubscriptionOperation() + { + DLTRACEIN(("")); + + DLTRACE(("Closing suboperations")); + // Close operations + for ( TInt i = 0; i < iSubOps.Count(); i++ ) + { + iSubOps[i]->Close(); + } + + DLTRACE(("Suboperations closed")); + iSubOps.Reset(); + iFailedSubOps.Reset(); + iCompletedSubOps.Reset(); + + if ( iTransaction ) + { + iTransaction->Release(); + iTransaction = NULL; + } + + iServersSubscriptions.ResetAndDestroy(); + + delete iSource; + delete iPurchaseOptionId; + delete iEntityId; + delete iNamespace; + delete iServerUri; + + delete iParser; + + DLTRACEOUT(("")); + } + + +TInt CNcdSubscriptionOperation::RunOperation() + { + DLTRACEIN(( "Pending message: %X", iPendingMessage )); + + // Cannot determine from iOperationState whether we are + // just starting this operation or continuing it after + // for example expiration info has been handled. + // This is because iOperationState will be EStateRunning + // In both cases. This is why we use our own internal + // variable. + if ( iSubscriptionOperationState == EBegin ) + { + // Operation is being started and we come here for + // the first time + iSubscriptionOperationState = ERunning; + } + else if ( iSubscriptionOperationState == EComplete ) + { + // It is possible that the operation has completed while we have + // been processing for example expired nodes. So we send completion + // message immediately. + if ( iPendingMessage ) + { + return CompletePendingMessage(); + } + return KErrGeneral; + } + else if ( iSubscriptionOperationState == EHandlingQueries ) + { + DLTRACE(("Queries handled")); + SubscriptionOperationComplete( iError ); + } + else + { + // We don't want to start the operation again as it + // is already running. Something should eventually trigger + // completion of iMessage + return KErrNone; + } + + TRAPD( err, + { + switch ( iSubscriptionOperationType ) + { + case MNcdSubscriptionOperation::EUnsubscribe: + RunUnsubscribeOperationL(); + break; + case MNcdSubscriptionOperation::ERefreshSubscriptions: + RunRefreshOperationL(); + break; + default: + User::Leave( KErrNotSupported ); + break; + } + } ); + + if ( err != KErrNone ) + { + SubscriptionOperationComplete( err ); + } + + DLTRACEOUT(("err: %d", err)); + return err; + } + +void CNcdSubscriptionOperation::Cancel() + { + DLTRACEIN( ( "" ) ); + + if ( iTransaction ) + { + iTransaction->Cancel(); + iTransaction = NULL; + } + if ( iParser ) + { + iParser->CancelParsing(); + //delete iParser; + //iParser = NULL; + } + + CancelSuboperations(); + + DLTRACEOUT(( "" )); + } + + +TBool CNcdSubscriptionOperation::QueryCompletedL( CNcdQuery* /* aQuery */ ) + { + DLTRACEIN(("")); + return EFalse; + } + + +void CNcdSubscriptionOperation::HandleHttpEventL( + MCatalogsHttpOperation& aOperation, + TCatalogsHttpEvent aEvent ) + { + DLTRACEIN(("")); + DASSERT( &aOperation == iTransaction ); + DASSERT( aOperation.OperationType() == ECatalogsHttpTransaction ); + + TCatalogsTransportProgress progress( iTransaction->Progress() ); + + switch( aEvent.iOperationState ) + { + // Handle completed operation + case ECatalogsHttpOpCompleted: + { + // Inform parser that no more data will be sent + iParser->EndL(); + break; + } + // Handle operation in progress + case ECatalogsHttpOpInProgress: + { + if( aEvent.iProgressState == ECatalogsHttpResponseBodyReceived ) + { + // send received data to parser + iParser->ParseL( aOperation.Body() ); + } + break; + } + + default: + { + break; + } + } + + DLTRACEOUT(("")); + } + +TBool CNcdSubscriptionOperation::HandleHttpError( + MCatalogsHttpOperation& aOperation, + TCatalogsHttpError aError ) + { + DLTRACEIN(("Error type: %d, code: %d", aError.iType, aError.iError )); + + DASSERT( &aOperation == iTransaction ); + + aOperation.Release(); + iTransaction = NULL; + + SubscriptionOperationComplete( aError.iError ); + + DLTRACEOUT(("")); + return ETrue; + } + +void CNcdSubscriptionOperation::ParseError( TInt aErrorCode ) + { + DLTRACEIN(("error:%d", aErrorCode )); + + // Handle error only if operation is not completed already + // (cancellation of parsing may cause an unnecessary call to this function). + if ( iSubscriptionOperationState != EComplete ) + { + if ( iTransaction ) + { + iTransaction->Cancel(); + iTransaction = NULL; + } + + SubscriptionOperationComplete( aErrorCode ); + + } + + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::ParseCompleteL( TInt aError ) + { + DLTRACEIN((_L("error:%d"), aError )); + + if ( iParser ) + { + delete iParser; + iParser = NULL; + } + + // HandleQuerysL will continue the operation in RunOperation + iSubscriptionOperationState = EHandlingQueries; + iError = aError; + HandleQuerysL(); + + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::ValidSubscriptionL( + MNcdPreminetProtocolSubscription* aData ) + { + DLTRACEIN(("")); + + iServersSubscriptions.AppendL( aData ); + + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::OldSubscriptionL( + MNcdPreminetProtocolSubscription* aData ) + { + DLTRACEIN(("")); + + iServersSubscriptions.AppendL( aData ); + + DLTRACEOUT(("")); + } + + +void CNcdSubscriptionOperation::Progress( CNcdBaseOperation& /*aOperation*/ ) + { + DLTRACEIN(("")); + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::QueryReceived( CNcdBaseOperation& /*aOperation*/, + CNcdQuery* /*aQuery*/ ) + { + DLTRACEIN(("")); + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::OperationComplete( + CNcdBaseOperation* aOperation, + TInt aError ) + { + DLTRACEIN(("error=%d", aError)); + + if ( iSubscriptionOperationType == MNcdSubscriptionOperation::EUnsubscribe ) + { + SubscriptionOperationComplete( aError ); + } + else if ( iSubscriptionOperationType == + MNcdSubscriptionOperation::ERefreshSubscriptions ) + { + DLINFO(("Refresh subscription op complete.")); + + TRAPD( err, + { + CNcdSubscriptionOperation* subOp = + static_cast( aOperation ); + + if ( aError != KErrNone ) + { + DLINFO(("Refresh sub operation failed.")); + iFailedSubOps.AppendL( subOp ); + if ( iCompletionErrorCode == KErrNone ) + { + iCompletionErrorCode = aError; + } + } + else + { + DLINFO(("Refresh sub operation successfull.")); + iCompletedSubOps.AppendL( subOp ); + } + } ); //TRAPD + + if ( err != KErrNone ) + { + DLERROR(("Internal subscription operation error")); + SubscriptionOperationComplete( err ); + } + else if ( iFailedSubOps.Count() + iCompletedSubOps.Count() == + iSubOps.Count() ) + { + // All sub operations completed, the operation is complete. + if ( iFailedSubOps.Count() && iCompletedSubOps.Count() ) + { + // Some suboperations has failed, but not all. + SubscriptionOperationComplete( KNcdErrorSomeSubscriptionsFailedToUpdate ); + } + else if ( iFailedSubOps.Count() ) + { + // All suboperations has failed. + SubscriptionOperationComplete( iCompletionErrorCode ); + } + else + { + SubscriptionOperationComplete( KErrNone ); + } + } + } + + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::ErrorL( MNcdPreminetProtocolError* aData ) + { + DLTRACEIN(("")); + + CleanupDeletePushL( aData ); + + // Map error codes to correct enumeration values. + switch ( aData->Code() ) + { + case 404: + { + iError = KNcdErrorNotFound; + DASSERT( iSubscription ); + if ( iSubscription ) + { + RemoveSubscriptionL( *iSubscription ); + iSubscription = NULL; + } + break; + } + case 416: + { + DLTRACE(("session expired")); + Cancel(); + + switch ( iSubscriptionOperationType ) + { + case MNcdSubscriptionOperation::EUnsubscribe: + { + iProtocol.SessionHandlerL( iSession.Context() ). + RemoveSession( *iServerUri, *iNamespace ); + break; + } + case MNcdSubscriptionOperation::ERefreshSubscriptions: + { + iProtocol.SessionHandlerL( iSession.Context() ). + RemoveSession( iSource->Uri(), iSource->Namespace() ); + break; + } + default: + DASSERT(0); + break; + } + + DLINFO(("Start operation from the beginning")); + // continue operation asynchronously to prevent problems with parser + ContinueOperationL(); + break; + } + case 426: + iError = KNcdErrorSubscriptionPaymentAlreadyDone; + break; + case 427: + iError = KNcdErrorSubscriptionNotSubscribed; + DASSERT( iSubscription ); + if ( iSubscription ) + { + RemoveSubscriptionL( *iSubscription ); + iSubscription = NULL; + } + break; + case 428: + iError = KNcdErrorSubscriptionInvalid; + DASSERT( iSubscription ); + if ( iSubscription ) + { + RemoveSubscriptionL( *iSubscription ); + iSubscription = NULL; + } + break; + case 429: + iError = KNcdErrorSubscriptionNotEnoughCredits; + break; + default: + iError = KNcdProtocolErrorBase - aData->Code(); + break; + } + + //CNcdBaseOperation::ErrorL( aData ); + + // Default observer deletes the data. + CleanupStack::Pop( aData ); + + iParser->DefaultObserver().ErrorL( aData ); + + if( iError != KErrNone ) + { + SubscriptionOperationComplete( iError ); + } + + DLTRACEOUT(("")); + } + +void CNcdSubscriptionOperation::SubscriptionsInternalizeComplete( + TInt /*aError*/ ) + { + DLTRACEIN(("")); + + // call observers + DLINFO(("Calling observers.")); + for ( TInt i = 0 ; i < iObservers.Count() ; i++ ) + { + DLINFO(("Calling observer: %d .", i )); + iObservers[i]->OperationComplete( this, KErrNone ); + } + } + +CNcdSubscriptionOperation* CNcdSubscriptionOperation::CreateSubOperationLC( + CNcdSubscriptionsSourceIdentifier* aSource, + CNcdGeneralManager& aGeneralManager, + CNcdSubscriptionManager& aSubscriptionManager, + MCatalogsHttpSession& aHttpSession, + MNcdOperationRemoveHandler& aRemoveHandler, + MCatalogsSession& aSession ) + { + CNcdSubscriptionOperation* self = + new( ELeave ) CNcdSubscriptionOperation( + MNcdSubscriptionOperation::ERefreshSubscriptions, + aGeneralManager, + aSubscriptionManager, + aHttpSession, + aRemoveHandler, + aSession ); + CleanupClosePushL( *self ); + self->ConstructL( aSource, KNullDesC, KNullDesC, KNullDesC, KNullDesC ); + return self; + } + +void CNcdSubscriptionOperation::RunRefreshOperationL() + { + DLTRACEIN(("")); + + if ( iSource ) + { + DLTRACE(( "Sub operation" )); + // This is a sub operation. Send request to the given source. + + CNcdRequestManageSubscriptions* request = + NcdRequestGenerator::CreateManageSubscriptionsRequestLC(); + + // Set namespace from the source. + request->SetNamespaceL( iSource->Namespace() ); + + MCatalogsContext& context( iSession.Context() ); + + HBufC8* data = + iProtocol.ProcessPreminetRequestL( + context, + *request, + iSource->Uri() ); + + CleanupStack::PopAndDestroy( request ); + CleanupStack::PushL( data ); + + // create transaction + iGeneralManager.HttpUtils().CreateTransactionL( + iHttpSession, + iTransaction, + iSource->Uri(), + *this, + *data, + iSource->Namespace(), + MCatalogsAccessPointManager::EBrowse, + iClientUid ); + + CleanupStack::PopAndDestroy( data ); + + // create parser + delete iParser; + iParser = NULL; + iParser = iProtocol.CreateParserL( context, iSource->Uri() ); + + // Set observers + MNcdParserObserverBundle& observers = iParser->Observers(); + observers.SetParserObserver( this ); + observers.SetSubscriptionObserver( this ); + observers.SetInformationObserver( this ); + observers.SetErrorObserver( this ); + + iParser->BeginAsyncL(); + + // start transaction + User::LeaveIfError( iTransaction->Start() ); + } + else + { + DLTRACE(( "Main operation" )); + // This is the main operation. Sub operations are started + // from here. + + // Get sources for sub operations. + RPointerArray sources = + iSubscriptionManager.SubscriptionsSourcesL( + iClientUid ); + CleanupResetAndDestroyPushL( sources ); + + TInt count = sources.Count(); + + DLTRACE(( "Source count: %d", count )); + + if ( count == 0 ) + { + // No sources found. + CleanupStack::PopAndDestroy( &sources ); + + SubscriptionOperationComplete( KErrNone ); + + DLTRACEOUT(("")); + return; + } + + // Start all sub operations. + for ( TInt i = 0; i < count; i++ ) + { + DLTRACE(( _L("Source URI: %S"), &sources[0]->Uri() )); + DLTRACE(( _L("Source namespace: %S"), &sources[0]->Namespace() )); + + const MCatalogsContext& context( iSession.Context() ); + MNcdServerDetails& serverDetails = + iConfigurationManager.ServerDetailsL( + context, + sources[0]->Uri(), + sources[0]->Namespace() ); + + // Capabilities are checked only if it is required + if ( sources[0]->RequiresCapabilityCheck() && + serverDetails.IsCapabilitySupported( + NcdCapabilities::KSubscriptions ) + || !sources[0]->RequiresCapabilityCheck() ) + { + DLTRACE(( "This source supports subscriptions!" )); + DLINFO(( "Capability check was required: %d", + sources[0]->RequiresCapabilityCheck() )); + + CNcdSubscriptionOperation* subOp = + CNcdSubscriptionOperation::CreateSubOperationLC( + sources[0], + iGeneralManager, + iSubscriptionManager, + iHttpSession, + *iRemoveHandler, + iSession ); + // CreateSubOperationLC takes the ownership of the first + // object in the sources array. Remove it from sources. + sources.Remove( 0 ); + subOp->AddObserverL( this ); + User::LeaveIfError( subOp->Start() ); + DLTRACE(( "Sub operation started!" )); + iSubOps.AppendL( subOp ); + CleanupStack::Pop( subOp ); + } + else + { + DLTRACE(( "This source does not support subscriptions!" )); + + // Do not use this source. + sources.Remove( 0 ); + } + } + + CleanupStack::PopAndDestroy( &sources ); + + // Any sub operations started + if ( iSubOps.Count() == 0 ) + { + DLTRACE(( "None of the sources did not support subscriptions!" )); + SubscriptionOperationComplete( KErrNone ); + } + } + + DLTRACEOUT(("")); + } + + +void CNcdSubscriptionOperation::RunUnsubscribeOperationL() + { + DLTRACEIN(("")); + + CNcdRequestManageSubscriptions* request = + NcdRequestGenerator::CreateManageSubscriptionsRequestLC(); + + request->SetNamespaceL( *iNamespace ); + request->AddSubscriptionL( + *iEntityId, + *iPurchaseOptionId, + EUnsubscribe ); + + MCatalogsContext& context( iSession.Context() ); + + HBufC8* data = + iProtocol.ProcessPreminetRequestL( + context, + *request, + *iServerUri ); + + CleanupStack::PopAndDestroy( request ); + CleanupStack::PushL( data ); + + // create transaction + iGeneralManager.HttpUtils().CreateTransactionL( + iHttpSession, + iTransaction, + *iServerUri, + *this, + *data, + *iNamespace, + MCatalogsAccessPointManager::EBrowse, + iClientUid ); + + CleanupStack::PopAndDestroy( data ); + + // create parser + delete iParser; + iParser = NULL; + iParser = iProtocol.CreateParserL( context, *iServerUri ); + + // Set observers + MNcdParserObserverBundle& observers = iParser->Observers(); + observers.SetParserObserver( this ); + observers.SetSubscriptionObserver( this ); + observers.SetInformationObserver( this ); + observers.SetErrorObserver( this ); + + iParser->BeginAsyncL(); + + // start transaction + User::LeaveIfError( iTransaction->Start() ); + + DLTRACEOUT(("")); + } + +TInt CNcdSubscriptionOperation::SubscriptionOperationComplete( TInt aError ) + { + DLTRACEIN(("")); + + // iSubscriptionOperationState is used in RunOperation to determine + // whether this operation has already completed (this function has been + // called). + // We should complete incoming message in RunOperation if it was not + // available in this function. + + // Notice that we cannot automatically set iOperationState to be + // EStateComplete as iOperationState is used when we receive + // continue message. State EStateComplete would produce an error in that + // case because it means that we are not waiting any messages anymore. + // This is why we have to use two state variables to inform of completion. + + iSubscriptionOperationState = EComplete; + + // Also given error code has to be stored if iPendingMessage is not + // currently available + iCompletionErrorCode = aError; + + + if ( aError != KErrNone ) + { + DLTRACE((_L("->Operation failed"))); + // Operation failed, send error message. + Cancel(); + if ( iPendingMessage ) + { + CompletePendingMessage(); + } + // call observers + for ( TInt i = 0 ; i < iObservers.Count() ; i++ ) + { + iObservers[i]->OperationComplete( this, aError ); + } + } + else + { + DLTRACE((_L("->Operation complete"))); + // Operation has completed. + + if ( iPendingMessage ) + { + TInt err = CompletePendingMessage(); + if ( err != KErrNone ) + { + // call observers + for ( TInt i = 0 ; i < iObservers.Count() ; i++ ) + { + iObservers[i]->OperationComplete( this, aError ); + } + return err; + } + } + + TInt err = KErrNone; + if ( iSource && iSubscriptionOperationType == + MNcdSubscriptionOperation::ERefreshSubscriptions ) + { + TRAP_IGNORE( + { + iSubscriptionManager.InternalizeSubscriptionsFromServerL( + iClientUid, + iSource->Uri(), + iServersSubscriptions, + &iSession.Context(), + this ); + } ); + + // Do not call operation complete here if this is + // suboperation. Instead do it after internalize in + // SubscriptionsInternalizeComplete() + DLTRACEOUT(("")); + return KErrNone; + } + + // call observers + DLINFO(("Calling observers.")); + for ( TInt i = 0 ; i < iObservers.Count() ; i++ ) + { + DLINFO(("Calling observer: %d .", i )); + iObservers[i]->OperationComplete( this, err ); + } + } + + DLTRACEOUT(("")); + return KErrNone; + } + +TInt CNcdSubscriptionOperation::CompletePendingMessage() + { + DASSERT( iPendingMessage ); + DLTRACEIN(( "Pending message: %X", iPendingMessage )); + + TInt err( 0 ); + if ( iCompletionErrorCode != KErrNone ) + { + err = CNcdBaseOperation::CompleteMessage( + iPendingMessage, + ENCDOperationMessageCompletionError, + iCompletionErrorCode ); + } + else + { + err = CNcdBaseOperation::CompleteMessage( iPendingMessage, + ENCDOperationMessageCompletionComplete, + iProgress, + KErrNone ); + } + // iPendingMessage = NULL set by CompleteMessage + + // Is this ok? + iOperationState = EStateComplete; + + return err; + } + +void CNcdSubscriptionOperation::RemoveSubscriptionL( + const CNcdSubscription& aSubscription ) + { + CNcdNodeIdentifier* nodeId = CNcdNodeIdentifier::NewLC( + aSubscription.ParentGroup().Namespace(), + aSubscription.ParentGroup().EntityId(), iClientUid ); + iSubscriptionManager.RemoveSubscriptionL( + *nodeId, aSubscription.PurchaseOptionId() ); + CleanupStack::PopAndDestroy( nodeId ); + } + + + +void CNcdSubscriptionOperation::ChangeToPreviousStateL() + { + DLTRACEIN(("")); + // Nothing to do. This is needed for query handling, ResendRequestL uses this + } + +void CNcdSubscriptionOperation::CancelSuboperations() + { + DLTRACEIN(("")); + + for ( TInt i = 0; i < iSubOps.Count(); i++ ) + { + CNcdSubscriptionOperation* operation = iSubOps[ i ]; + if ( iCompletedSubOps.Find( operation ) == KErrNotFound && + iFailedSubOps.Find( operation ) == KErrNotFound ) + { + DLINFO(("operation not completed yet, cancel it")); + operation->Cancel(); + } + } + } + + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CNcdSubscriptionOperation::CNcdSubscriptionOperation( + MNcdSubscriptionOperation::TType aSubscriptionOperationType, + CNcdGeneralManager& aGeneralManager, + CNcdSubscriptionManager& aSubscriptionManager, + MCatalogsHttpSession& aHttpSession, + MNcdOperationRemoveHandler& aRemoveHandler, + MCatalogsSession& aSession ) + : + CNcdBaseOperation( aGeneralManager, &aRemoveHandler, ESubscriptionOperation, aSession ), + iSubscriptionOperationState( EBegin ), + iSubscriptionOperationType( aSubscriptionOperationType ), + iAccessPointManager( aGeneralManager.AccessPointManager() ), + iSubscriptionManager( aSubscriptionManager ), + iNodeManager( aGeneralManager.NodeManager() ), + iConfigurationManager( aGeneralManager.ConfigurationManager() ), + iHttpSession( aHttpSession ), + iProtocol( aGeneralManager.ProtocolManager() ), + iCompletionErrorCode( KErrNone ) + { + } + + +// --------------------------------------------------------------------------- +// ConstructL +// --------------------------------------------------------------------------- +// +void CNcdSubscriptionOperation::ConstructL( + CNcdSubscriptionsSourceIdentifier* aSource, + const TDesC& aPurchaseOptionId, + const TDesC& aEntityId, + const TDesC& aNamespace, + const TDesC& aServerUri ) + + { + DLTRACEIN(("aSource=%08x", aSource)); + + // Call ConstructL for the base class + CNcdBaseOperation::ConstructL(); + + iSource = aSource; + iPurchaseOptionId = aPurchaseOptionId.AllocL(); + iEntityId = aEntityId.AllocL(); + iNamespace = aNamespace.AllocL(); + iServerUri = aServerUri.AllocL(); + + iClientUid = iSession.Context().FamilyId(); + + if ( iPurchaseOptionId->Length() > 0 && + iEntityId->Length() > 0 && + iNamespace->Length() > 0 ) + { + iSubscription = &iSubscriptionManager.SubscriptionL( + *iEntityId, + *iNamespace, + *iPurchaseOptionId, + iClientUid ); + } + + DLTRACEOUT(("")); + }