syncmlfw/common/alertqueue/src/NSmlAlertHandler.cpp
changeset 0 b497e44ab2fc
child 9 57a65a3a658c
--- /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