--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/common/alertqueue/src/NSmlAlertHandler.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,488 @@
+/*
+* Copyright (c) 2002-2004 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: Alert queue and handler
+*
+*/
+
+#include <nsmldebug.h>
+
+#include "NSmlAlertQueue.h"
+#include "nsmlsosserverdefs.h"
+
+//Fix to Remove the Bad Compiler Warnings
+#ifndef __WINS__
+// This lowers the unnecessary compiler warning (armv5) to remark.
+// "Warning: #174-D: expression has no effect..." is caused by
+// DBG_ARGS8 macro in no-debug builds.
+#pragma diag_remark 174
+#endif
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::NewL(MNSmlMessageHandler* aMsgHandler)
+// Two phase constructor
+// ---------------------------------------------------------
+//
+CNSmlAlertHandler* CNSmlAlertHandler::NewL( MNSmlMessageHandler* aMsgHandler )
+ {
+ CNSmlAlertHandler* self = new (ELeave) CNSmlAlertHandler;
+ CleanupStack::PushL( self );
+ self->ConstructL( aMsgHandler );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::CNSmlAlertHandler()
+// Constructor
+// ---------------------------------------------------------
+CNSmlAlertHandler::CNSmlAlertHandler()
+: CActive(0), iNewEntry( EFalse )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::~CNSmlAlertHandler()
+// Destructor
+// ---------------------------------------------------------
+CNSmlAlertHandler::~CNSmlAlertHandler()
+ {
+
+ Cancel();
+ if( !iHistoryArray )
+ {
+ iHistoryArray->SetOwnerShip( ETrue );
+ delete iHistoryArray;
+ }
+ delete iAlertParser;
+
+ if ( ! iNewEntry )
+ {
+ delete iAlertInfo;
+ delete iHistoryInfo;
+ }
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::DoCancel()
+// Method from base class
+// ---------------------------------------------------------
+void CNSmlAlertHandler::DoCancel()
+ {
+
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::ProcessAlert()
+// Activates alert handler
+// ---------------------------------------------------------
+void CNSmlAlertHandler::ProcessAlert()
+ {
+ if ( IsActive() )
+ {
+ return;
+ }
+ SetActive();
+ TRequestStatus* pStatus = &iStatus;
+ User::RequestComplete(pStatus, KErrNone);
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::ConstructL( MNSmlMessageHandler* aMsgHandler )
+// Second phase constructor
+// ---------------------------------------------------------
+void CNSmlAlertHandler::ConstructL( MNSmlMessageHandler* aMsgHandler )
+ {
+ User::LeaveIfNull(aMsgHandler);
+ iMsgHandler = aMsgHandler;
+
+ iHistoryInfo = CSyncMLHistoryPushMsg::NewL();
+
+ iAlertInfo = new ( ELeave ) CSmlAlertInfo;
+
+ iHistoryArray = CNSmlHistoryArray::NewL();
+ iHistoryArray->SetOwnerShip( EFalse ); // move ownership to history array
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::RunL()
+// Method from base class
+// ---------------------------------------------------------
+void CNSmlAlertHandler::RunL()
+ {
+ TRAP_IGNORE( DoRunL() );
+ };
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::DoRunL()
+// Method from base class
+// ---------------------------------------------------------
+void CNSmlAlertHandler::DoRunL()
+ {
+
+ // Delete member variables
+ iHistoryArray->SetOwnerShip( ETrue );
+ delete iHistoryArray;
+ iHistoryArray = NULL;
+ delete iAlertParser;
+ iAlertParser = NULL;
+
+ // These are deleted by iHistoryArray
+ iAlertInfo = NULL;
+ iHistoryInfo = NULL;
+
+ // Create member variables
+ iHistoryInfo = CSyncMLHistoryPushMsg::NewL();
+ iAlertInfo = new ( ELeave ) CSmlAlertInfo;
+ iHistoryArray = CNSmlHistoryArray::NewL();
+ iHistoryArray->SetOwnerShip( EFalse ); // move ownership to history array
+
+
+ // Continue DoRunL method
+ TBool message( EFalse );
+ TBool quit( ETrue );
+ TBool doPop( EFalse );
+
+ TPtrC8 pPackage;
+ TSmlUsageType type;
+ TSmlProtocolVersion version;
+ TSmlTransportId bearerType;
+
+ //check message
+ iMsgHandler->CheckMessage( message, type, version, bearerType );
+ iAlertInfo->SetJobControl( CSmlAlertInfo::EDoNotCreateJob );
+ iAlertInfo->SetTransportId( bearerType );
+ #ifdef __NSML_DEBUG__
+ DBG_ARGS(_S("CNSmlAlertHandler::RunL(): TransportId : '%d'"), bearerType );
+ #endif // __NSML_DEBUG__
+
+ TInt err( KErrNone );
+
+ if ( message )
+ {
+
+ iAlertParser = NSmlParserFactory::CreateAlertParserL( type, version, *iAlertInfo, *iHistoryInfo );
+ iAlertParser->CreateBufferL( iMsgHandler->MessageSize() );
+ iMsgHandler->AlertMessage( iAlertParser->Message() );
+
+ TRAP(err, iAlertParser->ParseMessageL());
+ DBG_FILE_CODE(err, _S8("CNSmlAlertHandler::RunL() : Alert result"));
+ iAlertInfo->SetErrorCode( err );
+
+ iNewEntry = ETrue;
+
+ if ( err != KErrNone)
+ {
+ iNewEntry = EFalse;
+ iAlertInfo->SetJobControl( CSmlAlertInfo::EDoNotCreateJob );
+
+ // Close local connection
+ if ( bearerType != KUidNSmlMediumTypeInternet.iUid )
+ {
+ iMsgHandler->DoDisconnect();
+ }
+
+ if ( err == KErrCorrupt )
+ {
+ return;
+ }
+ }
+ else
+ {
+ CheckDigestL( iAlertInfo->Profile(), iHistoryInfo->MsgDigest() );
+
+ CheckProtocolAndChangeL( version );
+
+ if ( ( type == ESmlDataSync ) && ( version == ESmlVersion1_1_2 ) )
+ {
+ iAlertInfo->SetConfirmation( ETrue );
+ pPackage.Set( iAlertParser->DoMessageCopyLC() );
+ doPop = ETrue;
+ }
+ }
+
+ delete iAlertParser;
+ iAlertParser = NULL;
+ }
+
+ iAlertInfo->SetConfirmation( FinalizeBeforeJobCreationL() );
+ iMsgHandler->CreateJobL( *iAlertInfo, quit, pPackage);
+
+ if ( doPop )
+ {
+ CleanupStack::PopAndDestroy(); // DoMessageCopyLC()
+ }
+
+
+ if (! quit)
+ {
+ ProcessAlert();
+ }
+
+ }
+
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::FinalizeBeforeJobCreationL()
+// Connects to notifier plug in to show confirmation note and
+// waits for the response.
+// ---------------------------------------------------------
+TBool CNSmlAlertHandler::FinalizeBeforeJobCreationL()
+ {
+
+ if ( iAlertInfo->Profile() < KMaxDataSyncID )
+ {
+ CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+
+ CNSmlDSProfile* profile = settings->ProfileL( iAlertInfo->Profile() );
+
+ if ( !profile )
+ {
+ CleanupStack::PopAndDestroy(); //settings
+ return EFalse;
+ }
+
+ CleanupStack::PushL( profile );
+
+ iAlertInfo->SetTransportId( profile->IntValue( EDSProfileTransportId) );
+ iAlertInfo->SetConnectionId( profile->IntValue( EDSProfileTransportId) );
+
+ CleanupStack::PopAndDestroy(2); //profile, settings
+ }
+ else
+ {
+ CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+
+ CNSmlDMProfile* profile = settings->ProfileL( iAlertInfo->Profile() );
+
+ if ( !profile )
+ {
+ CleanupStack::PopAndDestroy(); //settings
+ return EFalse;
+ }
+
+ CleanupStack::PushL( profile );
+ profile->SetIntValue( EDMProfileSessionId, iAlertInfo->SessionId() );
+ profile->SaveL();
+
+ iAlertInfo->SetTransportId( profile->IntValue( EDMProfileTransportId) );
+ iAlertInfo->SetConnectionId( profile->IntValue( EDMProfileTransportId) );
+
+ CleanupStack::PopAndDestroy(2); //profile, settings
+ }
+
+ SaveAlertInfoL();
+
+ if ( ! iAlertInfo->CreateSession() )
+ {
+ return ETrue;
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// CheckDigestL( const TInt aProfileId, const TDesC8& aDigest )
+// Checks whether alert has already been handled. Receive count
+// is updated if handled before.
+// ---------------------------------------------------------
+void CNSmlAlertHandler::CheckDigestL( const TInt aProfileId, const TDesC8& aDigest )
+ {
+
+ if ( aProfileId < KMaxDataSyncID )
+ {
+ CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+
+ CNSmlDSProfile* profile = settings->ProfileL(aProfileId);
+ CleanupStack::PushL(profile);
+
+ if ( ! profile->HasLogL() )
+ {
+ CleanupStack::PopAndDestroy(2); //profile, settings
+ return;
+ }
+
+ RReadStream& readStream = profile->LogReadStreamL();
+ CleanupClosePushL( readStream );
+
+ iHistoryArray->InternalizeL(readStream);
+
+ CleanupStack::PopAndDestroy(); //readStream
+
+ for (TInt i = 0; i < iHistoryArray->Count(); i++)
+ {
+ CSyncMLHistoryEntry& hEntry = iHistoryArray->Entry(i);
+ CSyncMLHistoryPushMsg * pushMsg = CSyncMLHistoryPushMsg::DynamicCast(&hEntry);
+
+ if (pushMsg == NULL)
+ continue;
+
+ if ( aDigest.Compare( pushMsg->MsgDigest() ) == 0)
+ {
+ pushMsg->IncReceivedCount();
+ iNewEntry = EFalse;
+ iAlertInfo->SetConfirmation( iNewEntry );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(2); //profile, settings
+ }
+ else
+ {
+ CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+
+ CNSmlDMProfile* profile = settings->ProfileL(aProfileId);
+ CleanupStack::PushL(profile);
+
+ if ( ! profile->HasLogL() )
+ {
+ CleanupStack::PopAndDestroy(2); //profile, settings
+ return;
+ }
+
+ RReadStream& readStream = profile->LogReadStreamL();
+ CleanupClosePushL( readStream );
+
+ iHistoryArray->InternalizeL( readStream );
+
+ CleanupStack::PopAndDestroy(); //readStream
+
+ for (TInt i = 0; i < iHistoryArray->Count(); i++)
+ {
+ CSyncMLHistoryEntry& hEntry = iHistoryArray->Entry(i);
+ CSyncMLHistoryPushMsg * pushMsg = CSyncMLHistoryPushMsg::DynamicCast(&hEntry);
+
+ if (pushMsg == NULL)
+ continue;
+
+ if ( aDigest.Compare( pushMsg->MsgDigest() ) == 0)
+ {
+ pushMsg->IncReceivedCount();
+ iNewEntry = EFalse;
+ iAlertInfo->SetConfirmation( iNewEntry );
+ }
+ }
+ CleanupStack::PopAndDestroy(2); //profile, settings
+ }
+ }
+
+// ---------------------------------------------------------
+// CNSmlAlertHandler::SaveAlertInfoL( )
+// Saves the result to profile history log and adds new entry
+// ---------------------------------------------------------
+void CNSmlAlertHandler::SaveAlertInfoL( )
+ {
+
+ TInt profileId( iAlertInfo->Profile() );
+
+ if ( profileId == KNSmlNullId )
+ {
+ return;
+ }
+
+ if ( profileId < KMaxDataSyncID )
+ {
+ CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+
+ CNSmlDSProfile* profile = settings->ProfileL( profileId );
+ CleanupStack::PushL( profile );
+ RWriteStream& stream = profile->LogWriteStreamL();
+ CleanupClosePushL( stream );
+
+ if ( iNewEntry )
+ {
+ RPointerArray<CSmlAlertInfo> alertInfoArray;
+ CleanupClosePushL( alertInfoArray );
+
+ alertInfoArray.AppendL( iAlertInfo );
+
+ iHistoryInfo->AddAlertsL( alertInfoArray );
+ iHistoryArray->AppendEntryL( iHistoryInfo );
+ CleanupStack::PopAndDestroy(); //alertInfoArray
+ }
+
+ iHistoryArray->ExternalizeL(stream);
+
+ CleanupStack::PopAndDestroy(); //stream
+
+ profile->WriteStreamCommitL();
+
+ CleanupStack::PopAndDestroy(2); // profile, settings
+ }
+ else
+ {
+ CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+
+ CNSmlDMProfile* profile = settings->ProfileL( profileId );
+ CleanupStack::PushL( profile );
+
+ RWriteStream& stream = profile->LogWriteStreamL();
+ CleanupClosePushL( stream );
+
+ if ( iNewEntry )
+ {
+ RPointerArray<CSmlAlertInfo> alertInfoArray;
+ CleanupClosePushL( alertInfoArray );
+
+ alertInfoArray.AppendL( iAlertInfo );
+
+ iHistoryInfo->AddAlertsL( alertInfoArray );
+ iHistoryArray->AppendEntryL( iHistoryInfo );
+
+ CleanupStack::PopAndDestroy(); //alertInfoArray
+ }
+
+ iHistoryArray->ExternalizeL( stream );
+ CleanupStack::PopAndDestroy(); //stream
+
+ profile->WriteStreamCommitL();
+
+ CleanupStack::PopAndDestroy(2); // profile, settings
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CheckProtocolAndChange(TSmlProtocolVersion& aVersion)
+// Checks if profile has different version and chages to alert's
+// version if different.
+// ---------------------------------------------------------
+void CNSmlAlertHandler::CheckProtocolAndChangeL( TSmlProtocolVersion& aVersion ) const
+ {
+ TInt profileId( iAlertInfo->Profile() );
+
+ if ( profileId == KNSmlNullId )
+ {
+ return;
+ }
+
+ if ( profileId < KMaxDataSyncID )
+ {
+ CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+ CNSmlDSProfile* profile = settings->ProfileL( profileId );
+ CleanupStack::PushL( profile );
+
+ if ( profile->IntValue( EDSProfileProtocolVersion ) != aVersion )
+ {
+ profile->SetIntValue( EDSProfileProtocolVersion, (TInt) aVersion );
+ profile->SaveL();
+ }
+
+ CleanupStack::PopAndDestroy(2); // profile, settings
+ }
+ }
+
+//End of File