syncmlfw/common/sosserver/src/nsmlsoshandler.cpp
changeset 0 b497e44ab2fc
child 25 b183ec05bd8c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/common/sosserver/src/nsmlsoshandler.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1438 @@
+/*
+* Copyright (c) 2002-2005 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:  Symbian OS Server source.
+*
+*/
+
+#include <s32mem.h>
+#include <ecom.h>
+#include <implementationinformation.h>
+//#include <syncmlnotifier.h>
+#include <e32property.h>
+#include <DevManInternalCRKeys.h>
+#include <centralrepository.h>
+#include <nsmlconstants.h>
+#include <nsmldebug.h>
+#include <nsmldsconstants.h>
+
+#include "nsmlsosserver.h"
+#include "nsmltransport.h"
+#include "nsmlsosthread.h"
+#include "nsmlprivatepskeys.h"
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler* CNSmlSOSHandler::NewL()
+// --------------------------------------------------------------------------
+//
+CNSmlSOSHandler* CNSmlSOSHandler::NewL()
+    {
+	CNSmlSOSHandler* self= new (ELeave) CNSmlSOSHandler();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(); // self
+	return self;    
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::ConstructL()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::ConstructL()
+    {
+    iMsgQueue = CNSmlMessageQueue::NewL(this);
+    iContactSuiteObserverProfileId = 0;
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler::CNSmlSOSHandler()
+// --------------------------------------------------------------------------
+//
+CNSmlSOSHandler::CNSmlSOSHandler() : CActive(EPriorityStandard), iSessionCount(0)
+    {     
+    CActiveScheduler::Add(this);
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler::~CNSmlSOSHandler()
+// --------------------------------------------------------------------------
+//
+CNSmlSOSHandler::~CNSmlSOSHandler()
+    {
+    Cancel();
+    delete iMsgQueue;
+    
+    delete iParams;
+    delete iThreadObserver;
+  	
+    iProfileLocks.Close();
+    iSessionLib.Close();
+    iEventMsgs.Close();
+    iProgressMsgs.Close();
+	iContactSuiteProgressMsgs.Close();
+    
+    iWrtStream.Close();
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::LockProfile( const TInt aProfId )
+// Adds profile to the array of locked profiles.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::LockProfile( const TInt aProfId )
+    {
+    iProfileLocks.Append( aProfId );
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::RemoveLock( const TInt aProfId )
+// Removes lock from profile.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::RemoveLock( const TInt aProfId )
+    {
+    TInt index = iProfileLocks.Find( aProfId );
+
+    if ( index != KErrNotFound )
+        {
+        iProfileLocks.Remove(index);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// TBool CNSmlSOSHandler::IsLocked( const TInt aProfId )
+// Checks whether profile is locked or not.
+// --------------------------------------------------------------------------
+//
+TBool CNSmlSOSHandler::IsLocked( const TInt aProfId )
+    {
+    if ( iProfileLocks.Find( aProfId ) != KErrNotFound )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// TInt CNSmlSOSHandler::AddJobL( CNSmlJob* aJob, TInt& aJobId )
+// Adds a created job to the job queue.
+// --------------------------------------------------------------------------
+//
+TInt CNSmlSOSHandler::AddJobL( CNSmlJob* aJob, TInt& aJobId )
+    {
+    aJobId = CreateJobId();
+    aJob->SetJobId( aJobId );
+    if ( !iCurrentJob )
+        {
+        iCurrentJob = aJob;
+        
+        if ( iCurrentJob->UsageType() == ESmlDataSync )
+            {
+            StartDSSyncL();
+            }
+        else
+            {
+            StartDMSyncL();
+            }
+        }
+    else
+        {
+        if ( SearchSimilarJobs( aJob ) )
+            {
+            delete aJob;
+            aJob = NULL;
+            return KErrAlreadyExists;
+            }
+        CNSmlJob* tempJob = iCurrentJob;
+        
+        while ( tempJob->iNext )
+            {            
+            tempJob = tempJob->iNext;
+            }
+
+        tempJob->iNext = aJob;    
+        }
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlJob* CNSmlSOSHandler::FindJob( TInt aJobId )
+// Finds job from queue.
+// --------------------------------------------------------------------------
+//
+CNSmlJob* CNSmlSOSHandler::FindJob( TInt aJobId )
+    {
+    if ( iCurrentJob )
+        {
+        CNSmlJob* job = iCurrentJob;
+        if ( job->JobId() == aJobId )
+            {
+            return iCurrentJob; 
+            }
+        while ( job->iNext )
+            {
+            job = job->iNext;
+            if ( job->JobId() == aJobId )
+                {
+                return job;
+                }
+            }
+        }
+    return NULL;   
+    }
+
+// --------------------------------------------------------------------------
+// TInt CNSmlSOSHandler::CreateJobId()
+// Creates an id to the new job.
+// --------------------------------------------------------------------------
+//
+TInt CNSmlSOSHandler::CreateJobId()
+    {
+    return iJobIndex++;
+    }
+
+// --------------------------------------------------------------------------
+// TInt CNSmlSOSHandler::StopJob( const TInt aJobId, const TInt aCreatorId )
+// Removes job from queue or cancels the job if currently running.
+// --------------------------------------------------------------------------
+//
+TInt CNSmlSOSHandler::StopJob( const TInt aJobId, const TInt aCreatorId )
+    {
+    if ( !iCurrentJob )
+        {
+        return KErrNotFound;
+        }
+    if ( iCurrentJob->JobId() == aJobId )
+        {
+        if ( iCurrentJob->CreatorId() != aCreatorId )
+            {
+            return KErrPermissionDenied;
+            }
+        else
+            {
+            if ( iCurrentJob->UsageType() == ESmlDataSync )
+                {
+                CancelDSSync();
+                }
+            else
+                {
+                CancelDMSync();
+                }           
+            return KErrNone;
+            }
+        }
+    else
+        {
+        CNSmlJob* tempJob = iCurrentJob;
+        CNSmlJob* prevJob = iCurrentJob;
+        while ( tempJob->iNext )
+            {
+            prevJob = tempJob;
+            tempJob = tempJob->iNext;
+            if ( tempJob->JobId() == aJobId )
+                {
+ 				if ( tempJob->CreatorId() != aCreatorId )
+                    {
+                    return KErrPermissionDenied;
+                    }
+                else
+                    {
+                    CNSmlJob* nextJob = tempJob->iNext;
+                    TRAP_IGNORE( CompleteEventMsgL( MSyncMLEventObserver::EJobStop, tempJob->JobId(), KErrNone ));  
+                    delete tempJob;
+                    prevJob->iNext = nextJob;
+                    tempJob = nextJob;
+                    return KErrNone;
+                    }
+                }            
+            }
+        }
+    return KErrNotFound;
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CurrentJob( TInt& aId, TSmlUsageType& aType )
+// Return the id and type of a job currently running.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CurrentJob( TInt& aId, TSmlUsageType& aType )
+    {
+    if ( iCurrentJob )
+        {
+        aId = iCurrentJob->JobId();
+        aType = iCurrentJob->UsageType();       
+        }
+    else    // No job running.
+        {
+        aId = KNSmlNullId;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::QueuedJobsL( RArray<TInt>& aArray, const TSmlUsageType aType )
+// Returns an array of ids of queued jobs of seleted type.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::QueuedJobsL( RArray<TInt>& aArray, const TSmlUsageType aType )
+    {
+    // Start from current job. If the usage type matches, append id to the array.
+    if ( iCurrentJob )
+        {
+        CNSmlJob* job = iCurrentJob;
+
+        if ( job->UsageType() == aType )
+            {
+            aArray.AppendL( job->JobId() );    
+            }
+        while ( job->iNext )
+            {
+            job = job->iNext;
+            if ( job->UsageType() == aType )
+                {
+                aArray.AppendL( job->JobId() );    
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::AddProgressMsgL( const RMessage2& aMessage )
+// Adds progress message to the message array.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::AddProgressMsgL( const RMessage2& aMessage )
+    {
+    iProgressMsgs.AppendL( aMessage );
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::AddProgressMsgL( const RMessage2& aMessage )
+// Adds progress message to the message array.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::AddContactSuiteProgressMsgL( const RMessage2& aMessage )
+    {
+        iContactSuiteProgressMsgs.AppendL( aMessage );
+    }
+
+
+// --------------------------------------------------------------------------
+// TBool CNSmlSOSHandler::CompleteBufProgressMsg( const TDesC8& aBuf, 
+// const CNSmlSOSSession* aSession )
+// Write data to the progress message and completes it.
+// --------------------------------------------------------------------------
+//
+TBool CNSmlSOSHandler::CompleteBufProgressMsg( 
+const TDesC8& aBuf, 
+const CNSmlSOSSession* aSession  )
+    {
+    _DBG_FILE("CNSmlSOSHandler::CompleteBufProgressMsg : Begin");
+    TBool request( EFalse );    
+        
+    // Session info is stored to job and compared to session of the message.
+    for( TInt i(0); i < iProgressMsgs.Count(); i++ )
+        {
+        if ( aSession == iProgressMsgs[i].Session() )
+            {     
+            _DBG_FILE("Owner session of job found. Progress completed.");    
+            request = ETrue;
+                        
+            iProgressMsgs[i].Write( 0, aBuf, 0 );
+            iProgressMsgs[i].Complete( KErrNone );
+            iProgressMsgs.Remove(i);        
+            }
+        }    
+    _DBG_FILE("CNSmlSOSHandler::CompleteBufProgressMsg : End");    
+    return request;     
+    }
+
+// --------------------------------------------------------------------------
+// TBool CNSmlSOSHandler::CompleteBufProgressMsg( const TDesC8& aBuf, 
+// const CNSmlSOSSession* aSession )
+// Write data to the progress message and completes it.
+// --------------------------------------------------------------------------
+//
+TBool CNSmlSOSHandler::CompleteBufContactSuiteProgressMsg( 
+const TDesC8& aBuf, 
+const CNSmlSOSSession* aSession  )
+    {
+    _DBG_FILE("CNSmlSOSHandler::CompleteBufProgressMsg : Begin");
+    TBool request( EFalse );    
+        
+	    // Session info is stored to job and compared to session of the message.
+    for( TInt i(0); i < iContactSuiteProgressMsgs.Count(); i++ )
+        {
+            request = ETrue;
+
+		    if(!iContactSuiteProgressMsgs[i].IsNull())
+                {
+                iContactSuiteProgressMsgs[i].Write( 0, aBuf, 0 );
+                iContactSuiteProgressMsgs[i].Complete( KErrNone );
+                }
+            iContactSuiteProgressMsgs.Remove(i);
+        }    
+
+    _DBG_FILE("CNSmlSOSHandler::CompleteBufProgressMsg : End");    
+    return request;     
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CancelContactSuiteProgressMsg( const CNSmlSOSSession* aSession )
+// Completes cancelled progress message and removes it from array.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CancelContactSuiteProgressMsg( const CNSmlSOSSession* aSession )
+    {
+    for ( TInt i(0) ; i < iContactSuiteProgressMsgs.Count() ; i++ )
+        {
+        //if ( iContactSuiteProgressMsgs[i].Session() == aSession )
+            {
+            iContactSuiteProgressMsgs[i].Complete( KErrCancel );
+            iContactSuiteProgressMsgs.Remove(i);
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CancelProgressMsg( const CNSmlSOSSession* aSession )
+// Completes cancelled progress message and removes it from array.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CancelProgressMsg( const CNSmlSOSSession* aSession )
+    {
+    for ( TInt i(0) ; i < iProgressMsgs.Count() ; i++ )
+        {
+        if ( iProgressMsgs[i].Session() == aSession )
+            {
+            iProgressMsgs[i].Complete( KErrCancel );
+            iProgressMsgs.Remove(i);
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::AddEventMsgL( const RMessage2& aMessagePtr )
+// Adds event message to the message array.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::AddEventMsgL( const RMessage2& aMessagePtr )
+    {
+    iEventMsgs.AppendL( aMessagePtr );
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CompleteEventMsgL( MSyncMLEventObserver::TEvent aEvent, TInt aId, TInt aError, TInt aAdditional )
+// Writes data to all event messages and completes them.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CompleteEventMsgL( MSyncMLEventObserver::TEvent aEvent, TInt aId, TInt aError, TInt aAdditional )
+    {
+    if ( iEventMsgs.Count() )
+        {
+        HBufC8* buf = HBufC8::NewLC(( (2*KSizeofTInt8) + (3*KSizeofTInt32) ));
+        TPtr8 bufPtr = buf->Des();
+
+        RDesWriteStream stream;
+        stream.Open(bufPtr);
+        CleanupClosePushL(stream);
+
+        stream.WriteInt8L( (TInt8) ENSmlTypeEvent );
+        stream.WriteInt8L( (TInt8) aEvent );
+        stream.WriteInt32L( aId );
+        stream.WriteInt32L( aError );
+        stream.WriteInt32L( aAdditional );
+        stream.CommitL();
+
+        while ( iEventMsgs.Count() > 0 )
+            {
+            if(!iEventMsgs[0].IsNull()&& iEventMsgs[0].Handle())
+                {
+                iEventMsgs[0].Write( 0, bufPtr, 0 );
+                iEventMsgs[0].Complete( KErrNone );
+                }
+            iEventMsgs.Remove(0);
+            }
+        CleanupStack::PopAndDestroy(&stream); 
+        CleanupStack::PopAndDestroy(buf);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CancelEventMsg( TInt aHandle )
+// Completes cancelled event message and removes it from array.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CancelEventMsg( TInt aHandle )
+    {
+    for ( TInt i(0) ; i < iEventMsgs.Count() ; i++ )
+        {
+        if ( iEventMsgs[i].Handle() == aHandle )
+            {
+            iEventMsgs[i].Complete( KErrCancel );
+            iEventMsgs.Remove(i);
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::ServerAlertL( TDesC8& aData, TSmlUsageType aType, TSmlProtocolVersion aVersion )
+// Add server alert message to message queue.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::ServerAlertL( TDesC8& aData, TSmlUsageType aType, TSmlProtocolVersion aVersion, TInt aBearerType )
+    {
+    iMsgQueue->AddMessageL( aData, aType, aVersion, aBearerType );
+    }
+
+
+// FOTA
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::GenericAlertL( HBufC8* aMgmtUri, HBufC8* aMetaType, HBufC8* aMetaFormat, TInt aFinalResult, HBufC8* aCorrelator )
+// Adds Generic Alert to DM Agent if it is currently running.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::GenericAlertL( HBufC8* aMgmtUri, HBufC8* aMetaType, HBufC8* aMetaFormat, TInt aFinalResult, HBufC8* aCorrelator )
+	{
+	if ( !iParams || !iParams->iThreadEngine )
+		{
+		User::Leave( KErrNotFound );
+		}
+	
+	iParams->iThreadEngine->DMAgentL()->SetGenericAlertL( *aMgmtUri, *aMetaType, *aMetaFormat, aFinalResult, *aCorrelator );
+	}
+
+// FOTA end
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::GenericAlertL( HBufC8* aMgmtUri, HBufC8* aMetaType, HBufC8* aMetaFormat, HBufC8* aCorrelator, HBufC8* aTargetUri, HBufC8* aMark, HBufC8* aData )
+// Adds Generic Alert to DM Agent if it is currently running.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::GenericAlertL( HBufC8* aCorrelator, RArray<CNSmlDMAlertItem>* aItem )
+	{
+	if ( !iParams || !iParams->iThreadEngine )
+		{
+		User::Leave( KErrNotFound );
+		}
+	
+	iParams->iThreadEngine->DMAgentL()->SetGenericAlertL( *aCorrelator, *aItem );
+	}
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::IncreaseSessionCount()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::IncreaseSessionCount()
+    {
+    iSessionCount++;
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::DecreaseSessionCount()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::DecreaseSessionCount()
+    {
+    iSessionCount--;
+    if ( !iSessionCount && !iCurrentJob && iMsgQueue->IsEmpty() ) 
+        {
+        CActiveScheduler::Stop();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::ServerSuspendedL( const TBool aSuspended )
+// Sets suspended state. 
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::ServerSuspendedL( const TBool aSuspended )
+    {
+    
+    if ( iSuspended != aSuspended )
+        {
+        CompleteEventMsgL( MSyncMLEventObserver::EServerSuspended, 0, 0, aSuspended );         
+        }
+        
+    iSuspended = aSuspended; 
+
+    iMsgQueue->ServerSuspended( iSuspended ); // Send suspend state to message queue.
+
+    if ( iSuspended )
+        {
+        // Cancel job if running.
+        if ( iCurrentJob )
+            {
+            if ( iCurrentJob->UsageType() == ESmlDataSync )
+                {
+                CancelDSSync();    
+                }
+            else // ESmlDevMan
+                {
+                CancelDMSync();
+                }
+            }
+        }
+    else
+        {
+        // Start job if queued.
+        if ( iCurrentJob && iCurrentJob->JobRunning() == EFalse )
+            {
+            if ( iCurrentJob->UsageType() == ESmlDataSync )
+                {
+                StartDSSyncL();    
+                }
+            else // ESmlDevMan
+                {
+                StartDMSyncL();
+                }
+            }
+        // If there are no sessions or jobs and message queue is empty
+        // then server can be stopped.
+        if ( !iSessionCount && !iCurrentJob && iMsgQueue->IsEmpty() )
+            {
+            CActiveScheduler::Stop();
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// TBool CNSmlSOSHandler::IsSuspended()
+// --------------------------------------------------------------------------
+//
+TBool CNSmlSOSHandler::IsSuspended()
+    {
+    return iSuspended;
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::StartDSSyncL()
+// Starts DS sync job.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::StartDSSyncL()
+    {
+    _DBG_FILE("CNSmlSOSHandler::StartDSSyncL(): begin");
+	static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+   	static _LIT_SECURITY_POLICY_C1(KAllowWriteDeviceDataPolicy, ECapabilityWriteDeviceData);
+    TInt sessiontype=1;
+    TInt r=RProperty::Define(KPSUidNSmlSOSServerKey,KNSmlSyncJobOngoing,RProperty::EInt,KAllowAllPolicy,KAllowWriteDeviceDataPolicy);
+	if ( r != KErrNone && r != KErrAlreadyExists )
+    	{
+    	User::LeaveIfError(r);
+    	}
+    //sessiontype=1 for DS session 	              
+    TInt r2=RProperty::Set(KPSUidNSmlSOSServerKey,KNSmlSyncJobOngoing,sessiontype);
+    DBG_FILE_CODE( sessiontype, _S8("P&S key set to 1 for ds session") );    
+    //Set job as running from now on
+    iCurrentJob->SetJobRunning( ETrue );
+    
+    // client or server iniated sync
+	TNSmlSyncInitiation syncInit = EClientInitiated;
+	
+    // Get non-overrided data from settings.
+    CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+    CNSmlDSProfile* prof = settings->ProfileL( iCurrentJob->ProfileId() );
+    if ( !prof )    // profile not found, delete job.
+        {
+        CleanupStack::PopAndDestroy(settings);
+        FinishCurrentJobL();      
+	    _DBG_FILE("CNSmlSOSHandler::StartDSSyncL(): profile not found!");
+        return;
+        }
+
+    CleanupStack::PushL(prof);    
+	
+	if ( iCurrentJob->iPending || prof->IntValue( EDSProfileHidden ) )
+		{
+		syncInit = EServerAlerted;	
+		}
+		
+    iParams = new (ELeave) CNSmlThreadParams( *iCurrentJob, this );
+	iParams->iCSArray = new(ELeave) CArrayFixFlat<TNSmlContentSpecificSyncType>(1);
+	iParams->iSyncInit = syncInit;
+		
+	TNSmlContentSpecificSyncType css;
+    // Tasks and sync type are overrided in a same struct -> must be handled together.
+   
+    RArray<TInt> tasks;
+    iCurrentJob->TaskIds( tasks );
+    CleanupClosePushL(tasks);
+	if (iCurrentJob->iCtInfo)
+		{
+		for (TInt i = 0; i < iCurrentJob->iCtInfo->Count(); i++)
+        	{
+            css.iType = ConvertSyncTypes( iCurrentJob->iCtInfo->At(i).iSyncType );   
+        	css.iTaskId = iCurrentJob->iCtInfo->At(i).iTaskId;
+        	iParams->iCSArray->AppendL(css);
+        	}
+        	
+		}
+	else
+    if ( tasks.Count() || ( iCurrentJob->SyncType() >= ESmlTwoWay &&
+                           iCurrentJob->SyncType() <= ESmlRefreshFromClient ) )
+        {
+        
+        TSmlSyncType sType;
+    
+        // If tasks are not overrided, get tasks from db.
+        if ( !tasks.Count() )
+            {
+            ReadTasksFromDBL( tasks );
+            }
+
+        for ( TInt i(0) ; i < tasks.Count() ; i++ )
+            {            
+            if ( iCurrentJob->SyncType() >= ESmlTwoWay &&
+                 iCurrentJob->SyncType() <= ESmlRefreshFromClient )
+                {
+                sType = iCurrentJob->SyncType();
+                }
+            else    // If sync type is not overridden, get sync type from db.
+                {
+                sType = ReadSyncTypeForTaskL( tasks[i] );
+                }
+                
+            // Convert sync types to match CNSmlDbCaps sync types.
+            css.iType = ConvertSyncTypes( sType );
+            css.iTaskId = tasks[i];
+            iParams->iCSArray->AppendL(css);
+            }
+        }
+       
+	iStatus = KRequestPending;
+	        		
+	iThreadObserver = new (ELeave) CNSmlThreadObserver( iStatus );
+	
+	//Start observing DM session thread.
+	TInt error = TNSmlThreadLauncher::RunJobSession( *iParams, *iThreadObserver );
+	if (  error != KErrNone )
+		{
+		HandleEventMsg( MSyncMLEventObserver::EJobStartFailed, error );	
+		return;
+		}
+	
+	HandleEventMsg( MSyncMLEventObserver::EJobStart );    
+
+    CleanupStack::PopAndDestroy(&tasks);
+    
+    CleanupStack::PopAndDestroy(prof);
+    CleanupStack::PopAndDestroy(settings);
+
+    if ( !IsActive() )
+        {
+        SetActive(); // Set object active to start listening RequestComplete() in RunL.
+        }
+    
+    _DBG_FILE("CNSmlSOSHandler::StartDSSyncL(): end");
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlDbCaps::ENSmlSyncTypes CNSmlSOSHandler::ConvertSyncTypes(TSmlSyncType aSyncType)
+// --------------------------------------------------------------------------
+//
+CNSmlDbCaps::ENSmlSyncTypes CNSmlSOSHandler::ConvertSyncTypes(TSmlSyncType aSyncType)
+	{
+	CNSmlDbCaps::ENSmlSyncTypes syncType;
+	
+	switch ( aSyncType )
+        {
+        case ESmlTwoWay:
+            syncType = CNSmlDbCaps::ETwoWaySync;
+            break;
+        case ESmlOneWayFromServer:
+            syncType = CNSmlDbCaps::EOneWaySyncFromServer;
+            break;
+        case ESmlOneWayFromClient:
+            syncType = CNSmlDbCaps::EOneWaySyncFromClient;
+            break;
+        case ESmlSlowSync:
+            syncType = CNSmlDbCaps::ESlowTwoWaySync;
+            break;
+        case ESmlRefreshFromServer:
+            syncType = CNSmlDbCaps::ERefreshSyncFromServer;
+            break;
+        case ESmlRefreshFromClient: 
+            syncType = CNSmlDbCaps::ERefreshSyncFromClient;
+            break;
+        default:
+            syncType = CNSmlDbCaps::ETwoWaySync;
+            break;
+ 		}
+ 	return syncType;
+	}
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CancelDSSync()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CancelDSSync()
+    {
+    _DBG_FILE("CNSmlSOSHandler::CancelDSSync(): begin");
+   
+    if (( iParams) && (iParams->iThreadEngine ))
+    	{
+    	iParams->iThreadEngine->CancelJob();	
+    	}
+       
+    _DBG_FILE("CNSmlSOSHandler::CancelDSSync(): end");
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::StartDMSyncL()
+// Starts DM configuration job.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::StartDMSyncL()
+    {
+    _DBG_FILE("CNSmlSOSHandler::StartDMSyncL(): begin");
+	static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+   	static _LIT_SECURITY_POLICY_C1(KAllowWriteDeviceDataPolicy, ECapabilityWriteDeviceData);
+    TInt sessiontype = 2;
+    TInt r=RProperty::Define(KPSUidNSmlSOSServerKey,KNSmlSyncJobOngoing,RProperty::EInt,KAllowAllPolicy,KAllowWriteDeviceDataPolicy);
+	if ( r != KErrNone && r != KErrAlreadyExists )
+    	{
+    	User::LeaveIfError(r);
+        }
+    //sessiontype=2 for dm session                  
+    TInt r2=RProperty::Set(KPSUidNSmlSOSServerKey,KNSmlSyncJobOngoing,sessiontype);
+    DBG_FILE_CODE( sessiontype, _S8("P&S key set to 2 for dm session") );    
+    //Set job as running from now on
+    iCurrentJob->SetJobRunning( ETrue );
+
+	TNSmlSyncInitiation syncInit = EClientInitiated;
+    CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+    CNSmlDMProfile* prof = settings->ProfileL( iCurrentJob->ProfileId() );
+    if(prof)
+        {
+        CleanupStack::PushL( prof );
+	    }
+    
+    if ( iCurrentJob->iPending || prof->IntValue( EDMProfileHidden ))
+        {
+        syncInit = EServerAlerted;
+        }
+
+    if ( !iCurrentJob->TransportId() )
+        {
+        if ( prof )
+            {
+            iCurrentJob->SetTransportId( prof->IntValue( EDMProfileTransportId ) );
+            }
+        }
+    if(prof)
+        {
+        CleanupStack::PopAndDestroy( prof );
+        }
+    CleanupStack::PopAndDestroy( settings );
+ 
+
+    switch ( iCurrentJob->JobType() )
+        {
+        case EDMJobProfile:
+        case EDMJobTransport:
+        	    {        		                		
+        		iStatus = KRequestPending;
+        		iParams = new (ELeave) CNSmlThreadParams( *iCurrentJob, this );
+        		iParams->iSyncInit = syncInit; 
+        		        		
+        		iThreadObserver = new (ELeave) CNSmlThreadObserver( iStatus );
+        		
+        		//Start observing DM session thread.
+        		TInt error = TNSmlThreadLauncher::RunJobSession( *iParams, *iThreadObserver );
+   		    	if (  error != KErrNone )
+   		    		{
+   		    		HandleEventMsg( MSyncMLEventObserver::EJobStartFailed, error );   		    		
+   		    		return;
+   		    		}
+        	    }
+            break;
+        default:
+            HandleEventMsg( MSyncMLEventObserver::EJobStartFailed );
+            break;
+        }
+    HandleEventMsg( MSyncMLEventObserver::EJobStart, iCurrentJob->JobId() );
+
+ 	if ( !IsActive() )
+        {
+        SetActive(); // Set object active to start listening RequestComplete() in RunL.
+        }   
+
+    _DBG_FILE("CNSmlSOSHandler::StartDMSyncL(): end");
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CancelDMSync()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CancelDMSync()
+    {
+    _DBG_FILE("CNSmlSOSHandler::CancelDMSync(): begin");
+    
+    if (( iParams) && (iParams->iThreadEngine ))
+    	{
+    	iParams->iThreadEngine->CancelJob();	
+    	}
+        
+    _DBG_FILE("CNSmlSOSHandler::CancelDMSync(): end");
+    }
+
+// --------------------------------------------------------------------------
+// TBool CNSmlSOSHandler::SearchSimilarJobs( const CNSmlJob* aJob )
+// Searches queued job if created job already exists.
+// --------------------------------------------------------------------------
+//
+TBool CNSmlSOSHandler::SearchSimilarJobs( const CNSmlJob* aJob )
+    {
+    // Goes through all the jobs and returns ETrue if similar exists.
+    CNSmlJob* tempJob = iCurrentJob;
+        
+    while ( tempJob->iNext )
+       {
+       RArray<TInt> tempTasks;
+       tempJob->TaskIds( tempTasks );
+       
+       RArray<TInt> tasks;
+       aJob->TaskIds( tasks );
+       
+       TInt match(0);
+       if ( tempJob->ProfileId()       == aJob->ProfileId()       &&
+            tempTasks.Count()          == tasks.Count()           &&
+            tempJob->SyncType()        == aJob->SyncType()        &&
+            tempJob->TransportId()     == aJob->TransportId() )
+            {
+            // Also check if all the task ids match if there are any.
+            if( !tasks.Count() )
+                {
+                tempTasks.Close();
+                tasks.Close();
+                return ETrue;
+                }
+            for( TInt i(0); i < tasks.Count(); i++ )
+                {    
+                if( tasks.operator[](i) == tempTasks.operator[](i) )
+                    {
+                    match++;   
+                    }
+                if ( match == tasks.Count() )
+                    {
+                    tempTasks.Close();
+                    tasks.Close();
+                    return ETrue;
+                    }
+                }
+            }
+            
+	   tempTasks.Close();
+       tasks.Close();
+       
+       tempJob = tempJob->iNext;
+       }
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::ReadTasksFromDBL( RArray<TInt>& aArray )
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::ReadTasksFromDBL( RArray<TInt>& aArray )
+    {
+    // Get non-overrided data from settings.
+    CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+    CNSmlDSProfile* prof = settings->ProfileL( iCurrentJob->ProfileId() );
+
+    if ( prof )
+        {        
+        CleanupStack::PushL(prof);
+        RImplInfoPtrArray implArray;
+        CleanupStack::PushL(PtrArrCleanupItemRArr( CImplementationInformation, &implArray ) );    
+        TUid ifUid = { KNSmlDSInterfaceUid };
+        REComSession::ListImplementationsL( ifUid, implArray );
+
+        for ( TInt i = 0 ; i < implArray.Count() ; i++ )
+            {    
+            CImplementationInformation* implInfo = implArray[i];
+            CNSmlDSContentType* ctype = prof->ContentType( implInfo->ImplementationUid().iUid );
+            if ( ctype )
+                {            
+                aArray.AppendL( ctype->IntValue( EDSAdapterTableId ) );
+                }
+            }        
+        CleanupStack::PopAndDestroy(&implArray); 
+        CleanupStack::PopAndDestroy(prof);
+        REComSession::FinalClose();        
+        }    
+    CleanupStack::PopAndDestroy(settings);
+    }
+
+// --------------------------------------------------------------------------
+// TSmlSyncType CNSmlSOSHandler::ReadSyncTypeForTaskL( const TInt aTaskId )
+// --------------------------------------------------------------------------
+//
+TSmlSyncType CNSmlSOSHandler::ReadSyncTypeForTaskL( const TInt aTaskId )
+    {
+    CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+    TSmlSyncType syncType( ESmlTwoWay );
+    CNSmlDSProfile* prof = settings->ProfileL( iCurrentJob->ProfileId() );
+    if ( prof )
+        {
+        CNSmlDSContentType* ctype = prof->ContentTypeId( aTaskId ); 
+        // content type is deleted in CNSmlDSProfile destructor.
+        syncType = (TSmlSyncType) ctype->IntValue( EDSAdapterSyncType );
+            
+        delete prof;
+        prof = NULL;
+        }
+    CleanupStack::PopAndDestroy(settings);
+    return syncType;
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::FinishCurrentJobL()
+// Removes finished job from queue and starts next from queue if one exists.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::FinishCurrentJobL()
+    {
+    _DBG_FILE("CNSmlSOSHandler::FinishCurrentJobL(): begin");
+        
+	if ( iParams )
+    	{
+       	delete iParams;
+       	iParams = NULL;	
+       	}
+       	
+     if (iThreadObserver)
+    	{
+    	delete iThreadObserver;
+    	iThreadObserver = NULL;        	
+    	}
+     
+    if ( iCurrentJob->iNext ) // If there is a job waiting, remove current and start next.  
+        {
+        CNSmlJob* nextJob = iCurrentJob->iNext;
+        delete iCurrentJob;
+        iCurrentJob = nextJob;
+
+        if ( iCurrentJob->UsageType() == ESmlDataSync )
+            {
+            StartDSSyncL();
+            }
+        else
+            {
+            StartDMSyncL();
+            }
+        }
+    else // No jobs at queue.
+        {
+        delete iCurrentJob;
+        iCurrentJob = NULL;
+        // if no clients connected and no jobs queued -> stop the server.
+        if ( !iSessionCount && iMsgQueue->IsEmpty() )
+            {
+            _DBG_FILE("CNSmlSOSHandler::FinishCurrentJobL(): CActiveScheduler::Stop()");
+            CActiveScheduler::Stop();   
+            }
+        }    
+     _DBG_FILE("CNSmlSOSHandler::FinishCurrentJobL(): end");
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::DoCancel()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::DoCancel()
+    {
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::RunL()
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::RunL()
+    {
+    _DBG_FILE("CNSmlSOSHandler::RunL() : Begin");
+    
+    HandleEventMsg( MSyncMLEventObserver::EJobStop, iStatus.Int() );        
+    // Remove current job and start next if one exists.  
+    TRAP_IGNORE( FinishCurrentJobL() );       
+    
+    _DBG_FILE("CNSmlSOSHandler::RunL() : End");
+    }
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::CreateJobL( CNSmlAlertJobInfo& aJobInfo )
+// Creates server alerted job got from message queue.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::CreateJobL( CNSmlAlertJobInfo& aJobInfo )
+    {
+    CNSmlJob* job = new (ELeave) CNSmlJob;
+    CleanupStack::PushL(job);
+    job->SetProfId( aJobInfo.iProfileId );
+    job->SetTransportId( aJobInfo.iTransportId );
+    job->SetUsageType( aJobInfo.iType );
+    job->iUimode = aJobInfo.iUimode;   
+    if ( aJobInfo.iType == ESmlDataSync )
+        {        
+        if ( aJobInfo.iPackage.Length() )
+            {
+            job->iPackage = aJobInfo.iPackage.AllocL();
+            job->iSessionId = aJobInfo.iSessionId;
+            }
+            
+        job->iCtInfo = new (ELeave) CArrayFixFlat<TNSmlContentTypeInfo>(1);
+
+        for ( TInt i=0 ; i < aJobInfo.iContentType->Count() ; i++ )
+            {
+            job->AddTaskIdL( aJobInfo.iContentType->At(i).iTaskId);
+            job->iCtInfo->AppendL( aJobInfo.iContentType->At(i) );
+            }
+
+        job->SetJobType( EDSJobTaskTransST );
+        
+        CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+        CNSmlDSProfile* prof = settings->ProfileL( aJobInfo.iProfileId );
+        if ( prof )
+            {
+            if ( !prof->IntValue( EDSProfileHidden ) )
+                {
+                job->iPending = ETrue; // Notifier is not called if profile is hidden.
+                }
+            delete prof;
+            prof = NULL;
+            }
+        CleanupStack::PopAndDestroy(settings);
+        }
+    else  // ESmlDevMan
+        {
+        job->SetJobType( EDMJobTransport );
+        CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+        CNSmlDMProfile* prof = settings->ProfileL( aJobInfo.iProfileId );
+        if ( prof )
+            {
+            if ( !prof->IntValue( EDMProfileHidden ) )
+                {
+                job->iPending = ETrue; // Notifier is not called if profile is hidden.
+                }
+            delete prof;
+            prof = NULL;
+            }
+        CleanupStack::PopAndDestroy(settings);
+        }        
+
+    TInt jobId(0);
+    // Add created job to the queue.
+    AddJobL( job, jobId );
+    CleanupStack::Pop(job);
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler::DoDisconnectL()
+// Disconnects local connection.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::DoDisconnectL()
+	{
+	CNSmlTransport* transport = CNSmlTransport::NewLC();
+		
+	TRequestStatus status;
+	TDesC8 temp = KNullDesC8();
+	
+	HBufC8* mimeType = KNSmlDSAgentMIMEType().AllocLC();	
+	transport->ConnectL( KUidNSmlMediumTypeUSB, ETrue, NULL, temp, *mimeType , status, temp, temp, 0 ); 
+	User::WaitForRequest(status);
+		
+	if (status.Int() == KErrNone)
+		{
+		transport->Disconnect();
+		}
+	CleanupStack::PopAndDestroy( mimeType );
+	CleanupStack::PopAndDestroy( transport );
+	}
+	
+// --------------------------------------------------------------------------
+// Progress observer
+// void CNSmlSOSHandler::OnSyncMLSyncError( TErrorLevel aErrorLevel, TInt aError, TInt aTaskId, TInt aInfo1, TInt aInfo2 )
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::OnSyncMLSyncError( TErrorLevel aErrorLevel, TInt aError, TInt aTaskId, TInt aInfo1, TInt aInfo2 )
+    {
+    // do not try to buffer, if there is not active session
+    if ( iCurrentJob->OwnerSession() != NULL )
+        {
+        TNSmlProgressEvent event;
+        event.iEventType = ENSmlSyncError;        
+        event.iErrorLevel = aErrorLevel;   
+        event.iInfo1 = aError;
+        event.iInfo2 = aTaskId;   
+        event.iInfo3 = aInfo1;
+        event.iInfo4 = aInfo2;
+
+        iCurrentJob->OwnerSessionNonConst()->StoreToProgessEventBuffer( event );            
+        }      
+    }
+
+// --------------------------------------------------------------------------
+// HBufC8* CNSmlSOSHandler::WriteSyncErrorL( TErrorLevel aErrorLevel, TInt aError, TInt aTaskId, TInt aInfo1, TInt aInfo2 )
+// --------------------------------------------------------------------------
+//
+HBufC8* CNSmlSOSHandler::WriteSyncErrorL( TErrorLevel aErrorLevel, TInt aError, TInt aTaskId, TInt aInfo1, TInt aInfo2 )
+	{
+    HBufC8* buf = HBufC8::NewLC( ( 3*KSizeofTInt8 + ( 4*KSizeofTInt32 ) ) );
+    TPtr8 bufPtr = buf->Des();
+
+    RDesWriteStream stream;
+    stream.Open( bufPtr );
+    CleanupClosePushL( stream );
+
+    stream.WriteInt8L( (TInt8) ENSmlTypeProgressEvent );
+    stream.WriteInt8L( (TInt8) ENSmlSyncError );
+    stream.WriteInt8L( (TInt8) aErrorLevel );
+
+    stream.WriteInt32L( aError );
+    stream.WriteInt32L( aTaskId );
+    stream.WriteInt32L( aInfo1 );
+    stream.WriteInt32L( aInfo2 );
+    stream.CommitL();
+    
+    CleanupStack::PopAndDestroy( &stream ); 
+    CleanupStack::Pop( buf );
+   	
+   	return buf;
+	}
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::OnSyncMLSyncProgress( MSyncMLProgressObserver::TStatus aStatus, TInt aInfo1, TInt aInfo2 )
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::OnSyncMLSyncProgress( MSyncMLProgressObserver::TStatus aStatus, TInt aInfo1, TInt aInfo2 )
+    {
+    // do not try to buffer, if there is not active session
+    if ( iCurrentJob->OwnerSession() != NULL )
+        {
+        TNSmlProgressEvent event;
+        event.iEventType = ENSmlSyncProgress;
+        event.iProgressStatus = aStatus;    
+        event.iInfo1 = aInfo1;
+        event.iInfo2 = aInfo2;   
+        event.iInfo3 = 0;
+        event.iInfo4 = 0;
+    
+        iCurrentJob->OwnerSessionNonConst()->StoreToProgessEventBuffer( event );
+        }                	
+    }
+
+// --------------------------------------------------------------------------
+// HBufC8* CNSmlSOSHandler::WriteSyncProgressL( TStatus aStatus, TInt aInfo1, TInt aInfo2 )
+// --------------------------------------------------------------------------
+//
+HBufC8* CNSmlSOSHandler::WriteSyncProgressL( TStatus aStatus, TInt aInfo1, TInt aInfo2 )
+	{
+	HBufC8* buf = HBufC8::NewLC( (3*KSizeofTInt8 + (2*KSizeofTInt32) ));
+    TPtr8 bufPtr = buf->Des();
+
+    RDesWriteStream stream;
+    stream.Open( bufPtr );
+    CleanupClosePushL( stream );
+
+    stream.WriteInt8L( (TInt8) ENSmlTypeProgressEvent );
+    stream.WriteInt8L( (TInt8) ENSmlSyncProgress );
+    stream.WriteInt8L( (TInt8) aStatus );
+
+    stream.WriteInt32L( aInfo1 );
+    stream.WriteInt32L( aInfo2 );
+    stream.CommitL(); 
+    
+    CleanupStack::PopAndDestroy( &stream );
+    CleanupStack::Pop( buf );
+    
+    return buf;
+	}
+
+// --------------------------------------------------------------------------
+// void CNSmlSOSHandler::OnSyncMLDataSyncModifications( TInt aTaskId, const TSyncMLDataSyncModifications& aClientMods, const TSyncMLDataSyncModifications& aServerMods )
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::OnSyncMLDataSyncModifications( TInt aTaskId, const TSyncMLDataSyncModifications& aClientMods,
+                                                                   const TSyncMLDataSyncModifications& aServerMods )
+    {
+    
+    // do not try to buffer, if there is not active session
+    if ( iCurrentJob->OwnerSession() != NULL )
+        {
+        TNSmlProgressEvent event;
+        event.iEventType = ENSmlModifications;
+        event.iClientMods = aClientMods;
+        event.iServerMods = aServerMods;
+        event.iInfo1 = aTaskId;
+        event.iInfo2 = 0;   
+        event.iInfo3 = 0;
+        event.iInfo4 = 0;
+    
+        iCurrentJob->OwnerSessionNonConst()->StoreToProgessEventBuffer( event );            
+        }
+    }
+
+// --------------------------------------------------------------------------
+// HBufC8* CNSmlSOSHandler::WriteSyncModificationsL( TInt aTaskId, const TSyncMLDataSyncModifications& aClientMods, const TSyncMLDataSyncModifications& aServerMods )
+// --------------------------------------------------------------------------
+//
+HBufC8* CNSmlSOSHandler::WriteSyncModificationsL( TInt aTaskId, const TSyncMLDataSyncModifications& aClientMods,
+                                                                const TSyncMLDataSyncModifications& aServerMods )
+	{
+	HBufC8* buf = HBufC8::NewLC( (2*KSizeofTInt8 + (11*KSizeofTInt32) ));
+    TPtr8 bufPtr = buf->Des();
+
+    RDesWriteStream stream;
+    stream.Open(bufPtr);
+    CleanupClosePushL(stream);
+
+    stream.WriteInt8L( (TInt8) ENSmlTypeProgressEvent );
+    stream.WriteInt8L( (TInt8) ENSmlModifications );
+
+    stream.WriteInt32L( aTaskId );
+
+    stream.WriteInt32L( aClientMods.iNumAdded );
+    stream.WriteInt32L( aClientMods.iNumReplaced );
+    stream.WriteInt32L( aClientMods.iNumMoved );
+    stream.WriteInt32L( aClientMods.iNumDeleted );
+    stream.WriteInt32L( aClientMods.iNumFailed );
+
+    stream.WriteInt32L( aServerMods.iNumAdded );
+    stream.WriteInt32L( aServerMods.iNumReplaced );
+    stream.WriteInt32L( aServerMods.iNumMoved );
+    stream.WriteInt32L( aServerMods.iNumDeleted );
+    stream.WriteInt32L( aServerMods.iNumFailed );
+    stream.CommitL();
+    
+    CleanupStack::PopAndDestroy( &stream ); 
+    CleanupStack::Pop( buf );
+    
+    return buf;
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler::HandleEventMsg( MSyncMLEventObserver::TEvent aEvent, 
+// TInt aStatus )
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::HandleEventMsg( 
+    MSyncMLEventObserver::TEvent aEvent,
+    TInt aStatus )
+    {
+    _DBG_FILE("CNSmlSOSHandler::HandleEventMsg : Begin");
+    TBool found( EFalse );
+    
+    for (TInt i(0); i < iEventMsgs.Count(); i++ )    
+        {
+        if ( iEventMsgs[i].Session() == iCurrentJob->OwnerSession() )
+            {
+            found = ETrue;
+            }             
+        } 
+    
+    if ( !found && !iCurrentJob->iSilentJob)
+        {                              
+        if ( iCurrentJob->OwnerSession() )
+            {
+            _DBG_FILE("HandleEventMsg : Event buffered");
+            iCurrentJob->OwnerSessionNonConst()->StoreToEventBuffer( aEvent, iCurrentJob->JobId(), aStatus );            
+            }        
+        }
+    else
+        {        
+        _DBG_FILE("HandleEventMsg : Event completed");                      
+        TRAP_IGNORE( CompleteEventMsgL( aEvent, iCurrentJob->JobId(), aStatus ));        
+        }
+    _DBG_FILE("CNSmlSOSHandler::HandleEventMsg : End");                      
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler::ClearSessionFromJob( const CNSmlSOSSession* aSession )
+// Resets session from job.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::ClearSessionFromJob( const CNSmlSOSSession* aSession )
+    {
+        
+    CNSmlJob* tempJob = iCurrentJob;
+        
+    while ( tempJob )
+        {            
+        if (tempJob->OwnerSession() == aSession )        
+            {
+            tempJob->SetOwnerSession( NULL );    
+            }
+        tempJob = tempJob->iNext;
+        }    
+    }
+
+void CNSmlSOSHandler::RegisterContactSuiteObserversWithProfileId( TInt aProfileId )
+    {
+    iContactSuiteObserverProfileId = aProfileId;
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlSOSHandler::ClosePendingMessages( const CNSmlSOSSession* aSession )
+// Resets session from job.
+// --------------------------------------------------------------------------
+//
+void CNSmlSOSHandler::ClosePendingMessages( const CNSmlSOSSession* aSession )
+    {
+    TInt count = iProgressMsgs.Count();
+    TInt i (0);
+    while ( i < count )
+        {
+        if ( aSession == iProgressMsgs[i].Session() )
+            {     
+            _DBG_FILE("Close pending progress message");                                        
+            iProgressMsgs.Remove(i); 
+            count = iProgressMsgs.Count();       
+            }   
+        else
+            {
+            i++;
+            }             
+        }
+    
+	
+	count = iContactSuiteProgressMsgs.Count(); 
+    i = 0;
+    while ( i < count )
+        {
+                
+            _DBG_FILE("Close pending event message");                                        
+            iContactSuiteProgressMsgs.Remove(i); 
+            count = iContactSuiteProgressMsgs.Count();                                
+            i++;       
+        }
+
+
+    count = iEventMsgs.Count(); 
+    i = 0;
+    while ( i < count )
+        {
+        if ( aSession == iEventMsgs[i].Session() )
+            {     
+            _DBG_FILE("Close pending event message");                                        
+            iEventMsgs.Remove(i); 
+            count = iEventMsgs.Count();                       
+            } 
+         else
+            {
+            i++;
+            }    
+        }
+    }
+
+// End of file