syncmlfw/common/sosserver/src/nsmlsosthread.cpp
changeset 0 b497e44ab2fc
child 24 13d7c31c74e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/common/sosserver/src/nsmlsosthread.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1034 @@
+/*
+* 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 <e32math.h>
+#include <DevManInternalCRKeys.h>
+#include <centralrepository.h>
+#include <nsmldebug.h>
+
+#include "nsmlsosthread.h"
+#include <DataSyncInternalPSKeys.h>
+
+#include <PolicyEngineClient.h>
+#include <centralrepository.h>
+#include "PMUtilInternalCRKeys.h"
+#include <featmgr.h>
+// --------------------------------------------------------------------------
+// EXPORT_C TInt ThreadFunction( TAny* )
+// --------------------------------------------------------------------------
+//
+TInt ThreadFunction( TAny* aStarted )
+	{
+	#ifdef __CLIENT_API_MT_
+	 __UHEAP_MARK;
+	#endif
+	
+	CNSmlThreadParams* params = (CNSmlThreadParams*) aStarted;
+	
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	_DBG_FILE("CNSmlSOSServer : Session thread started");	
+	
+	CActiveScheduler* scheduler = new CActiveScheduler;
+	__ASSERT_ALWAYS( scheduler, User::Panic( KSOSServerThread, EMainSchedulerError ) );
+    	
+	CActiveScheduler::Install( scheduler );
+	
+	TInt endStatus(KErrNone);
+	CNSmlThreadEngine * threadEngine = 0;
+	
+	params->iCurrentJob.iSilentJob = EFalse;
+
+	TRAPD(err,
+		threadEngine = CNSmlThreadEngine::NewL( *params );
+	
+	if ( params->iSyncInit == EServerAlerted && params->iCurrentJob.iPending )
+		{
+		if ( threadEngine->SilentModeL( params ))
+			{
+			//in silent mode DM client UI is not opened
+			params->iCurrentJob.iPending = EFalse;
+		    params->iCurrentJob.iSilentJob = ETrue;
+			threadEngine->SaveSessionInfoL();
+			threadEngine->ForcedCertificateCheckL( ETrue );
+			threadEngine->StartJobSessionL();		
+			}
+		else
+			{
+			//if not a silent mode behave as in a normal DM session
+			threadEngine->ForcedCertificateCheckL( EFalse );
+			threadEngine->VerifyJobFromNotifierL();		
+			}
+		}
+	else
+		{
+		//when sync session is not alerted behave as in a normal DM session
+		threadEngine->ForcedCertificateCheckL( EFalse );
+		threadEngine->StartJobSessionL();		
+		}
+	);
+	
+	endStatus = err;
+    
+    if ( err != KErrNone )    
+ 		{
+		if ( params->iCurrentJob.TransportId() != KUidNSmlMediumTypeInternet.iUid )
+			{
+			// Disconnect if local connection
+			TRAP_IGNORE( params->iSOSHandler->DoDisconnectL() );		
+			}		
+		}	
+	
+	// start scheduler after succesfull initialization 
+	if ( threadEngine )
+	    {
+	    if ( threadEngine->IsActive() )
+	        {
+	        CActiveScheduler::Start();                
+	        }	    
+	    }	
+	
+	delete scheduler;
+	
+	if ( endStatus == KErrNone )
+		{
+		endStatus = threadEngine->FinishedStatus();	
+		}
+	
+	if ( threadEngine )	
+	    {
+	    delete threadEngine;        
+	    }
+	
+	_DBG_FILE("SosServer Job Thread ended");
+	delete cleanup;
+	
+	#ifdef __CLIENT_API_MT_
+	__UHEAP_MARKEND;
+	#endif
+	
+    return endStatus;
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::NewL( CNSmlThreadParams& aParams )
+// Two phase Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadEngine* CNSmlThreadEngine::NewL( CNSmlThreadParams& aParams )
+	{
+	CNSmlThreadEngine* self = new (ELeave) CNSmlThreadEngine( aParams );
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::ConstructL()
+// 2nd Constructor
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::ConstructL()
+	{
+		FeatureManager::InitializeLibL();
+	iThreadParams.iThreadEngine = this;
+	iContentArray = new(ELeave) CArrayFixFlat<TNSmlContentSpecificSyncType>(1);
+	
+	if ( iThreadParams.iCSArray )
+		{
+		for (TInt i = 0; i < iThreadParams.iCSArray->Count(); i++)
+			{
+			TNSmlContentSpecificSyncType type;
+			type.iTaskId = iThreadParams.iCSArray->At( i ).iTaskId;
+			type.iType = iThreadParams.iCSArray->At( i ).iType;
+			iContentArray->AppendL( type );
+			}
+		}		
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine( TNSmlThreadParams& aParams ) 
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadEngine::CNSmlThreadEngine( CNSmlThreadParams& aParams ) 
+: CActive(EPriorityLow), iThreadParams(aParams)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::~CNSmlThreadEngine()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadEngine::~CNSmlThreadEngine()
+	{
+	delete iContentArray;
+	delete iNotifierObserver;
+	Cancel();
+	RThread().Close();
+	delete iDSAgent;
+	delete iDMAgent;
+	delete iCancelTimeout;
+	FeatureManager::UnInitializeLib();
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::SilentModeL()
+// Check is current serverid mentioned to work in silent mode (TARM feature)
+// --------------------------------------------------------------------------
+//
+TBool CNSmlThreadEngine::SilentModeL( const CNSmlThreadParams* aParams )
+    {   
+    _DBG_FILE("CNSmlThreadEngine::SilentModeL() : start");	
+    TInt retVal = ETrue;
+    
+    if ( aParams->iCurrentJob.UsageType() == ESmlDataSync )
+        {
+        return EFalse;               
+        }
+ if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement))
+ {
+	//get DM profile -> get profile serverid
+	CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+    CNSmlDMProfile* prof = settings->ProfileL( 
+            aParams->iCurrentJob.ProfileId() );
+    CleanupStack::PushL( prof );
+
+	//connect to policy engine
+	RPolicyEngine policyEngine;
+	User::LeaveIfError( policyEngine.Connect() );
+	CleanupClosePushL( policyEngine );
+		
+	RPolicyManagement policyManagement;
+	User::LeaveIfError( policyManagement.Open( policyEngine ) );
+
+	//check is the specific server id allowed to work in silent mode
+	TInt err = policyManagement.IsAllowedServerId( 
+	        prof->StrValue( EDMProfileServerId ) );
+			
+	policyManagement.Close();
+
+	CleanupStack::PopAndDestroy( 3, settings );
+	
+	if ( err == KErrNone )
+	    {
+	    retVal = ETrue;    
+	    }
+	else
+	    {
+	    retVal = EFalse;    
+	    }	
+}
+else
+{
+	//if policy management is not installed....
+	retVal = EFalse;
+}
+
+    if( retVal )
+        {
+        _DBG_FILE("CNSmlThreadEngine::SilentModeL() : end, return ETrue");
+        }
+    else
+        {
+        _DBG_FILE("CNSmlThreadEngine::SilentModeL() : end, return EFalse");
+        }
+
+    return retVal;
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::SaveSessionInfo()
+// Save session info which is needed later in DM agent to launch notifier
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::SaveSessionInfoL()
+    {    
+ if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement))
+ {
+	CRepository * rep = CRepository::NewLC( 
+	                    KCRUidPolicyManagementUtilInternalKeys );
+
+	TSyncMLAppLaunchNotifParams params;	
+	
+	if ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync )	
+	    {
+	    params.iSessionType = ESyncMLSyncSession;    
+	    }
+	else
+	    {
+	    params.iSessionType = ESyncMLMgmtSession;    
+	    }
+   
+	params.iJobId = iThreadParams.iCurrentJob.JobId();
+	params.iProfileId = iThreadParams.iCurrentJob.ProfileId(); 
+
+    TPckg<TSyncMLAppLaunchNotifParams> data( params );
+   
+	TInt err = rep->Set( KSyncMLSessionParamsKey, data );
+	
+	if ( err == KErrNotFound )
+	    {
+		User::LeaveIfError( rep->Create( KSyncMLSessionParamsKey, data ) );
+    	}
+	else
+	    {
+        _DBG_FILE("CNSmlThreadEngine::SaveSessionInfoL TInt err = \
+                    rep->Set( KParamsKey, data );");
+	    User::LeaveIfError( err );
+	    }
+
+	CleanupStack::PopAndDestroy( rep );
+}
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::ForcedCertificateCheckL( TBool aForcedState )
+// Launch job session in thread
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::ForcedCertificateCheckL( TBool aForcedState )
+    {
+    if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement))
+    {	
+	CRepository * rep = CRepository::NewLC( KCRUidPolicyManagementUtilInternalKeys );
+
+	TInt err = rep->Set( KSyncMLForcedCertificateCheckKey, aForcedState );
+	
+	if ( err == KErrNotFound )
+	    {
+		User::LeaveIfError( rep->Create( KSyncMLForcedCertificateCheckKey, aForcedState ));
+    	}
+
+	CleanupStack::PopAndDestroy( rep );
+		}
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::StartJobSessionL()
+// Launch job session in thread
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::StartJobSessionL()
+	{
+	_DBG_FILE("CNSmlThreadStart::StartJobSession() : Begin");	
+		
+	if ( !IsActive() )
+		{
+		SetActive();
+		}
+		
+	TInt status( KErrNone );			
+	if ( iThreadParams.iCurrentJob.UsageType() == ESmlDevMan )
+		{
+		TRAP( status, StartDMSessionL() );
+		}
+	else
+		{
+		TRAP( status, StartDSSessionL() );	
+		}
+	
+	if ( status != KErrNone )
+	    {
+	   	TRequestStatus* sStatus = &iStatus;
+		User::RequestComplete( sStatus, status );    
+	    }
+	_DBG_FILE("CNSmlThreadStart::StartJobSession() : End");	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::CancelJob()
+// Cancel current running job
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::CancelJob()
+	{
+	if ( iCancelTimeout )
+	    {
+		iCancelTimeout->SetJobCancelled( iThreadParams.iCurrentJob.UsageType() );
+	    }	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::StartDMSessionL()
+// Start DM job
+// --------------------------------------------------------------------------
+//	
+void CNSmlThreadEngine::StartDMSessionL()
+	{
+	TInt result = iSessionLib.Load( KSmlDMAgentLoaderLibName );
+    if ( result != KErrNone )
+    	{
+	    _DBG_FILE("CNSmlSOSHandler::StartDMSyncL(): loading agent failed !");
+    	User::Leave( result );
+    	}
+    TNSmlCreateDMAgentFunc createDMAgentL = (TNSmlCreateDMAgentFunc)iSessionLib.Lookup(1);
+    iDMAgent =  createDMAgentL(iThreadParams.iSOSHandler);    
+    
+    iCancelTimeout = new (ELeave) CNSmlCancelTimeOut( *iDMAgent, *iDSAgent );
+    
+	iDMAgent->Configure(iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), (TNSmlSyncInitiation)iThreadParams.iSyncInit,
+			iThreadParams.iCurrentJob.GetJobIapId());
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::StartDSSessionL()
+// Start DS job
+// --------------------------------------------------------------------------
+//		
+void CNSmlThreadEngine::StartDSSessionL()
+	{
+	
+	TInt result = iSessionLib.Load( KSmlDSAgentLoaderLibName );
+	if ( result != KErrNone )
+		{
+	    _DBG_FILE("CNSmlSOSHandler::StartDSSyncL(): loading agent failed!");
+		User::Leave( result );
+		}
+	
+	TNSmlCreateDSAgentFunc createDSAgentL = (TNSmlCreateDSAgentFunc)iSessionLib.Lookup(1);
+	iDSAgent = createDSAgentL( iThreadParams.iSOSHandler );
+	
+	iCancelTimeout = new (ELeave) CNSmlCancelTimeOut( *iDMAgent, *iDSAgent );
+	
+	// Select correct sync method and start sync
+	TNSmlSyncInitiation syncInit = (TNSmlSyncInitiation)iThreadParams.iSyncInit;
+	
+    switch ( iThreadParams.iCurrentJob.JobType() )
+        {
+        case EDSJobProfile:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, NULL, syncInit );
+            break;           
+        case EDSJobProfileST:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, iContentArray, syncInit ); // + syncType
+            break;            
+        case EDSJobTasks:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, iContentArray, syncInit ); // + tasks
+            break;
+        case EDSJobTasksST:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, iContentArray, syncInit ); // + tasks & syncType
+            break;
+        case EDSJobTransport:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), NULL, syncInit ); // + transport
+            break;
+        case EDSJobTransportST:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), iContentArray, syncInit ); // + transport & syncType
+            break;
+        case EDSJobTaskTrans:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), iContentArray, syncInit ); // + tasks & transport
+            break;
+        case EDSJobTaskTransST:
+            iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), iContentArray, syncInit, iThreadParams.iCurrentJob.iSessionId, iThreadParams.iCurrentJob.iPackage ); // + tasks & transport & syncType & server alert
+            break;
+        default:
+            break;
+        }
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::VerifyJobFromNotifierL()
+// Launches notifier and waits for 
+// --------------------------------------------------------------------------
+//
+TInt CNSmlThreadEngine::VerifyJobFromNotifierL()
+	{
+	_DBG_FILE("CNSmlThreadEngine::VerifyJobFromNotifierL() : Begin");
+	iNotifierObserver = new (ELeave) CNSmlNotifierObserver(iStatus, iThreadParams);
+	SetActive();
+	
+	TSyncMLAppLaunchNotifParams params;
+	params.iSessionType = ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync ) ? ESyncMLSyncSession : ESyncMLMgmtSession;
+	params.iJobId = iThreadParams.iCurrentJob.JobId();
+	params.iProfileId = iThreadParams.iCurrentJob.ProfileId();
+    params.iUimode = iThreadParams.iCurrentJob.iUimode;	
+	iNotifierObserver->ConnectToNotifierL( params );
+	_DBG_FILE("CNSmlThreadEngine::VerifyJobFromNotifierL() : End");
+    return KErrNone;
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DMAgentL()
+// Returns dm agent if it is created, otherwise leaves with KErrNotFound.
+// --------------------------------------------------------------------------
+//
+CNSmlDMAgent* CNSmlThreadEngine::DMAgentL() const
+	{
+	if ( !iDMAgent )
+		{
+		User::Leave( KErrNotFound );
+		}
+	
+	return iDMAgent;
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DSAgentL()
+// Returns ds agent if it is created, otherwise leaves with KErrNotFound.
+// --------------------------------------------------------------------------
+//
+CNSmlDSAgent* CNSmlThreadEngine::DSAgentL() const
+	{
+	if ( !iDSAgent )
+		{
+		User::Leave( KErrNotFound );
+		}
+	
+	return iDSAgent;
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::DoCancel()
+	{
+	_DBG_FILE("CNSmlThreadStart::DoCancel() : Begin");	
+	_DBG_FILE("CNSmlThreadStart::DoCancel() : End");	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::RunL()
+// From base class : 
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::RunL()
+	{
+	_DBG_FILE("CNSmlThreadEngine::RunL() : Begin");
+	TBool resume( EFalse );
+	TRAP_IGNORE( resume = DoRunL() );
+	
+	if ( resume )
+	    {
+	    return;
+	    }
+	_DBG_FILE("CNSmlThreadEngine::RunL() : End");	
+	CActiveScheduler::Stop();	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DoRunL()
+// Method to perform RunL, that can be trapped.
+// --------------------------------------------------------------------------
+//
+TBool CNSmlThreadEngine::DoRunL()
+    {
+    _DBG_FILE("CNSmlThreadEngine::DoRunL() : Begin");
+    
+    if ( iThreadParams.iCurrentJob.iPending != EFalse )	
+		{
+		iThreadParams.iCurrentJob.iPending = EFalse;
+		if ( iStatus.Int() == KErrNone )
+			{
+			StartJobSessionL();
+			return ETrue;
+			}
+		else
+			{
+			if ( iThreadParams.iCurrentJob.TransportId() != KUidNSmlMediumTypeInternet.iUid )
+				{
+				// Disconnect local connection.
+				TRAP_IGNORE( iThreadParams.iSOSHandler->DoDisconnectL() );				
+				}
+			
+			WriteHistoryLogL( iStatus.Int() );
+			}
+		}
+	_DBG_FILE("CNSmlThreadEngine::DoRunL() : Begin");    
+	return EFalse;	
+    }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::WriteHistoryLogL( TInt aErrorCode )
+// Writes history log when notifier start 
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::WriteHistoryLogL( TInt aErrorCode )
+	{
+    RArray<TInt> tasks;
+   	       	
+    if ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync )
+    	{
+    	iThreadParams.iCurrentJob.TaskIds( tasks );	
+    	}       	
+   	CleanupClosePushL(tasks);
+   	
+    CSyncMLHistoryJob* historyLog = CSyncMLHistoryJob::NewL( iThreadParams.iCurrentJob.ProfileId(), tasks );
+    CleanupStack::PushL( historyLog );             
+    
+	TTime time;
+	time.UniversalTime();
+	
+	historyLog->SetResult( time, aErrorCode );
+
+	if ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync )
+		{
+		CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+		CNSmlDSProfile* prof = settings->ProfileL( iThreadParams.iCurrentJob.ProfileId() );
+		CleanupStack::PushL( prof );
+		CNSmlHistoryArray* array = CNSmlHistoryArray::NewL();
+		CleanupStack::PushL( array );
+		array->SetOwnerShip( ETrue );
+	
+		RReadStream& readStream = prof->LogReadStreamL();
+		CleanupClosePushL( readStream );
+		
+		if ( readStream.Source()->SizeL() > 0 )
+			{
+			array->InternalizeL( readStream );
+			}
+			
+		CleanupStack::PopAndDestroy(); // readStream
+	
+		array->AppendEntryL( historyLog );
+		RWriteStream& writeStream = prof->LogWriteStreamL();
+		CleanupClosePushL( writeStream );
+		array->ExternalizeL( writeStream );
+		CleanupStack::PopAndDestroy(); // writeStream
+		prof->WriteStreamCommitL();
+	
+		CleanupStack::PopAndDestroy(array);
+		CleanupStack::PopAndDestroy(prof);
+		CleanupStack::PopAndDestroy(settings);
+		}
+	else	// DevMan
+		{
+		CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+		CNSmlDMProfile* prof = settings->ProfileL( iThreadParams.iCurrentJob.ProfileId() );
+		CleanupStack::PushL( prof );
+		CNSmlHistoryArray* array = CNSmlHistoryArray::NewL();
+		CleanupStack::PushL( array );
+		array->SetOwnerShip( ETrue );
+	
+		RReadStream& readStream = prof->LogReadStreamL();
+		CleanupClosePushL( readStream );
+		
+		if ( readStream.Source()->SizeL() > 0 )
+			{
+			array->InternalizeL( readStream );
+			}
+			
+		CleanupStack::PopAndDestroy(); // readStream
+	
+		array->AppendEntryL( historyLog );
+		RWriteStream& writeStream = prof->LogWriteStreamL();
+		CleanupClosePushL( writeStream );
+		array->ExternalizeL( writeStream );
+		CleanupStack::PopAndDestroy(); // writeStream
+		prof->WriteStreamCommitL();
+	
+		CleanupStack::PopAndDestroy(array);
+		CleanupStack::PopAndDestroy(prof);
+		CleanupStack::PopAndDestroy(settings); 				
+		}
+		
+	CleanupStack::Pop(historyLog);
+	CleanupStack::PopAndDestroy(&tasks);					
+	}
+// --------------------------------------------------------------------------
+// TNSmlThreadLauncher::RunJobSession( CNSmlThreadParams& aParams, CNSmlThreadObserver& aObserver )
+// Launches a new thread for job session
+// --------------------------------------------------------------------------
+//
+TInt TNSmlThreadLauncher::RunJobSession( CNSmlThreadParams& aParams, CNSmlThreadObserver& aObserver )
+	{
+	_DBG_FILE("TNSmlThreadLauncher::RunJobSession() : Begin");	
+	RThread thread;
+	
+	TName threadName ( KNSmlJobThread );
+    threadName.Append ( _L("_") );
+    threadName.AppendNum ( Math::Random(), EHex );
+	
+	TInt status = thread.Create(threadName, ThreadFunction, KNSmlSOSServerStackSize, NULL, &aParams, EOwnerProcess);
+	
+	if (status != KErrNone)
+		{
+		thread.Close();
+		return status;
+		}
+		
+	thread.SetPriority( EPriorityNormal ); // set priority
+	thread.Resume();
+	
+	//Request notification when DM session thread ends.
+	aObserver.LogonToThread( thread );
+
+	thread.Close(); 
+	_DBG_FILE("TNSmlThreadLauncher::RunJobSession() : End");	
+	return status;
+	}
+
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::CNSmlThreadObserver()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadObserver::CNSmlThreadObserver(TRequestStatus& aStatus)
+:CActive(0), iSosStatus(aStatus)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::~CNSmlThreadObserver()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadObserver::~CNSmlThreadObserver()
+	{
+	Cancel();
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::LogonToThread( RThread& aThread )
+// Logs on to given thread. Wakes the server scheduler
+// --------------------------------------------------------------------------
+//	
+void CNSmlThreadObserver::LogonToThread( RThread& aThread )
+	{
+	_DBG_FILE("CNSmlThreadObserver::LogonToThread() : Begin");	
+	if ( !IsActive() )
+		{
+		SetActive();
+		}
+		
+	aThread.Logon( iStatus );
+	_DBG_FILE("CNSmlThreadObserver::LogonToThread() : End");	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadObserver::DoCancel()
+	{
+	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::RunL()
+// Logs on to given thread. Called when thread finishes.
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadObserver::RunL()
+	{
+	DBG_FILE_CODE(iStatus.Int(), _S8("CNSmlThreadObserver::RunL() : Begin"));	
+	
+	TInt err;
+	TInt dsStatus = KErrNotFound;
+	
+	err = RProperty::Set( KPSUidDataSynchronizationInternalKeys, KDataSyncStatus, dsStatus );
+	
+	if(err == KErrNone) 
+	{
+		if(dsStatus != EDataSyncNotRunning )	
+		{
+			RProperty::Set( KPSUidDataSynchronizationInternalKeys, KDataSyncStatus, EDataSyncNotRunning );	
+		}
+	
+	}
+	//Notify thread completion status code to caller.
+	TRequestStatus* sStatus = &iSosStatus;
+	User::RequestComplete( sStatus, iStatus.Int() );
+	
+	_DBG_FILE("CNSmlThreadObserver::LogonToThread() : End");	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::CNSmlNotifierObserver(TRequestStatus& aStatus, CNSmlThreadEngine* aEngine, CNSmlThreadParams& aParams)
+// Constructor
+// --------------------------------------------------------------------------
+//	
+CNSmlNotifierObserver::CNSmlNotifierObserver(TRequestStatus& aStatus, CNSmlThreadParams& aParams)
+: CActive(0), iCallerStatus(aStatus), iThreadParams(aParams)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::~CNSmlNotifierObserver()
+// Destructor
+// --------------------------------------------------------------------------
+//	
+CNSmlNotifierObserver::~CNSmlNotifierObserver()
+	{
+	
+	// StartNotifier called to avoid Notifier server panic, if 
+	// notifier does not exist anymore.
+	TBuf8<1> dummy;	
+	iNotifier.StartNotifier(KNullUid, dummy, dummy); // KNullUid should do also..
+	
+	iNotifier.CancelNotifier( KUidNotifier );
+	iNotifier.Close();
+	Cancel();
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::ConnectToNotifierL( const TSyncMLAppLaunchNotifParams& aParam )
+// Starts connection with notifier
+// --------------------------------------------------------------------------
+//		
+void CNSmlNotifierObserver::ConnectToNotifierL( const TSyncMLAppLaunchNotifParams& aParam )
+	{
+	_DBG_FILE( "CNSmlNotifierObserver::ConnectToNotifierL:Begin" );
+	iTimeOut = EFalse;
+	
+	if ( !IsActive() )
+		{
+		SetActive();
+		}
+		
+	   
+    TSyncMLAppLaunchNotifParamsPckg data( aParam );
+    
+    if ( !KNSmlWaitNotifierForEver )
+        {
+        iNotifierTimeOut.LaunchNotifierTimer( this );
+        }
+        
+    TInt err = iNotifier.Connect();
+    if ( err == KErrNone )
+        {
+        iNotifier.StartNotifierAndGetResponse( iStatus, KUidNotifier, data, iResBuf );                
+        }
+    else
+        {
+        // Stop job. Error connecting to notifier.
+        TRequestStatus* sStatus = &iStatus;
+		User::RequestComplete( sStatus, err );            
+        }
+     _DBG_FILE("CNSmlNotifierObserver::ConnectToNotifierL:End");   
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::NotifierTimeOut()
+// Starts notifier time out timer
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierObserver::NotifierTimeOut()
+	{
+	iTimeOut = ETrue;
+	
+	// StartNotifier called to avoid Notifier server panic, if 
+	// notifier does not exist anymore.
+	TBuf8<1> dummy;
+	iNotifier.StartNotifier(KNullUid, dummy, dummy); // KNullUid should do also..
+	iNotifier.CancelNotifier( KUidNotifier );
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//	
+void CNSmlNotifierObserver::DoCancel()
+	{
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::RunL()
+// From base class
+// --------------------------------------------------------------------------
+//	
+void CNSmlNotifierObserver::RunL()
+	{
+	    
+    TInt ret = iStatus.Int();
+    if ( ret == KErrCancel && iTimeOut )
+    	{
+    	
+    	}
+    else
+    if ( ret == KErrNone )
+    	{	   
+        
+	  	TInt sid = iResBuf().iSecureId.iUid; // read secure id from notifier.
+	   	
+	    // Check the response and error code. If there is a fail, dump the job.        
+	    // Also compare sid to creator id saved for current job to secure that listener owns the job.
+	    if ( ret != KErrNone || sid != iThreadParams.iCurrentJob.CreatorId() )
+	        {
+	        if ( ret == KErrNone && sid != iThreadParams.iCurrentJob.CreatorId() )
+	        	{
+#ifndef __WINS__	        	
+	        	ret = KErrPermissionDenied;
+#endif	        	
+	        	}
+	        }
+	    	
+    	}
+    
+	TRequestStatus* sStatus = &iCallerStatus;
+	User::RequestComplete( sStatus, ret );
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::~CNSmlNotifierTimeOut()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlNotifierTimeOut::CNSmlNotifierTimeOut()
+:CActive(0)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::~CNSmlNotifierTimeOut()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlNotifierTimeOut::~CNSmlNotifierTimeOut()
+	{
+	Cancel();
+	iTimeOutTimer.Close();
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::LaunchNotifierTimer( CNSmlNotifierObserver*  aObserver )
+// Starts notifier time out timer
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierTimeOut::LaunchNotifierTimer( CNSmlNotifierObserver*  aObserver )
+	{
+	
+	if ( !IsActive() )
+		{
+		SetActive();
+		}
+		
+	iTimeOutTimer.CreateLocal();
+	iTimeOutTimer.After( iStatus, KNotifierTimeout );
+	iObserver = aObserver;
+	}
+	
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::DoCancel()
+// From base class 
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierTimeOut::DoCancel()
+	{
+	iTimeOutTimer.Cancel();
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::RunL()
+// From base class 
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierTimeOut::RunL()
+	{
+	if ( iStatus.Int() != KErrCancel )
+		{
+		iObserver->NotifierTimeOut();	
+		}
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::CNSmlCancelTimeOut()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlCancelTimeOut::CNSmlCancelTimeOut( CNSmlDMAgent& aDMAgent, CNSmlDSAgent& aDSAgent )
+: CActive(0), iDMAgent(aDMAgent), iDSAgent(aDSAgent)
+	{
+	CActiveScheduler::Add(this);
+	iTimeOutTimer.CreateLocal();
+	iDoCancel = EFalse;
+	if ( !IsActive() )
+		{
+		SetActive();
+		}
+		
+	iTimeOutTimer.After( iStatus, 10000 );	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::~CNSmlCancelTimeOut()
+// Destructor
+// --------------------------------------------------------------------------
+//	
+CNSmlCancelTimeOut::~CNSmlCancelTimeOut()
+	{
+	Cancel();
+	iTimeOutTimer.Close();	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::SetJobCancelled()
+// Flags job to be cancelled
+// --------------------------------------------------------------------------
+//			
+void CNSmlCancelTimeOut::SetJobCancelled( TSmlUsageType aUsageType )
+	{
+	iDoCancel = ETrue;
+	iUsageType = aUsageType;	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::DoCancel()
+// From base class 
+// --------------------------------------------------------------------------
+//	
+void CNSmlCancelTimeOut::DoCancel()
+	{
+	iTimeOutTimer.Cancel();	
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::RunL()
+// From base class 
+// --------------------------------------------------------------------------
+//
+void CNSmlCancelTimeOut::RunL()
+	{
+	if ( iDoCancel )
+		{
+		if ( iUsageType == ESmlDevMan )
+			{
+			iDMAgent.Cancel();					
+			}
+		else
+			{
+			iDSAgent.Cancel();					
+			}
+		}
+	else
+		{
+		if ( !IsActive() )
+			{
+			SetActive();
+			}
+		iTimeOutTimer.After( iStatus, 10000 );		
+		}
+	}
+
+// --------------------------------------------------------------------------
+// CNSmlThreadParams::~CNSmlThreadParams()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadParams::~CNSmlThreadParams()
+	{
+	delete iCSArray;
+	iCSArray = 0;
+	}