diff -r 000000000000 -r b497e44ab2fc syncmlfw/common/sosserver/src/nsmlsoshandler.cpp --- /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 +#include +#include +//#include +#include +#include +#include +#include +#include +#include + +#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& aArray, const TSmlUsageType aType ) +// Returns an array of ids of queued jobs of seleted type. +// -------------------------------------------------------------------------- +// +void CNSmlSOSHandler::QueuedJobsL( RArray& 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* 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(1); + iParams->iSyncInit = syncInit; + + TNSmlContentSpecificSyncType css; + // Tasks and sync type are overrided in a same struct -> must be handled together. + + RArray 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 tempTasks; + tempJob->TaskIds( tempTasks ); + + RArray 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& aArray ) +// -------------------------------------------------------------------------- +// +void CNSmlSOSHandler::ReadTasksFromDBL( RArray& 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(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