syncmlfw/dm/syncagent/src/nsmldmcmds.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 18 Aug 2010 10:39:36 +0300
changeset 57 f5b689a4f7a2
parent 44 39aa16f3fdc2
permissions -rw-r--r--
Revision: 201031 Kit: 201033

/*
* Copyright (c) 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:  SyncML DM command handling 
*
*/



// INCLUDE FILES
//
#include <f32file.h>
#include <utf.h>
// FOTA
#include <DevManInternalCRKeys.h>
#include <featmgr.h>
// FOTA end
#include <devicedialogsymbian.h>

#include <nsmlconstants.h>
#include <nsmldebug.h>
#include <nsmlphoneinfo.h>
#include <nsmlunicodeconverter.h>
// DM specific includes
#include <nsmldmconst.h>
#include <nsmldmmodule.h>
//For P&S keys
#include <e32property.h>
#include <e32math.h> 
#include "nsmldminternalpskeys.h"
// common includes with DS
#include "nsmlcliagconstants.h"
#include "NSmlCmdsBase.h"
#include "NSmlAgentBase.h"
#include "NSmlStatusContainer.h"
#include "NSmlResponseController.h"
#include "NSmlResultsContainer.h"
#include "NSmlAuth.h"
#include "NSmlURI.h"
#include "WBXMLSyncMLGenerator.h"
#include "WBXMLSyncMLParser.h"
#include "WBXMLGeneratorError.h"
#include "WBXMLParser.h"
#include "smldtd.h"
#include "smldef.h"
#include "nsmlagenttestdefines.h"
#include <hbdevicedialogsymbian.h>
#include <hbsymbianvariant.h>
// DM specific includes
#include "nsmldmagconstants.h"
#include "NSmlDMCmds.h"
#include "nsmldmerror.h"
#include <dmdevdialogclient.h>
#include "OnlineSupportLogger.h"
#ifdef __TEST_TREEMODULE
#include "nsmldmtestmodule.h"
#else
#include <nsmldmmodule.h>
#endif


#ifndef __WINS__
// This lowers the unnecessary compiler warning (armv5) to remark.
// "Warning:  #174-D: expression has no effect..." is caused by 
// DBG_ARGS8 macro in no-debug builds.
#pragma diag_remark 174
#endif


//const TUid KNSmlSyncDialogUid = { 0x101F876A };
// FOTA
const TInt KNSmlDmNoRequest = -1;
// FOTA end

_LIT8 ( KNSmlDMMetaTypeUserRequest, "org.openmobilealliance.dm.firmwareupdate.userrequest" );
_LIT8 ( KNSmlDMMetaFormatUserRequest, "chr" );

const TUid dmagentuid =
            {
            0x101F6DE5
            };



enum TSyncmlHbNotifierKeys 
		{

     EHbSOSNotifierKeyStatus = 11, // status set will complete the client subscribe
     EHbSOSNotifierKeyStatusReturn = 12, // Return the content of actual status value accepted from UI
     
     EHbDMSyncNotifierKeyStatus = 13,
     EHbDMSyncNotifierKeyStatusReturn = 14
		};

// ---------------------------------------------------------
// CNSmlDMCmds::NewL()
// Creates new instance of CNSmlDMCmds 
// Does not leave instance pointer to CleanupStack.
// ---------------------------------------------------------
//
CNSmlDMCmds* CNSmlDMCmds::NewL( CNSmlAgentBase* aAgent, const TDesC8& aSessionID, const TDesC8& aVerProto, const HBufC& aSyncMLUserName, CNSmlURI* aSyncServer, const TDesC& aDMServerId, MSyncMLProgressObserver* aDMObserver )
    {
	CNSmlDMCmds* self = new (ELeave) CNSmlDMCmds();
	CleanupStack::PushL( self );
    self->ConstructL( aAgent, aSessionID, aVerProto, aSyncMLUserName, aSyncServer, aDMServerId, aDMObserver );
    CleanupStack::Pop(); //self
	return self;
    }

// ---------------------------------------------------------
// CNSmlDMCmds::~CNSmlDMCmds()
// Destructor
// ---------------------------------------------------------
//
CNSmlDMCmds::~CNSmlDMCmds()
    {
	delete iDMServerId;
	delete iDMModule;
	if ( iDMDevInfo )
		{
		delete iDMDevInfo->iFormat;
		delete iDMDevInfo->iType; 
		delete iDMDevInfo->iObject;
		delete iDMDevInfo;
		}
	delete iLargeObjectUri;

	if(iChunk.Handle())
	    {
	    iChunk.Close();
	    }
	// FOTA
	// uninitialize feature manager
	FeatureManager::UnInitializeLib();
	delete iRepository;
	
	//P&S key deletion,even fine if the key is not there
	RProperty::Delete( KPSUidNSmlDMSyncAgent,KNSmlDMCmdAddOnExistingNodeorLeafKey);	
	// FOTA end	
	}


// ---------------------------------------------------------
// CNSmlDMCmds::CNSmlDMCmds()
// Constructor
// ---------------------------------------------------------
//
CNSmlDMCmds::CNSmlDMCmds()
    {
	}
// ---------------------------------------------------------
// CNSmlDMCmds::ConstructL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::ConstructL( CNSmlAgentBase* aAgent, const TDesC8& aSessionID, const TDesC8& aVerProto, const HBufC& aSyncMLUserName, CNSmlURI* aSyncServer, const TDesC& aDMServerId, MSyncMLProgressObserver* aDMObserver )
    {
    if(!FeatureManager::FeatureSupported( KFeatureIdSyncMlDm112  ))
    {
	CNSmlCmdsBase::ConstructL( aAgent, aSessionID, aVerProto,KNSmlSyncMLPublicId12 , aSyncMLUserName, aSyncServer, EFalse );
    }
    else
    {
    CNSmlCmdsBase::ConstructL( aAgent, aSessionID, aVerProto,KNSmlSyncMLPublicId , aSyncMLUserName, aSyncServer, EFalse );	
    }
	iDMServerId = aDMServerId.AllocL();
	iDMObserver = aDMObserver;
#ifdef __TEST_TREEMODULE
	iDMModule = CNSmlDmTestModule::NewL( this );
#else
	iDMModule = CNSmlDmModule::NewL( this );
#endif
	HBufC8* serverId = CnvUtfConverter::ConvertFromUnicodeToUtf8L(aDMServerId);
	CleanupStack::PushL(serverId);
	iDMModule->SetServerL( *serverId );
	CleanupStack::PopAndDestroy(); //serverId
	
	// FOTA
	// init feature manager
	FeatureManager::InitializeLibL();
	if ( FeatureManager::FeatureSupported ( KFeatureIdSyncMlDmFota ) )
		{
		TRAPD ( error, iRepository = CRepository::NewL ( KCRUidDeviceManagementInternalKeys ) );
		if ( error != KErrNone )
			{
			iRepository = NULL;
			}
		}
	// FOTA end	
    }

// ---------------------------------------------------------
// CNSmlDMCmds::DoDevInfoItemsL()
// Function which is called recursive when writing DevInfo items
// ---------------------------------------------------------
void CNSmlDMCmds::DoDevInfoItemsL( const TDesC8& aURI ) 
	{
	iDMModule->FetchObjectL( aURI, KNullDesC8, 0, 0, ETrue );
	if ( !iDMDevInfo->iResults )
		{
		return;
		}
	iDMDevInfo->iResults = EFalse;
	if ( *iDMDevInfo->iFormat == _L8("node") )
		{
		HBufC8* childList = iDMDevInfo->iObject->AllocLC();
		TPtrC8 childListPtr( *childList );
		TInt pos = 0;
		TBool moreData = ETrue;
		do 
			{
			pos = childListPtr.Locate('/');
			if ( pos == KErrNotFound )
				{
				moreData = EFalse;
				pos = childListPtr.Length();
				}
			User::LeaveIfError( pos );
			HBufC8* childURI = HBufC8::NewLC( aURI.Length() + 1 + pos );
			*childURI = aURI;
			TPtr8 childURIPtr = childURI->Des();
			childURIPtr += _L8("/");
			HBufC8* segment = HBufC8::NewLC( pos );
			segment->Des().Copy( childListPtr.Left( pos ) );
			childURIPtr += *segment;
			DoDevInfoItemsL( *childURI );
			if ( moreData )
				{
				childListPtr.Set( childListPtr.Right( childListPtr.Length() - ( segment->Length() +1 ) ));
				}
			CleanupStack::PopAndDestroy( 2 ); // segment, childURI
			} while ( moreData );
		CleanupStack::PopAndDestroy(); // childList
		}
	else
		{
		if ( iDMDevInfo->iFirst )
			{
			iDMDevInfo->iFirst = EFalse;
			}
		else
			{
			(*iDMDevInfo->iItemListPtr)->next = new( ELeave ) SmlItemList_t;
			iDMDevInfo->iItemListPtr = &(*iDMDevInfo->iItemListPtr)->next;
			(*iDMDevInfo->iItemListPtr)->item = new( ELeave ) SmlItem_t;
			}
		DoSourceL( (*iDMDevInfo->iItemListPtr)->item->source, aURI );
		SmlMetInfMetInf_t* metInf;
		DoMetInfLC( metInf ); 
		PcdataNewL( metInf->format, *iDMDevInfo->iFormat );
		PcdataNewL( metInf->type, _L8("text/plain") );
		DoMetaL( (*iDMDevInfo->iItemListPtr)->item->meta, metInf );
		CleanupStack::Pop(); //metInf , only Pop because ownership has been changed
		PcdataNewL( (*iDMDevInfo->iItemListPtr)->item->data, *iDMDevInfo->iObject );
		}
	}
// ---------------------------------------------------------
// CNSmlDMCmds::FreeDMDevinfo()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::FreeDMDevinfo()
	{
	if ( iDMDevInfo )
		{
		delete iDMDevInfo->iFormat;
		delete iDMDevInfo->iType; 
		delete iDMDevInfo->iObject;
		delete iDMDevInfo;
		iDMDevInfo = NULL;
		}
	}
// ---------------------------------------------------------
// CNSmlDMCmds::AlertParameter()
// 
// ---------------------------------------------------------
TInt CNSmlDMCmds::AlertParameter( const SmlPcdata_t* aData, const TDesC8& aParamID ) const
	{
	TInt valueNum = 0;
	if ( aData )
		{
		if ( aData->content )
			{
			TPtr8 parameters( (TUint8*) aData->content, aData->length, aData->length );
			TrimRightSpaceAndNull( parameters );
			TInt startPos = parameters.Find( aParamID );
			if ( startPos >= 0 )
				{
				if ( parameters.Length() > startPos + aParamID.Length() )
					{
					TPtrC8 strPart = parameters.Right( parameters.Length() - ( startPos + aParamID.Length() ) );
					TInt length = 0;
					while ( length < strPart.Length() )
						{
						TChar character = strPart[length];
						if ( character.IsDigit() )
							{
							++length;
							}
						else
							{
							break;
							}
						}
					TPtrC8 valueStr = strPart.Left(	length );
					TLex8 lexicalValue( valueStr );
					if ( lexicalValue.Val( valueNum ) != KErrNone )
						{
						valueNum = 0;
						}
					}
				}
			}
		}
	return valueNum; 
	}

// ---------------------------------------------------------
// CNSmlDMCmds::AlertDataLC()
// 
// ---------------------------------------------------------
HBufC8* CNSmlDMCmds::AlertDataLC( const SmlItemList_t* aItemList ) const
	{
	HBufC8* unicodeData = NULL;
	_DBG_FILE("CNSmlDMCmds::AlertDataLC: Begin");
	if (  aItemList )
		{
		if (  aItemList->next )
			{
			if (  aItemList->next->item )
				{
			  if (  aItemList->next->item->data )
				  {
				  if (  aItemList->next->item->data->content )
					{
					TPtr8 data( (TUint8*)  aItemList->next->item->data->content,  aItemList->next->item->data->length, aItemList->next->item->data->length );
					TrimRightSpaceAndNull( data );
					unicodeData = data.AllocLC();
					data.Zero();
					}
				  }
				}
			}
		}
		
	if ( unicodeData == NULL )
		{
		unicodeData = HBufC8::NewLC( 0 );
		}
	_DBG_FILE("CNSmlDMCmds::AlertDataLC: end");	
	return unicodeData;
	}
// ---------------------------------------------------------
// CNSmlDMCmds::InitStatusToAtomicOrSequenceL()
// 
// ---------------------------------------------------------
TInt CNSmlDMCmds::InitStatusToAtomicOrSequenceL( const TDesC8& aCmd, const SmlAtomic_t* aAtomic ) const
	{
	TInt statusID( 0 );
	statusID = iStatusToServer->CreateNewStatusElementL(); 
	iStatusToServer->SetCmdRefL( statusID, aAtomic->cmdID );
	iStatusToServer->SetCmdL( statusID, aCmd ); 
	if ( iStatusToServerNoResponse || IsFlagSet( aAtomic->flags, SmlNoResp_f ) )
		{
		iStatusToServer->SetNoResponse( statusID, ETrue );
		}
	else
		{
		iStatusToServer->SetNoResponse( statusID, EFalse );
		}
	iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusOK );
	return statusID;
	}

// ---------------------------------------------------------
// CNSmlDMCmds::DoAlertL()
// Makes Alert element and calls parser to generate xml
// ---------------------------------------------------------
void CNSmlDMCmds::DoAlertL( const TDesC8& aAlertCode, TTime* /*aLastSyncAnchor*/, TTime* /*aNextSyncAnchor*/ )
	{
	//initialise Alert
	SmlAlert_t* alert = new( ELeave ) SmlAlert_t; 
	CleanupStack::PushL( alert );
	//element type
	alert->elementType = SML_PE_ALERT;
	//CmdID element
	DoCmdIdL( alert->cmdID );
	//Alert code to Data element 
	PcdataNewL ( alert->data, aAlertCode );
	TInt ret = iGenerator->smlAlertCmd( alert);
	if ( ret != KWBXMLGeneratorOk )
		{
		User::Leave( ret );
		}
	CleanupStack::PopAndDestroy(); //alert
	//save Status response information for response status controlling
	CreateAndInitResponseItemL( KNSmlAgentAlert );
	}

// FOTA
// ---------------------------------------------------------
// CNSmlDMCmds::DoGenericAlertL()
//	Makes a generic alert element (or possible many of them) 
//	and calls WBXML generator.
//	@param aFwMgmtUri. The uri which has been used in the exe command whose final result is 
//	about to be reported.
//	@param aMetaType. Meta/Type that should be used in the alert.
//	@param aMetaFormat. Meta/Format that should be used in the alert.
//	@param aFinalResult. The final result value which is reported to remote server.
//	@param aCorrelator. Correlator value used in the original exec command.
// ---------------------------------------------------------
//
void CNSmlDMCmds::DoGenericAlertL ( const TDesC8& aFwMgmtUri, const TDesC8& aMetaType, const TDesC8& aMetaFormat, 
									TInt aFinalResult, const TDesC8& aFwCorrelator ) 
	{	
	SmlAlert_t* alert = new (ELeave) SmlAlert_t; 
	CleanupStack::PushL ( alert );
	alert->elementType = SML_PE_ALERT;
	DoCmdIdL ( alert->cmdID );
	PcdataNewL ( alert->data, KNSmlDMAgentGenericAlert );

	if ( aFwCorrelator != KNullDesC8 )
		{
		PcdataNewL ( alert->correlator, aFwCorrelator );		
		}

	alert->itemList = new ( ELeave ) SmlItemList_t;
	alert->itemList->item = new ( ELeave ) SmlItem_t;
	// URI comes without ./ from the adapter - add it now
	TPtr8 uri = HBufC8::NewLC ( aFwMgmtUri.Length() + KNSmlAgentRelativeURIPrefix().Length() )->Des();
	uri.Append ( KNSmlAgentRelativeURIPrefix );
	uri.Append ( aFwMgmtUri );
	
	DoSourceL ( alert->itemList->item->source, uri );
	CleanupStack::PopAndDestroy();  // uri
	
	SmlMetInfMetInf_t* metInf;
	DoMetInfLC ( metInf ); 
		
	PcdataNewL ( metInf->type, aMetaType );
	PcdataNewL ( metInf->format, aMetaFormat );
	DoMetaL ( alert->itemList->item->meta, metInf );
	CleanupStack::Pop(); // metInf
	TBuf8<KNSmlMaxInt32Length> result;
	result.Num ( aFinalResult );
	PcdataNewL ( alert->itemList->item->data, result );

	TInt ret = iGenerator->smlAlertCmd ( alert );
	if ( ret != KWBXMLGeneratorOk )
		{
		User::Leave( ret );
		}
	CleanupStack::PopAndDestroy(); //alert
	//response item is not created, because client is not
	//interested what server responds to generic alert.
	// ...
	}

//	@param aMetaType. Meta/Type that should be used in the alert.
//	@param aMetaFormat. Meta/Format that should be used in the alert.
//	@param aFinalResult. The final result value which is reported to remote server.
//	@param aCorrelator. Correlator value used in the original exec command.
// ---------------------------------------------------------
//
void CNSmlDMCmds::DoGenericAlertL ( const TDesC8& aCorrelator, const RArray<CNSmlDMAlertItem>& aItemList ) 
	{	
	SmlAlert_t* alert = new (ELeave) SmlAlert_t; 
	CleanupStack::PushL ( alert );
	alert->elementType = SML_PE_ALERT;
	DoCmdIdL ( alert->cmdID );
	PcdataNewL ( alert->data, KNSmlDMAgentGenericAlert );

	if ( aCorrelator != KNullDesC8 )
		{
		PcdataNewL ( alert->correlator, aCorrelator );		
		}

	SmlItemList_t* itemPtr = NULL;
	TInt count = 1;
	if(&aItemList)
	    count = aItemList.Count();
	for(TInt i = 0; i<count; i++)
	{
	if( itemPtr == NULL)
	{
		alert->itemList = new ( ELeave ) SmlItemList_t;
		itemPtr = alert->itemList;		
	}
	else
	{
		itemPtr->next = new ( ELeave ) SmlItemList_t;
		itemPtr = itemPtr->next;
	}
	itemPtr->item = new ( ELeave ) SmlItem_t;
	// URI comes without ./ from the adapter - add it now
	TPtr8 uri = HBufC8::NewLC ((*aItemList[i].iSource).Length() + KNSmlAgentRelativeURIPrefix().Length())->Des();
	uri.Append ( KNSmlAgentRelativeURIPrefix );
	uri.Append ( *aItemList[i].iSource );
	
	DoSourceL ( itemPtr->item->source, uri );
	CleanupStack::PopAndDestroy();  // uri

	TPtr8 targeturi = HBufC8::NewLC ( (*aItemList[i].iTarget).Length())->Des();
	targeturi.Append ( *aItemList[i].iTarget);	
	DoTargetL ( itemPtr->item->target, targeturi  );
	CleanupStack::PopAndDestroy();  // targeturi   
	
	SmlMetInfMetInf_t* metInf;
	DoMetInfLC ( metInf ); 
		
	PcdataNewL ( metInf->type, *aItemList[i].iMetaType );
	PcdataNewL ( metInf->format, *aItemList[i].iMetaFormat );
	PcdataNewL ( metInf->mark, *aItemList[i].iMetaMark );

	DoMetaL ( itemPtr->item->meta, metInf );
	CleanupStack::Pop(); // metInf
	
	PcdataNewL ( itemPtr->item->data, *aItemList[i].iData );

	}
	TInt ret = iGenerator->smlAlertCmd ( alert );
	if ( ret != KWBXMLGeneratorOk )
		{
		User::Leave( ret );
		}
	CleanupStack::PopAndDestroy(); //alert
	//response item is not created, because client is not
	//interested what server responds to generic alert.
	// ...
	}
	
// ---------------------------------------------------------
// CNSmlDMCmds::DoGenericUserAlertL()
//	Makes a generic user alert element, if the update request is set to the
//	central repository by the FOTA UI.
//	@param aProfileId. The profile id of the current dm session. 
//	@return TBool. ETrue if the alert was generated, otherwise EFalse.
// ---------------------------------------------------------
//
TBool CNSmlDMCmds::DoGenericUserAlertL ( TInt aProfileId ) 
	{	
	// Check from the central repository if firmware update
	// is requested by the user
	TBool needsReset(EFalse);
	
	// Getting a value
	TInt readProfId ( KNSmlDmNoRequest );
	if ( iRepository )
		{
		iRepository->Get ( KDevManClientInitiatedFwUpdateId, readProfId );	
		}

	if ( readProfId != KNSmlDmNoRequest && readProfId == aProfileId )
		{
		SmlAlert_t* alert = new (ELeave) SmlAlert_t; 
		CleanupStack::PushL ( alert );
		alert->elementType = SML_PE_ALERT;
		DoCmdIdL ( alert->cmdID );
		PcdataNewL ( alert->data, KNSmlDMAgentGenericAlert );

		alert->itemList = new ( ELeave ) SmlItemList_t;
		alert->itemList->item = new ( ELeave ) SmlItem_t;
	
		SmlMetInfMetInf_t* metInf;
		DoMetInfLC ( metInf ); 
		
		PcdataNewL ( metInf->type, KNSmlDMMetaTypeUserRequest );
		PcdataNewL ( metInf->format, KNSmlDMMetaFormatUserRequest );
		DoMetaL ( alert->itemList->item->meta, metInf );
		CleanupStack::Pop(); // metInf
		
		PcdataNewL ( alert->itemList->item->data, KNullDesC8 );

		TInt ret = iGenerator->smlAlertCmd ( alert );
		if ( ret != KWBXMLGeneratorOk )
			{
			User::Leave( ret );
			}
		CleanupStack::PopAndDestroy(); //alert
		needsReset = ETrue;
		}
	return needsReset;
	}

// ---------------------------------------------------------
// CNSmlDMCmds::ResetGenericUserAlertL()
//	Resets the update request in the central repository by
//	writing '-1' value.
// ---------------------------------------------------------
//
void CNSmlDMCmds::ResetGenericUserAlertL() 
	{	
	// Reset the value in the Central Repository
	if ( iRepository )
		{
		iRepository->Set ( KDevManClientInitiatedFwUpdateId, KNSmlDmNoRequest );	
		}
	}

// ---------------------------------------------------------
// CNSmlDMCmds::MarkGenAlertsSentL()
//	When the generic alerts are successfully sent to the remote 
//	server, the FOTA adapter needs to be informed about this.
//	This command is chained through the DM engine.
// ---------------------------------------------------------
//
void CNSmlDMCmds::MarkGenAlertsSentL() 
	{
	iDMModule->MarkGenAlertsSentL();
	}


// ---------------------------------------------------------
// CNSmlDMCmds::MarkGenAlertsSentL()
//	When the generic alerts are successfully sent to the remote 
//	server, the FOTA adapter needs to be informed about this.
//	This command is chained through the DM engine.
// ---------------------------------------------------------
//
void CNSmlDMCmds::MarkGenAlertsSentL(const TDesC8& aURI) 
	{
	iDMModule->MarkGenAlertsSentL(aURI);
	}
// ---------------------------------------------------------
// CNSmlDMCmds::DisconnectFromOtherServers()
//	Closes the connections to callback server and host servers.
//	Separate function is needed, since the disconnecting cannot 
//	be made after the active scheduler of the thread is stopped.
// ---------------------------------------------------------
//
void CNSmlDMCmds::DisconnectFromOtherServers() 
	{
	iDMModule->DisconnectFromOtherServers();	
	}


// FOTA end

// ---------------------------------------------------------
// CNSmlDMCmds::DoPutL()
// Empty function In DM
// ---------------------------------------------------------
void CNSmlDMCmds::DoPutL()
	{
	}

// ---------------------------------------------------------
// CNSmlDMCmds::DoResultsL()
// 
// ---------------------------------------------------------
CNSmlCmdsBase::TReturnValue CNSmlDMCmds::DoResultsL()
	{
	TBool found( ETrue );
	CNSmlCmdsBase::TReturnValue returnValue = CNSmlCmdsBase::EReturnOK;
	if ( iResultsToServer )  
		{
		iResultsToServer->Begin();
		while( found )
			{
			SmlResults_t* results;
			found = iResultsToServer->NextResultsElement( results ); 
			if ( found )
				{
				SmlPcdata_t* cmdID;
				DoCmdIdL( cmdID );
				CleanupStack::PushL( cmdID );
				iResultsToServer->SetCmdIDL( iResultsToServer->CurrentEntryID(), cmdID );
                CleanupStack::PopAndDestroy(); //cmdID;
                
                TInt dataBufferSize(0);
                
				while ( results->itemList->item->data->length < KNSmlDefaultWorkspaceSize &&  iBytesSent+dataBufferSize<iLargeObjectTotalSize)
					{
					//loop until the whole item is got from the dm module, but stop if item size is over the workspace size.
					//the while condition is false if not large object (iLargeObjectTotalSize =0)
					CBufBase *data= CBufFlat::NewL(64);
					CleanupStack::PushL(data);
					data->InsertL(0,results->itemList->item->data->content,results->itemList->item->data->length);
					TInt len = data->Size();
            		DBG_ARGS8(_S8("CNSmlDMCmds::DoResultsL 1,dataLen= %d,totalSize= %d,bytesSent= %d"), len,iLargeObjectTotalSize,iBytesSent );
					iDMModule->MoreDataL(data);
					if(data->Size()==len)
						{
						CleanupStack::PopAndDestroy(); //data
						break;
						}
					delete results->itemList->item->data;
					PcdataNewL( results->itemList->item->data, data->Ptr( 0 ) );
					dataBufferSize = data->Size();
            		DBG_ARGS8(_S8("CNSmlDMCmds::DoResultsL 2,dataBufferSize= %d"), dataBufferSize );
					CleanupStack::PopAndDestroy(); //data
					}
				
				if ( results->itemList->item->data->length >= KNSmlLargeObjectMinSize )
					{
					iGenerator->SetTruncate( ETrue );
					iGenerator->SetContentLength( results->itemList->item->data->length );
					}
				TInt ret = iGenerator->smlResultsCmd( results );
				switch ( ret )
					{
					case KWBXMLGeneratorOk:
						if ( iGenerator->WasTruncated() )
							{
                      		DBG_ARGS8(_S8("CNSmlDMCmds::DoResultsL before subtract, length=%d"), results->itemList->item->data->length);
							SubtractConsumedFromPcData( results->itemList->item, iGenerator->DataConsumed() );
                      		DBG_ARGS8(_S8("CNSmlDMCmds::DoResultsL after subtract, length=%d, dataConsumed=%d"), results->itemList->item->data->length, iGenerator->DataConsumed());
                       		DBG_ARGS8(_S8("CNSmlDMCmds::DoResultsL DataConsumed, BytesSent= %d, length=%d"), iBytesSent, iGenerator->DataConsumed() );
							iBytesSent += iGenerator->DataConsumed();

							returnValue = CNSmlCmdsBase::EReturnBufferFull;
							found = EFalse;
							}
						else
							{
							iLargeObjectTotalSize = 0;
							iBytesSent = 0;
							iResultsToServer->RemoveWritten( iResultsToServer->CurrentEntryID() );
							}
						CreateAndInitResponseItemL( KNSmlAgentResults );
						break;
					case KWBXMLGeneratorBufferFull:
						returnValue = CNSmlCmdsBase::EReturnBufferFull;
						found = EFalse;
						break;
					default:	
						User::Leave( ret );
						break;
					}
           		DBG_ARGS8(_S8("CNSmlDMCmds::DoResultsL 3,BytesSent= %d"), iBytesSent );
				iGenerator->SetTruncate( EFalse );
				}
			else
				{
				iLargeObjectTotalSize = 0;
				iBytesSent = 0;
				}
			}
		}
	return returnValue;
	}
// ---------------------------------------------------------
// CNSmlDMCmds::DoGetL()
// Empty function In DM
// ---------------------------------------------------------
void CNSmlDMCmds::DoGetL()
	{
	}
// ---------------------------------------------------------
// CNSmlCmdsBase::DoStartSyncL
// Empty function In DM 
// ---------------------------------------------------------
CNSmlCmdsBase::TReturnValue CNSmlDMCmds::DoStartSyncL() 
	{
	return CNSmlCmdsBase::EReturnOK; 
	}
// ---------------------------------------------------------
// CNSmlDMCmds::DoEndSyncL
// Empty function In DM
// ---------------------------------------------------------
void CNSmlDMCmds::DoEndSyncL()  
	{
	}
// ---------------------------------------------------------
// CNSmlDMCmds::DoAddOrReplaceOrDeleteL
// Generate Replace element, which contains DevInf 
// and calls parser to generate xml 
// ---------------------------------------------------------
CNSmlCmdsBase::TReturnValue CNSmlDMCmds::DoAddOrReplaceOrDeleteL() 
	{
	//initialise Add, Update or Delete element 
	SmlGenericCmd_t* genericCmd = new( ELeave ) SmlGenericCmd_t; 
	CleanupStack::PushL( genericCmd );
	//CmdID element
	DoCmdIdL( genericCmd->cmdID );
	
	genericCmd->itemList = new( ELeave ) SmlItemList_t;
		
	iDMDevInfo = new(ELeave) TDMDevInfo;
	iDMDevInfo->iFormat = NULL;
	iDMDevInfo->iType = NULL;
	iDMDevInfo->iObject= NULL;
	iDMDevInfo->iItemListPtr = &genericCmd->itemList;
	(*iDMDevInfo->iItemListPtr)->item = new( ELeave ) SmlItem_t;
	iDMDevInfo->iFirst = ETrue;
	iDMDevInfo->iResults = EFalse;
	iDMDevInfoResults = ETrue;
	DoDevInfoItemsL( _L8("./DevInfo") ); 
	FreeDMDevinfo();
	iDMDevInfoResults = EFalse;	
		
	genericCmd->elementType = SML_PE_REPLACE;
	TInt ret = iGenerator->smlReplaceCmd( genericCmd );
	CNSmlCmdsBase::TReturnValue returnValue = CNSmlCmdsBase::EReturnOK;
	switch ( ret )
		{
		case KWBXMLGeneratorOk:
			break;
		default:
			User::Leave( ret );
			break;
		}
	if ( ret == KWBXMLGeneratorOk )
		{
		CreateAndInitResponseItemL( KNSmlAgentReplace );
		}
	CleanupStack::PopAndDestroy();  //genericCmd 
	return returnValue;
	}


// ---------------------------------------------------------
// CNSmlDMCmds::DoMapL
// Empty function In DM 
// ---------------------------------------------------------
CNSmlDMCmds::TReturnValue CNSmlDMCmds::DoMapL()  
	{
	return EReturnOK;
	}
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessResultsCmdL
// Empty function In DM 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessResultsCmdL( SmlResults_t* /*aResults*/ )
	{
	}
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessPutCmd
// Empty function In DM 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessPutCmdL( SmlPut_t* /*aPut*/ )
	{
	}
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessGetCmdL
// Handle object request from the server in Get command
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessGetCmdL( SmlGet_t* aGet )
	{
	// cmdID
	if ( aGet->cmdID->length == 0 )
		{
		StatusDataToGetCommandL( aGet, NULL, TNSmlError::ESmlStatusIncompleteCommand );
		iAgent->Interrupt( TNSmlError::ESmlCmdIDMissing, EFalse, EFalse );
		return;
		}
    TPtrC8 cmdID( (TUint8*) aGet->cmdID->content, aGet->cmdID->length );
	DBG_ARGS8(_S8("CNSmlDMCmds::ProcessGetCmdL, CmdId = %S"), &cmdID );
	
	SmlItemList_t* itemList;
	HBufC8* uri;
	itemList = aGet->itemList;
	TInt statusID;
	TInt resultsID;
	while ( itemList )
		{
		if ( iAgent->Interrupted() )
			{
			StatusDataToGetCommandL( aGet, itemList->item, TNSmlError::ESmlStatusCommandFailed );
			itemList = itemList->next;
			continue;
			}
		if ( iServerAuth->Challenged() )
			{
			StatusDataToGetCommandL( aGet, itemList->item, TNSmlError::ESmlStatusClientAuthenticationRequired );
			itemList = itemList->next;
			continue;
			}
		if ( iDMNotExecuted )
			{
			StatusDataToGetCommandL( aGet, itemList->item, TNSmlError::ESmlStatusNotExecuted  );
			itemList = itemList->next;
			continue;
			}
		// target
		if ( !TargetIsUnderItem( itemList ) )
			{
			StatusDataToGetCommandL( aGet, itemList->item, TNSmlError::ESmlStatusIncompleteCommand );
			itemList = itemList->next;
			continue;
			}
		statusID = StatusDataToGetCommandL( aGet, itemList->item, TNSmlError::ESmlStatusOK );
		resultsID = iResultsToServer->CreateNewResultsL( *iCurrServerMsgID, cmdID, itemList->item->target, itemList->item->source );
		iResultsToServer->SetStatusID( resultsID, statusID );
		
		TPtr8 pcdata( (TUint8*) itemList->item->target->locURI->content, itemList->item->target->locURI->length, itemList->item->target->locURI->length );
		TrimRightSpaceAndNull( pcdata );
		uri = pcdata.AllocLC();	
				
		iDMModule->FetchObjectL( *uri, *MetaTypeInUtf8LC( itemList->item->meta ), resultsID, statusID, EFalse );
		if ( iDMAtomic )
			{
			iStatusToServer->SetAtomicOrSequenceId( statusID, iDMAtomicID );
			}
		CleanupStack::PopAndDestroy( 2 ); // *MetaTypeLC(), uri
		itemList = itemList->next;
		}
	}

// ---------------------------------------------------------
// CNSmlDMCmds::ProcessAlertCmdL
// Handles Alert command from a server.  
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessAlertCmdL( SmlAlert_t* aAlert, TBool /*aNextAlert*/, TBool /*aServerAlert*/, TBool /*aDisplayAlert*/ )
	{
	TInt statusID( 0 );
	statusID = iStatusToServer->CreateNewStatusElementL(); 
	iStatusToServer->SetCmdRefL( statusID, aAlert->cmdID );
	iStatusToServer->SetCmdL( statusID, KNSmlAgentAlert ); 
	if ( iStatusToServerNoResponse || IsFlagSet( aAlert->flags, SmlNoResp_f ) )
		{
		iStatusToServer->SetNoResponse( statusID, ETrue );
		}
	else
		{
		iStatusToServer->SetNoResponse( statusID, EFalse );
		}
	
	iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusOK );
	
	// Alert Code in Data element
	TPtr8 alertCode = AlertCode( aAlert );
	if ( alertCode.Length() == 0 )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusIncompleteCommand );
		iAgent->Interrupt( TNSmlError::ESmlAlertCodeMissing, EFalse, EFalse );
		return;
		}
	if ( alertCode == KNSmlDMAgentSessionAbortAlert )
		{
		iAgent->Interrupt( TNSmlDMError::ESmlServerSessionAbort, ETrue, EFalse );
		return;
		}
	if ( iAgent->Interrupted() )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusCommandFailed );
		return;
		}
    // cmdID
	if ( aAlert->cmdID->length == 0 )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusIncompleteCommand );
		iAgent->Interrupt( TNSmlError::ESmlCmdIDMissing, EFalse, EFalse );
		return;
		}
	if ( iServerAuth->Challenged() )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusClientAuthenticationRequired );
		return;
		}
	
	if ( iDMNotExecuted )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusNotExecuted );
		return;
		}	
	

	if ( alertCode == KNSmlDMAgentDisplayAlert ||
		 alertCode == KNSmlDMAgentContinueOrAbortAlert ||
		 alertCode == KNSmlDMAgentNextMessage ||
		 alertCode == KNSmlDMAgentSessionAbortAlert ||
		 alertCode == KNSmlDMAgentServerInitAlert ||
		 alertCode == KNSmlDMAgentClientInitAlert )
		{
		HandleAlertsL(aAlert,statusID);
		}
	else
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusOptFeatureNotSupported );
		return;
		}
	
	}

// ---------------------------------------------------------
// CNSmlDMCmds::HandleAlertErrorL
// Handles Error while processing Alert command from a server.  
// ---------------------------------------------------------
void CNSmlDMCmds::HandleAlertErrorL()
    {
    if ( iDMAtomic || iDMSequence )
        {
        iDMNotExecuted = ETrue;
        if (iDMAtomic )
            {
            iDMModule->RollBackL();
            iStatusToServer->SetStatusCodesInAtomicL( iDMAtomicID,    TNSmlError::ESmlStatusRollBackOK, EFalse );
            iStatusToServer->SetStatusCodeToAtomicOrSequenceCmdL( iDMAtomicID, TNSmlError::ESmlStatusNotExecuted, KNSmlAgentAtomic );
            }
        if ( iDMSequence )
            {
            iStatusToServer->SetStatusCodeToAtomicOrSequenceCmdL( iDMSequenceID, TNSmlError::ESmlStatusNotExecuted, KNSmlAgentSequence );
            }
        } 
    }

// ---------------------------------------------------------
// CNSmlDMCmds::HandleAlertsL
// Handles Alert commands from a server.  
// ---------------------------------------------------------
void CNSmlDMCmds::HandleAlertsL( SmlAlert_t* aAlert, TInt& aStatusId)
	    {
	    TPtr8 alertCode = AlertCode( aAlert );
	    if ( alertCode == KNSmlDMAgentDisplayAlert ||  alertCode == KNSmlDMAgentContinueOrAbortAlert )
	        {
	        if ( !aAlert->itemList )
	            {
	            iStatusToServer->SetStatusCodeL( aStatusId, TNSmlError::ESmlStatusIncompleteCommand );
	            iAgent->Interrupt( TNSmlError::ESmlAlertInvalid, EFalse, EFalse );
	            return;
	            }
	        if ( !aAlert->itemList->item )
	            {
	            iStatusToServer->SetStatusCodeL( aStatusId, TNSmlError::ESmlStatusIncompleteCommand );
	            iAgent->Interrupt( TNSmlError::ESmlAlertInvalid, EFalse, EFalse );
	            return;
	            }

	        if ( alertCode == KNSmlDMAgentDisplayAlert )
	            {
	            HandleDisplayAlertL(aAlert,aStatusId);
	            }
	        else if(alertCode == KNSmlDMAgentContinueOrAbortAlert)
	            {
	            HandleConfirmationAlertL(aAlert,aStatusId);
	            }

	        else //
	            {

	            }
	        }
	    }


// ---------------------------------------------------------
// CNSmlDMCmds::HandleConfirmationAlertL
// Handles Confirmation Alert command from a server.  
// ---------------------------------------------------------	
void CNSmlDMCmds::HandleConfirmationAlertL( SmlAlert_t* aAlert, TInt& aStatusId)
    {    
    // MINDT 
    TInt mindt = AlertParameter( aAlert->itemList->item->data, KNSmlDMAgentMINDT );
    // MAXDT 
    TInt maxdt = AlertParameter( aAlert->itemList->item->data, KNSmlDMAgentMAXDT );
    if ( mindt > maxdt )
        {
        maxdt = mindt;
        }   
    TSyncMLDlgNotifParams notifyParams;
    TInt maxlen = AlertParameter( aAlert->itemList->item->data, KNSmlDMAgentMAXLEN );                                        
    HBufC8* alertData = AlertDataLC( aAlert->itemList );
    if ( alertData->Length() == 0)
        {
        CleanupStack::PopAndDestroy();//alertData
        iStatusToServer->SetStatusCodeL( aStatusId, TNSmlError::ESmlStatusIncompleteCommand );
        HandleAlertErrorL(); 
        return;   
        }
    HBufC8* alertDataWithMDT = HBufC8::NewLC(alertData->Length()+KNSmlDMAgentMINDT().Length()+KNSmlDMAgentMAXDT().Length()+6);
    TPtr8 dataBuf = alertDataWithMDT->Des();
    dataBuf.Append(*alertData);
    HBufC* dataBuf16 = NULL;
    TRAPD(errC,  dataBuf16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(dataBuf));
    if( errC == KErrCorrupt )
        {
        CleanupStack::PopAndDestroy(2); //alertData alertDataWithMDT
        iStatusToServer->SetStatusCodeL( aStatusId, TNSmlError::ESmlStatusCommandFailed );
        return;
        }
    CleanupStack::PushL(dataBuf16);    
   
    TPckgBuf<TBool> resBuf;
    if( dataBuf16->Length() > KSyncMLMaxServerMsgLength )
        {
        notifyParams.iServerMsg = (*dataBuf16).Left(KSyncMLMaxServerMsgLength) ;    
        }
    else
        {
        notifyParams.iServerMsg = *dataBuf16;   
        }     
    notifyParams.iMaxTime = maxdt;
    notifyParams.iMaxLength = maxlen;             
    TRequestStatus status;      
    //Note type to Query note
    notifyParams.iNoteType = ESyncMLYesNoQuery;
    TPckgBuf<TSyncMLDlgNotifParams> pkgBuf(notifyParams);
    
    
    if(!IsHbSyncmlNotifierEnabledL())
    {
    	_DBG_FILE("starting notifier");  

    }
    else
    {
 
    TInt statusval;
    ServerHbNotifierL(notifyParams.iNoteType, notifyParams.iServerMsg);
    TInt err = RProperty::Get(dmagentuid, EHbDMSyncNotifierKeyStatusReturn, statusval);
    	LOGSTRING2("get error status = %d", err);
    	if(err == KErrNone)
    		{
    			status = statusval;
    			LOGSTRING2("get statusval = %d", status.Int());
    		}
 
    }
    
    if (status == KErrCancel || status == KErrTimedOut)
        {
        TInt error = status == KErrCancel ? TNSmlError::ESmlStatusNotModified : TNSmlError::ESmlStatusRequestTimeout;
        iStatusToServer->SetStatusCodeL( aStatusId, error );
        HandleAlertErrorL();
        }
    CleanupStack::PopAndDestroy(3); //alertData alertDataWithMDT,databuf16 
    }

 // ---------------------------------------------------------
 // CNSmlDMCmds::HandleDisplayAlertL
 // Handles Display Alert command from a server.  
 // ---------------------------------------------------------  
 void CNSmlDMCmds::HandleDisplayAlertL( SmlAlert_t* aAlert, TInt& aStatusId)
     {     
     // MINDT 
     TInt mindt = AlertParameter( aAlert->itemList->item->data, KNSmlDMAgentMINDT );
     // MAXDT 
     TInt maxdt = AlertParameter( aAlert->itemList->item->data, KNSmlDMAgentMAXDT );
     if ( mindt > maxdt )
         {
         maxdt = mindt;
         }   
     TSyncMLDlgNotifParams notifyParams;
     TInt maxlen = AlertParameter( aAlert->itemList->item->data, KNSmlDMAgentMAXLEN );
     HBufC8* alertData = AlertDataLC( aAlert->itemList );
     if ( alertData->Length() == 0)
         {
         CleanupStack::PopAndDestroy();//alertData
         iStatusToServer->SetStatusCodeL( aStatusId, TNSmlError::ESmlStatusIncompleteCommand );
         HandleAlertErrorL(); 
         return;   
         }
     HBufC8* alertDataWithMDT = HBufC8::NewLC(alertData->Length()+KNSmlDMAgentMINDT().Length()+KNSmlDMAgentMAXDT().Length()+6);
     TPtr8 dataBuf = alertDataWithMDT->Des();
     dataBuf.Append(*alertData);
     HBufC* dataBuf16 = NULL;
     TRAPD(errC,  dataBuf16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(dataBuf));
     if( errC == KErrCorrupt )
         {
         CleanupStack::PopAndDestroy(2); //alertData alertDataWithMDT
         iStatusToServer->SetStatusCodeL( aStatusId, TNSmlError::ESmlStatusCommandFailed );
         return;
         }
     CleanupStack::PushL(dataBuf16);    
    
     TPckgBuf<TBool> resBuf;
     if( dataBuf16->Length() > KSyncMLMaxServerMsgLength )
         {
         notifyParams.iServerMsg = (*dataBuf16).Left(KSyncMLMaxServerMsgLength) ;    
         }
     else
         {
         notifyParams.iServerMsg = *dataBuf16;   
         }     
     notifyParams.iMaxTime = maxdt;
     notifyParams.iMaxLength = maxlen;     
     TRequestStatus status;              
     notifyParams.iNoteType = ESyncMLInfoNote;
     TPckgBuf<TSyncMLDlgNotifParams> pkgBuf( notifyParams );
    if(!IsHbSyncmlNotifierEnabledL())
        {
     
        }
    else
        {
        LOGSTRING("HandleDisplayAlertL Start test 1 start");  
        ServerHbNotifierL(notifyParams.iNoteType, notifyParams.iServerMsg);
        LOGSTRING("HandleDisplayAlertL Start test 2 end");
        }
    
    CleanupStack::PopAndDestroy(3); //alertData alertDataWithMDT,databuf16   


    }

void CNSmlDMCmds::ServerHbNotifierL(TSyncMLDlgNoteTypes& aNotetype, TDesC& aServerMsg)
    
    {
				LOGSTRING("HandleDisplayAlertL ServerHbNotifier start");                
        RDmDevDialog DmDevdialog;
        TInt err = DmDevdialog.OpenL();
        User::LeaveIfError(err);
        TRequestStatus status = KRequestPending;
        if(aNotetype == ESyncMLInfoNote)
            {
        DmDevdialog.ShowDisplayAlert(aServerMsg,status);
            }
            
        else 
            {
        TInt timeout = 30; // dummy
        TBuf<30> header; // dummy
        DmDevdialog.ShowConfirmationAlert(timeout,header,aServerMsg,status);
            }
       
        User::WaitForRequest(status);

DmDevdialog.Close();
        LOGSTRING("HandleDisplayAlertL ServerHbNotifier end");

}
TBool CNSmlDMCmds::IsHbSyncmlNotifierEnabledL()
    {
    CRepository * rep =
            CRepository::NewLC(KCRUidDeviceManagementInternalKeys);

    TInt notifierenabled = KErrNone;

    TInt err = rep->Get(KDevManEnableHbNotifier, notifierenabled);

    CleanupStack::PopAndDestroy(rep);

    if (err == KErrNone && notifierenabled)
        {
        return ETrue;
        }
    else
        {
        return EFalse;
        }

    }

// ---------------------------------------------------------
// CNSmlDMCmds::ProcessSyncL()
// Process received Add, Replace and Delete commands
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessSyncL( SmlSync_t* /*aSync*/ )
	{
	}

// ---------------------------------------------------------
// CNSmlDMCmds::ProcessUpdatesL()
// Process received Add, Replace and Delete commands
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessUpdatesL( const TDesC8& aCmd, SmlGenericCmd_t* aContent )
	{
	TInt statusID( 0 );
	// cmdID
	if ( aContent->cmdID->length == 0 )
		{
		StatusDataToGenericCommandL( aCmd, aContent, NULL, TNSmlError::ESmlStatusIncompleteCommand );
		iAgent->Interrupt( TNSmlError::ESmlCmdIDMissing, EFalse, EFalse );
		return;
		}
	SmlItemList_t* itemList=0;
	SmlItem_t* item=0;
	HBufC8* uri;
	// FOTA
	/*
	if(aCmd==KNSmlAgentExec())
		{
		item = ((SmlExecPtr_t)aContent)->item;
		}
	else
		{
	*/
		itemList = aContent->itemList;
		item = itemList->item;
	//	}
	// FOTA end	
	
	while ( item )
		{
		TNSmlError::TNSmlSyncMLStatusCode statusCode=TNSmlError::ESmlStatusOK;
		UpdateErrorStatusCode(item,statusCode);

		if(statusCode!=TNSmlError::ESmlStatusOK)
			{
			StatusDataToGenericCommandL( aCmd, aContent, item, statusCode );
			if(itemList)
				{
				itemList = itemList->next;
				if(itemList)
					{
					item=itemList->item;
					}
				else
					{
					item=0;
					}
				}
			else
				{
				item = 0;
				}
			continue;
			}
	
		TPtr8 pcdata( (TUint8*) item->target->locURI->content, item->target->locURI->length, item->target->locURI->length );
		TrimRightSpaceAndNull( pcdata );
		uri = pcdata.AllocLC();	
		CBufBase* dataBuffer = NULL;
		
		//Get the data chunk from the servers message. The data is set to dataBuffer.
		TInt totSizeOfLarge(0);
		statusCode = GetChunkL( *uri, item, aContent->meta, dataBuffer, totSizeOfLarge );
// FOTA		
//		if ( dataBuffer )
//			{
			CleanupStack::PushL( dataBuffer );
//			}
		if ( !(statusCode == TNSmlError::ESmlStatusOK||statusCode == TNSmlError::ESmlStatusItemAccepted ))
			{
			statusID = StatusDataToGenericCommandL( aCmd, aContent, item, statusCode );
			
			// If this was the last chunk and there was a size mismatch, send anyway
			// a null chunk package to HostServer, so that largeObject handling session ends
			// properly.
			if ( statusCode == TNSmlError::ESmlStatusSizeMismatch )
				{
				iDMModule->UpdateObjectL ( *uri, KNullDesC8, KNullDesC8, statusID, iMoreData );					
				}
			}
// FOTA end
			
		else
			{
			if ( dataBuffer )
				{
				TPtr8 objectData( dataBuffer->Ptr(0) );
		
				HBufC8* metaType = MetaTypeInUtf8LC( item->meta );
				if ( metaType->Length() == 0 )
					{
					CleanupStack::PopAndDestroy(); // metaType
					metaType = MetaTypeInUtf8LC( aContent->meta );
					}
				if ( aCmd == KNSmlAgentAdd )
					{
					statusID = StatusDataToGenericCommandL( aCmd, aContent, item, statusCode );
					//Set p& S key to EAddCmd 													        			    
					RProperty::Define(KPSUidNSmlDMSyncAgent,
						KNSmlDMCmdAddOnExistingNodeorLeafKey, RProperty::EInt,
							KReadPolicy, KWritePolicy );					
					RProperty::Set(KPSUidNSmlDMSyncAgent,
							KNSmlDMCmdAddOnExistingNodeorLeafKey, EAddCmd );
					iDMModule->AddObjectL( *uri, objectData, *metaType, statusID,iMoreData ); 
					}
				else if ( aCmd == KNSmlAgentReplace )
					{
					statusID = StatusDataToGenericCommandL( aCmd, aContent, item, statusCode);
					// FOTA
					if ( totSizeOfLarge )
						{
						// The total size of the large object is forwarded only for FOTA adapter.
						iDMModule->UpdateObjectL( *uri, objectData, *metaType, statusID, iMoreData, totSizeOfLarge );											
						}
					else
						{
						iDMModule->UpdateObjectL( *uri, objectData, *metaType, statusID, iMoreData );					
						}
					// FOTA end
					}
				else if ( aCmd == KNSmlAgentDelete )
					{
					statusID = StatusDataToGenericCommandL( aCmd, aContent, item, statusCode);
					iDMModule->DeleteObjectL( *uri, statusID );
					}
				// FOTA
				/*
				if ( aCmd == KNSmlAgentExec )
					{
					statusID = StatusDataToGenericCommandL( aCmd, aContent, item, statusCode);
					iDMModule->ExecuteObjectL( *uri, objectData, *metaType, statusID,iMoreData  );
					}
				*/
				// FOTA end
				else if ( aCmd == KNSmlAgentCopy )
					{
					statusID = StatusDataToGenericCommandL( aCmd, aContent, item, statusCode);
					TPtr8 pcdataSourceUri( (TUint8*) item->source->locURI->content, item->source->locURI->length, item->source->locURI->length );
					TrimRightSpaceAndNull( pcdataSourceUri );

					iDMModule->CopyObjectL( *uri, pcdataSourceUri, *metaType, statusID );
					}
				// FOTA : Pop and destroy for databuffer moved forward
				CleanupStack::PopAndDestroy(); // metaType
				// FOTA end 
				if ( iDMAtomic )
					{
					iStatusToServer->SetAtomicOrSequenceId( statusID, iDMAtomicID );
					}
				}
			}
		// FOTA : Pop and destroy for databuffer added
		CleanupStack::PopAndDestroy(2); // databuffer, uri
		// FOTA end
		if(itemList)
			{
			itemList = itemList->next;
			if(itemList)
				{
				item=itemList->item;
				}
			else
				{
				item=0;
				}
			}
		else
			{
			item = 0;
			}
		}
	}
	
// FOTA
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessExecCmdL()
//	Process the exec structure sent by the remote server.
//	@param aExec. The exec command structure, accordant with the dtd. 
// ---------------------------------------------------------
//
void CNSmlDMCmds::ProcessExecCmdL ( SmlExec_t* aExec )
	{
	if ( aExec->cmdID->length == 0 )
		{
		StatusDataToCommandL ( KNSmlAgentExec, aExec->cmdID, aExec->flags, NULL, TNSmlError::ESmlStatusIncompleteCommand );
		iAgent->Interrupt ( TNSmlError::ESmlCmdIDMissing, EFalse, EFalse );
		return;
		}
	TNSmlError::TNSmlSyncMLStatusCode statusCode ( TNSmlError::ESmlStatusOK );
		
	if ( iAgent->Interrupted() )
		{
		statusCode = TNSmlError::ESmlStatusCommandFailed;
		}
	else if ( iServerAuth->Challenged() )
		{
		statusCode = TNSmlError::ESmlStatusClientAuthenticationRequired;
		}
	else if ( iDMNotExecuted )
		{
		statusCode = TNSmlError::ESmlStatusNotExecuted;
		}
	else if ( !aExec->item->target || !aExec->item->target->locURI )
		{
		statusCode = TNSmlError::ESmlStatusIncompleteCommand;
		}

	if ( statusCode != TNSmlError::ESmlStatusOK )
		{
		StatusDataToCommandL ( KNSmlAgentExec, aExec->cmdID, aExec->flags, aExec->item, statusCode );
		return;
		}
	
	TPtr8 pcdata ( (TUint8*) aExec->item->target->locURI->content, aExec->item->target->locURI->length, aExec->item->target->locURI->length );
	TrimRightSpaceAndNull ( pcdata );
	HBufC8* uri = pcdata.AllocLC();	
	CBufBase* dataBuffer = NULL;
		
	//Get the data chunk from the servers message. The data is set to dataBuffer.
	TInt dummy(0);
	statusCode = GetChunkL ( *uri, aExec->item, aExec->meta, dataBuffer, dummy );
	CleanupStack::PushL( dataBuffer );
	
	if ( !( statusCode == TNSmlError::ESmlStatusOK || statusCode == TNSmlError::ESmlStatusItemAccepted ) )
		{
		StatusDataToCommandL ( KNSmlAgentExec, aExec->cmdID, aExec->flags, aExec->item, statusCode );
		}
	else
		{
		if ( dataBuffer )
			{
			HBufC8* metaType = MetaTypeInUtf8LC( aExec->item->meta );
			if ( metaType->Length() == 0 )
				{
				CleanupStack::PopAndDestroy(); // metaType
				metaType = MetaTypeInUtf8LC ( aExec->meta );
				}
			TInt statusID ( 0 );
			statusID = StatusDataToCommandL ( KNSmlAgentExec, aExec->cmdID, aExec->flags, aExec->item, statusCode );
			if ( aExec->correlator )
				{
				TPtr8 correlator ( (TUint8*) aExec->correlator->content, aExec->correlator->length, aExec->correlator->length );
				TrimRightSpaceAndNull ( correlator );
				HBufC8* execCorrelator = correlator.AllocLC();	
				iDMModule->ExecuteObjectL ( *uri, dataBuffer->Ptr(0), *metaType, statusID, *execCorrelator, iMoreData );
				CleanupStack::PopAndDestroy();  // execCorrelator
				}
			else
				{
				iDMModule->ExecuteObjectL ( *uri, dataBuffer->Ptr(0), *metaType, statusID, KNullDesC8(), iMoreData );				
				}
			CleanupStack::PopAndDestroy(); // metaType
			if ( iDMAtomic )
				{
				iStatusToServer->SetAtomicOrSequenceId ( statusID, iDMAtomicID );
				}
			}
		}
	CleanupStack::PopAndDestroy(2); // databuffer, uri
	}

// FOTA end
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessAtomicL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessAtomicL( SmlAtomic_t* aAtomic )
	{
	TInt statusID = InitStatusToAtomicOrSequenceL( KNSmlAgentAtomic, aAtomic );
	if ( iAgent->Interrupted() )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusCommandFailed );
		return;
		}
	if ( iServerAuth->Challenged() )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusClientAuthenticationRequired );
		return;
		}
	iDMAtomicID++;
	iStatusToServer->SetAtomicOrSequenceId( statusID, iDMAtomicID );
	iDMModule->StartTransactionL();
	iDMAtomic = ETrue;
	}
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessEndAtomicL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessEndAtomicL()
	{
	if ( (!iAgent->Interrupted()) && ( !iServerAuth->Challenged() ) )
		{
		iDMModule->CommitTransactionL();
		}
	iDMAtomic = EFalse;
	if ( !iDMSequence )
		{
		iDMNotExecuted = EFalse;
		}
	}

// ---------------------------------------------------------
// CNSmlDMCmds::ProcessSequenceL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessSequenceL( SmlSequence_t* aSequence )
	{
	TInt statusID = InitStatusToAtomicOrSequenceL( KNSmlAgentSequence, aSequence );
	if ( iAgent->Interrupted() )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusCommandFailed );
		return;
		}
	if ( iServerAuth->Challenged() )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusClientAuthenticationRequired );
		return;
		}
	if ( iDMNotExecuted )
		{
		iStatusToServer->SetStatusCodeL( statusID, TNSmlError::ESmlStatusNotExecuted );
		return;
		}
	iDMSequenceID++;
	iStatusToServer->SetAtomicOrSequenceId( statusID, iDMSequenceID );
	iDMSequence = ETrue;
	}
// ---------------------------------------------------------
// CNSmlDMCmds::ProcessEndSequence()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessEndSequence()
	{
	iDMSequence = EFalse;
	if ( !iDMAtomic )
		{
		iDMNotExecuted = EFalse;
		}
	}

// ---------------------------------------------------------
// CNSmlDMCmds::ProcessEndSync()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::ProcessEndSyncL()
	{
	}

// ---------------------------------------------------------
// CNSmlDMCmds::DoEndMessageL
// Generates end tag of SyncML element and possble final flag in SyncBody 
// and calls Ref.Toolkit parser to generate xml 
// ---------------------------------------------------------
void CNSmlDMCmds::DoEndMessageL( TBool aFinal )  
	{
	TInt ret;
	if ( aFinal )
		{
		ret = iGenerator->smlEndMessage( ETrue );
		}
	else
		{
		ret = iGenerator->smlEndMessage( EFalse );
		}
	if ( ret != KWBXMLGeneratorOk )
		{
		User::Leave( ret );
		}
	}

// ---------------------------------------------------------
// CNSmlDMCmds::EndOfServerMessageL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::EndOfServerMessageL() const
	{
	iDMModule->EndMessageL();
	}



// ---------------------------------------------------------
// CNSmlDMCmds::SetResultsL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::SetResultsL( const TInt aResultsRef, const CBufBase& aObject, const TDesC8& aType, const TDesC8& aFormat,TInt aTotalSize )
	{
	if ( !iDMDevInfoResults )
		{
		if ( iServerMaxObjectSize > 0 && aObject.Size() > iServerMaxObjectSize )
			{
			iLargeObjectTotalSize = 0;
			iBytesSent=0;
			iStatusToServer->SetStatusCodeL( iResultsToServer->StatusID( aResultsRef ), TNSmlError::TNSmlSyncMLStatusCode( TNSmlError::ESmlStatusEntityTooLarge ), ETrue );
			}
		else
			{
			iBytesSent=0;
			iLargeObjectTotalSize = aTotalSize;
			iResultsToServer->AddItemL( aResultsRef, aObject, aType, aFormat );
			}
		}
	else
		{
		iDMDevInfo->iResults = ETrue;
		delete iDMDevInfo->iFormat;
		iDMDevInfo->iFormat = NULL;
		delete iDMDevInfo->iType;
		iDMDevInfo->iType = NULL;
		delete iDMDevInfo->iObject;
		iDMDevInfo->iObject = NULL;
		iDMDevInfo->iFormat = aFormat.AllocL();
		iDMDevInfo->iType = aType.AllocL();
		iDMDevInfo->iObject = CONST_CAST( CBufBase&, aObject ).Ptr(0).AllocL();
		}
	}

// ---------------------------------------------------------
// CNSmlDMCmds::SetStatusL()
// 
// ---------------------------------------------------------
void CNSmlDMCmds::SetStatusL( TInt aStatusRef, TInt aStatusCode )
	{
	if ( !iDMDevInfoResults )
		{
		iStatusToServer->SetStatusCodeL( aStatusRef, aStatusCode );
		/*if ( iDMSequence )
			{
			if ( aStatusCode >= 300 || aStatusCode < 200 ) 
				{
				iDMNotExecuted = ETrue;
				}
			}*/
		if ( iDMAtomic ) 
			{
			if ( aStatusCode >= 300 || aStatusCode < 200 ) 
				{
				iStatusToServer->SetStatusCodeToAtomicOrSequenceCmdL( iDMAtomicID, TNSmlError::ESmlStatusAtomicFailed, KNSmlAgentAtomic );
				}
			}
		}
	if ( ( aStatusCode == TNSmlError::TNSmlSyncMLStatusCode( TNSmlError::ESmlStatusDeviceFull ) ) &&
		 (!iDMDeviceFullWritten ) )
		{
		iAgent->WriteWarningL( -1, TNSmlError::ESmlStatusDeviceFull );
		iDMDeviceFullWritten = ETrue;
		}
	}

// -----------------------------------------------------------------------------
// CNSmlDMCmds::GetChunkL
// Buffer the received item and handles large objects.
// -----------------------------------------------------------------------------
//
TNSmlError::TNSmlSyncMLStatusCode CNSmlDMCmds::GetChunkL(TDesC8& aLargeUri,
	const SmlItem_t* aCurrentItem, 
	const SmlPcdata_t* aMetaInCommand, 
	CBufBase*& aBuffer,
	// FOTA
	TInt& aTotSizeOfLarge 
	// FOTA end
	 )
	{
	iItemSizeInStream = 0;
	TNSmlError::TNSmlSyncMLStatusCode status( TNSmlError::ESmlStatusOK );
	iMoreData = IsFlagSet( aCurrentItem->flags, SmlMoreData_f );
	
	// check that the previously received chunk belongs to the same item
	if ( iAmountReceived != 0 )
		{
		if (iLargeObjectUri&&iLargeObjectUri->Compare(aLargeUri) )
			{
			iAgent->SetEndOfDataAlertRequest();
			delete iRecBuf;
			iRecBuf = NULL;
			delete iLargeObjectUri;
			iLargeObjectUri=NULL;
			iServerLargeObjectSize = 0;
			}
		}
		
	if ( iMoreData && ( iAmountReceived == 0 ) )
		{
		iServerLargeObjectSize = ServerObjectSize( aCurrentItem->meta );
		
		if ( iServerLargeObjectSize == 0 )
			{
			iServerLargeObjectSize = ServerObjectSize( aMetaInCommand );
			}
		// FOTA
		if ( iServerLargeObjectSize == 0 )
			{
			status = TNSmlError::ESmlStatusSizeRequired;			
			}
		// FOTA end
		iItemSizeInStream = iServerLargeObjectSize;	
		// FOTA
		aTotSizeOfLarge = iServerLargeObjectSize;
		// FOTA end
		delete iLargeObjectUri;
		iLargeObjectUri=NULL;
		iLargeObjectUri = aLargeUri.AllocL();
		}
		
	iRecBuf = CBufFlat::NewL( 1 );
	
	// buffer data
	if ( aCurrentItem->data )
		{
		if ( iItemSizeInStream == 0 )
			{
			iItemSizeInStream = aCurrentItem->data->length;
			}
			
		if ( aCurrentItem->data->content )
			{
			TPtr8 data( static_cast<TUint8*>( aCurrentItem->data->content ), aCurrentItem->data->length, aCurrentItem->data->length );
			iRecBuf->InsertL( iRecBuf->Size(), data );
			}
		}
	else
		{
		aBuffer = iRecBuf;
		iRecBuf = NULL;
		return status;
		}
		
	// last / only chunk
	if ( !iMoreData )
		{
		TBool notFirst( iAmountReceived != 0 );
		iAmountReceived += aCurrentItem->data->length;
		
		if ( notFirst && ( iAmountReceived != iServerLargeObjectSize ) )
			{
			status = TNSmlError::ESmlStatusSizeMismatch;
			delete iRecBuf;
			iRecBuf = NULL;
			}

		iAmountReceived = 0;
		}
	// middle chunk
	else
		{
		iAmountReceived += aCurrentItem->data->length;
		// FOTA 
		if ( status == TNSmlError::ESmlStatusOK )
			{
			status = TNSmlError::ESmlStatusItemAccepted;		
			}
		// FOTA end
		}
		
	aBuffer = iRecBuf;
	iRecBuf = NULL;
	
	return status;
	}

// ---------------------------------------------------------
// CNSmlDMCmds::UpdateErrorStatusCode()
//  Updates the status code with proper error
// ---------------------------------------------------------------------------------------------------------------
void CNSmlDMCmds::UpdateErrorStatusCode(SmlItem_t* aItem,
		TNSmlError::TNSmlSyncMLStatusCode& aStatusCode )
	{
	if ( iAgent->Interrupted() )
		{
		aStatusCode = TNSmlError::ESmlStatusCommandFailed;
		}
	if ( iServerAuth->Challenged() )
		{
		aStatusCode = TNSmlError::ESmlStatusClientAuthenticationRequired;
		}
	if ( iDMNotExecuted )
		{
		aStatusCode = TNSmlError::ESmlStatusNotExecuted;
		}
	// target
	if ( !aItem->target||!aItem->target->locURI )
		{
		aStatusCode = TNSmlError::ESmlStatusIncompleteCommand;
		}
	}