mtpfws/mtpfw/dataproviders/dputility/src/cmtpsvccompoundprocessor.cpp
changeset 0 d0791faffa3f
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // mw/remoteconn/mtpfws/mtpfw/dataproviders/dputility/src/cmtpsvccompoundprocessor.cpp
       
    15 
       
    16 #include <mtp/mmtpdataproviderframework.h>
       
    17 
       
    18 #include <mtp/cmtpobjectmetadata.h>
       
    19 #include <mtp/cmtptypefile.h>
       
    20 #include <mtp/cmtptypeobjectinfo.h>
       
    21 #include <mtp/cmtptypeobjectproplist.h>
       
    22 #include <mtp/cmtptypestring.h>
       
    23 #include <mtp/mmtpobjectmgr.h>
       
    24 #include <mtp/mmtpstoragemgr.h>
       
    25 #include <mtp/mtpprotocolconstants.h> 
       
    26 #include <mtp/tmtptypeint128.h>
       
    27 
       
    28 #include "cmtpsvccompoundprocessor.h"
       
    29 #include "mmtpservicedataprovider.h"
       
    30 #include "mmtpsvcobjecthandler.h"
       
    31 
       
    32 #include "cmtpconnection.h"
       
    33 #include "cmtpconnectionmgr.h"
       
    34 #include "mtpsvcdpconst.h"
       
    35 
       
    36 // Class constants.
       
    37 __FLOG_STMT(_LIT8(KComponent,"SvcCompound");)
       
    38 
       
    39 EXPORT_C MMTPRequestProcessor* CMTPSvcCompoundProcessor::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection, MMTPServiceDataProvider& aDataProvider)
       
    40 	{
       
    41 	CMTPSvcCompoundProcessor* self = new (ELeave) CMTPSvcCompoundProcessor(aFramework, aConnection, aDataProvider);
       
    42 	CleanupStack::PushL(self);
       
    43 	self->ConstructL();
       
    44 	CleanupStack::Pop(self);
       
    45 	return self;
       
    46 	}
       
    47 
       
    48 EXPORT_C CMTPSvcCompoundProcessor::~CMTPSvcCompoundProcessor()
       
    49 	{
       
    50 	__FLOG(_L8("~CMTPSvcCompoundProcessor - Entry"));
       
    51 	delete iReceivedObjectMetaData;
       
    52 	delete iObjectInfo;
       
    53 	delete iObjectPropList;
       
    54 	__FLOG(_L8("~CMTPSvcCompoundProcessor - Exit"));
       
    55 	__FLOG_CLOSE; 
       
    56 	}
       
    57 
       
    58 CMTPSvcCompoundProcessor::CMTPSvcCompoundProcessor(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection, MMTPServiceDataProvider& aDataProvider) :
       
    59 	CMTPRequestProcessor(aFramework, aConnection, 0, NULL),
       
    60 	iDataProvider(aDataProvider), iState(EIdle), iIsCommited(EFalse), iIsRollBackHandlerObject(EFalse)
       
    61 	{
       
    62 	}
       
    63 
       
    64 void CMTPSvcCompoundProcessor::ConstructL()
       
    65 	{
       
    66 	__FLOG_OPEN(KMTPSubsystem, KComponent);
       
    67 	__FLOG(_L8("ConstructL - Entry"));
       
    68 	iExpectedSendObjectRequest.SetUint16(TMTPTypeRequest::ERequestOperationCode, EMTPOpCodeSendObject);
       
    69 	iReceivedObjectMetaData = CMTPObjectMetaData::NewL();
       
    70 	iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EDataProviderId, iFramework.DataProviderId());
       
    71 	__FLOG(_L8("ConstructL - Exit"));
       
    72 	}
       
    73 
       
    74 /**
       
    75 Override to match both the SendObjectInfo/SendObjectPropList/UpdateObjectPropList and SendObject requests
       
    76 @param aRequest    The request to match
       
    77 @param aConnection The connection from which the request comes
       
    78 @return ETrue if the processor can handle the request, otherwise EFalse
       
    79 */
       
    80 TBool CMTPSvcCompoundProcessor::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const
       
    81 	{
       
    82 	__FLOG(_L8("Match - Entry"));
       
    83 	TBool result = EFalse;
       
    84 	TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
       
    85 	if ((&iConnection == &aConnection) && 
       
    86 		(operationCode == EMTPOpCodeSendObjectInfo || 
       
    87 		operationCode == EMTPOpCodeSendObject ||
       
    88 		operationCode == EMTPOpCodeUpdateObjectPropList ||
       
    89 		operationCode == EMTPOpCodeSendObjectPropList))
       
    90 		{
       
    91 		result = ETrue;
       
    92 		}
       
    93 	__FLOG(_L8("Match - Exit"));
       
    94 	return result;
       
    95 	}
       
    96 
       
    97 TBool CMTPSvcCompoundProcessor::HasDataphase() const
       
    98 	{
       
    99 	return ETrue;
       
   100 	}
       
   101 
       
   102 /**
       
   103 Verify the request
       
   104 @return EMTPRespCodeOK if request is verified, otherwise one of the error response codes
       
   105 */
       
   106 TMTPResponseCode CMTPSvcCompoundProcessor::CheckRequestL()
       
   107 	{
       
   108 	__FLOG(_L8("CheckRequestL - Entry"));
       
   109 	TMTPResponseCode responseCode = CMTPRequestProcessor::CheckRequestL();
       
   110 	if (EMTPRespCodeOK == responseCode)
       
   111 		{
       
   112 		responseCode = CheckSendingStateL();
       
   113 		if (EMTPRespCodeOK == responseCode)
       
   114 			{
       
   115 			responseCode = CheckRequestParametersL();
       
   116 			}
       
   117 		}
       
   118 	__FLOG_VA((_L8("CheckRequestL - Exit with code: 0x%04X"), responseCode));
       
   119 	return responseCode;
       
   120 	}
       
   121 
       
   122 /**
       
   123 Verify if the SendObject request comes after SendObjectInfo/SendObjectPropList request
       
   124 @return EMTPRespCodeOK if SendObject request comes after a valid SendObjectInfo request, otherwise
       
   125 EMTPRespCodeNoValidObjectInfo
       
   126 */
       
   127 TMTPResponseCode CMTPSvcCompoundProcessor::CheckSendingStateL()
       
   128 	{
       
   129 	__FLOG(_L8("CheckSendingStateL - Entry"));
       
   130 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   131 	iOperationCode = Request().Uint16(TMTPTypeRequest::ERequestOperationCode);
       
   132 	
       
   133 	if (iOperationCode == EMTPOpCodeSendObject)
       
   134 		{
       
   135 		//In ParseRouter everytime SendObject gets resolved then will be removed from Registry
       
   136 		//Right away therefore we need reRegister it here again in case possible cancelRequest
       
   137 		//Against this SendObject being raised.
       
   138 		iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   139 		iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   140 		}
       
   141 
       
   142 	switch (iState)
       
   143 		{
       
   144 		case EIdle:
       
   145 			// Received an orphan SendObject
       
   146 			if (iOperationCode == EMTPOpCodeSendObject)
       
   147 				{
       
   148 				responseCode = EMTPRespCodeNoValidObjectInfo;
       
   149 				__FLOG(_L8("EIdle: Received an orphan SendObject request"));
       
   150 				}
       
   151 			break;
       
   152 		case EObjectInfoSucceed:
       
   153 			// If another SendObjectInfo or SendObjectPropList operation occurs before a SendObject
       
   154 			// operation, the new ObjectInfo or ObjectPropList shall replace the previously held one. 
       
   155 			// If this occurs, any storage or memory space reserved for the object described in the 
       
   156 			// overwritten ObjectInfo or ObjectPropList dataset should be freed before overwriting and 
       
   157 			// allocating the resources for the new data. 
       
   158 			
       
   159 			// Here is for the processor received another SendObjectInfo or SendObjectPropList 
       
   160 			// before a SendObject or process SendObject failed,
       
   161 			if (iOperationCode == EMTPOpCodeSendObjectInfo ||
       
   162 				iOperationCode == EMTPOpCodeSendObjectPropList ||
       
   163 				iOperationCode == EMTPOpCodeUpdateObjectPropList)
       
   164 				{
       
   165 				iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   166 				if (!iIsCommited)
       
   167 					{
       
   168 					// Object Size != 0, need roll back all resource for the new SendInfo request
       
   169 					CMTPSvcCompoundProcessor::RollBackObject(this);
       
   170 					iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObjectMetaData);
       
   171 					}
       
   172 				delete iObjectInfo;
       
   173 				iObjectInfo = NULL;
       
   174 				delete iObjectPropList;
       
   175 				iObjectPropList = NULL;
       
   176 				delete iReceivedObjectMetaData;
       
   177 				iReceivedObjectMetaData = NULL;
       
   178 				iReceivedObjectMetaData = CMTPObjectMetaData::NewL();
       
   179 				iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EDataProviderId, iFramework.DataProviderId());
       
   180 				iObjectHandler = NULL;
       
   181 				iState = EIdle;
       
   182 				// Reset commit state to false
       
   183 				iIsCommited = EFalse;
       
   184 				__FLOG(_L8("EObjectInfoSucceed: Receive send obj info request again, return to EIdle"));
       
   185 				}
       
   186 			break;
       
   187 		default:
       
   188 			User::Leave(KErrGeneral);
       
   189 		}
       
   190 	__FLOG_VA((_L8("CheckSendingStateL - Exit with code: 0x%04X, state: %u"), responseCode, iState));
       
   191 	return responseCode;
       
   192 	}
       
   193 
       
   194 /**
       
   195 Validates the data type for a given property code.
       
   196 @return EMTPRespCodeOK if the parent handle matches the store id, or another MTP response code if not
       
   197 */
       
   198 TMTPResponseCode CMTPSvcCompoundProcessor::CheckRequestParametersL()
       
   199 	{
       
   200 	__FLOG(_L8("CheckRequestParametersL - Entry"));
       
   201 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   202 	
       
   203 	switch (iOperationCode)
       
   204 		{
       
   205 		case EMTPOpCodeSendObject:
       
   206 			{
       
   207 			__FLOG(_L8("Check SendObject request parameters"));
       
   208 			// Check SendObject's session ID
       
   209 			if (iSessionId != iLastSessionID)
       
   210 				{
       
   211 				responseCode = EMTPRespCodeNoValidObjectInfo;
       
   212 				}
       
   213 			else if ((iLastTransactionID + 1) != iTransactionCode)
       
   214 				{
       
   215 				// Check SendObject's transaction ID
       
   216 				responseCode = EMTPRespCodeInvalidTransactionID;
       
   217 				}
       
   218 			break;
       
   219 			}
       
   220 
       
   221 		case EMTPOpCodeSendObjectInfo:
       
   222 			{
       
   223 			__FLOG(_L8("Check SendObjectInfo request parameters"));
       
   224 			responseCode = CheckStoreAndParent();
       
   225 			break;
       
   226 			}
       
   227 			
       
   228 		case EMTPOpCodeSendObjectPropList:
       
   229 			{
       
   230 			__FLOG(_L8("Check SendObjectPropList request parameters"));
       
   231 			responseCode = CheckStoreAndParent();
       
   232 			if (EMTPRespCodeOK == responseCode)
       
   233 				{
       
   234 				// SendObjectPropList need check format code and size in the request
       
   235 				TUint32 objectSizeHigh = Request().Uint32(TMTPTypeRequest::ERequestParameter4);
       
   236 				TUint32 objectSizeLow  = Request().Uint32(TMTPTypeRequest::ERequestParameter5);
       
   237 				iObjectSize = MAKE_TUINT64(objectSizeHigh, objectSizeLow);
       
   238 				
       
   239 				iFormatCode = Request().Uint32(TMTPTypeRequest::ERequestParameter3);
       
   240 				responseCode = CheckFmtAndSetHandler(iFormatCode);
       
   241 				iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EFormatCode, iFormatCode);
       
   242 				}
       
   243 			break;
       
   244 			}
       
   245 
       
   246 		case EMTPOpCodeUpdateObjectPropList:
       
   247 			{
       
   248 			__FLOG(_L8("Check UpdateObjectPropList request parameters"));
       
   249 			TUint32 objectHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   250 			if (objectHandle != KMTPHandleNone)
       
   251 				{
       
   252 				// Find the updating object information
       
   253 				MMTPObjectMgr& objects(iFramework.ObjectMgr());
       
   254 				if (objects.ObjectL(objectHandle, *iReceivedObjectMetaData))
       
   255 					{
       
   256 					iFormatCode = iReceivedObjectMetaData->Uint(CMTPObjectMetaData::EFormatCode);
       
   257 					if (iReceivedObjectMetaData->Uint(CMTPObjectMetaData::EDataProviderId) != iFramework.DataProviderId())
       
   258 						{
       
   259 						responseCode = EMTPRespCodeInvalidObjectHandle;
       
   260 						}
       
   261 					else
       
   262 						{
       
   263 						responseCode = CheckFmtAndSetHandler(iFormatCode);
       
   264 						}
       
   265 					}
       
   266 				else
       
   267 					{
       
   268 					responseCode = EMTPRespCodeInvalidObjectHandle;
       
   269 					}
       
   270 				}
       
   271 			else
       
   272 				{
       
   273 				responseCode = EMTPRespCodeInvalidObjectHandle;
       
   274 				}
       
   275 			break;
       
   276 			}
       
   277 			
       
   278 		default:
       
   279 			// Unexpected operation code
       
   280 			responseCode = EMTPRespCodeOperationNotSupported;
       
   281 			break;
       
   282 		}
       
   283 	__FLOG_VA((_L8("CheckRequestParametersL exit with code: 0x%x"), responseCode));
       
   284 	return responseCode;
       
   285 	}
       
   286 
       
   287 /**
       
   288 Validates the data type for a given property code.
       
   289 @return EMTPRespCodeOK if the parent handle matches the store id, or another MTP response code if not
       
   290 */
       
   291 TMTPResponseCode CMTPSvcCompoundProcessor::CheckStoreAndParent()
       
   292 	{
       
   293 	__FLOG(_L8("CheckStoreAndParent - Entry"));
       
   294 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   295 	iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   296 	iParentHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter2);
       
   297 	
       
   298 	// If the first parameter is unused, it should be set to 0x00000000, and the responder should decide
       
   299 	// in which store to place the object
       
   300 	if (iStorageId == KMTPStorageDefault)
       
   301 		{
       
   302 		// If the second parameter is used, the first parameter must also be used.
       
   303 		// If the second parameter is unused, it should be set to 0x00000000
       
   304 		if (iParentHandle != KMTPHandleNone)
       
   305 			{
       
   306 			responseCode = EMTPRespCodeInvalidParentObject;
       
   307 			}
       
   308 		else
       
   309 			{
       
   310 			// Set storage id as service dp's logical storage id.
       
   311 			iStorageId = iDataProvider.StorageId();
       
   312 			}
       
   313 		}
       
   314 	else
       
   315 		{
       
   316 		// Check logical storage id.
       
   317 		if (iStorageId != iDataProvider.StorageId())
       
   318 			{
       
   319 			responseCode = EMTPRespCodeInvalidStorageID;
       
   320 			}
       
   321 		}
       
   322 	
       
   323 	__FLOG_VA((_L8("CheckStoreAndParent - Exit with code: 0x%x"), responseCode));
       
   324 	return responseCode;
       
   325 	}
       
   326 
       
   327 /**
       
   328 SendObjectInfo/SendObjectPropList/UpdateObjectPropList/SendObject request handler
       
   329 To maintain the state information between the two requests, the two requests are 
       
   330 combined together in one request processor.
       
   331 */
       
   332 void CMTPSvcCompoundProcessor::ServiceL()
       
   333 	{
       
   334 	__FLOG(_L8("ServiceL - Entry"));
       
   335 	switch (iState)
       
   336 		{
       
   337 		case EIdle:
       
   338 			ServiceObjectPropertiesL();
       
   339 			break;
       
   340 		case EObjectInfoSucceed:
       
   341 			ServiceSendObjectL();
       
   342 			break;
       
   343 		default:
       
   344 			__FLOG(_L8("Wrong state in ServiceL"));
       
   345 			break;
       
   346 		}
       
   347 	__FLOG(_L8("ServiceL - Exit"));
       
   348 	}
       
   349 
       
   350 void CMTPSvcCompoundProcessor::ServiceObjectPropertiesL()
       
   351 	{
       
   352 	__FLOG(_L8("ServiceObjectPropertiesL - Entry"));
       
   353 	switch (iOperationCode)
       
   354 		{
       
   355 		case EMTPOpCodeSendObjectInfo:
       
   356 			ServiceSendObjectInfoL();
       
   357 			break;
       
   358 		
       
   359 		case EMTPOpCodeSendObjectPropList:
       
   360 		case EMTPOpCodeUpdateObjectPropList:
       
   361 			ServiceSendObjectPropListL();
       
   362 			break;
       
   363 		default:
       
   364 			break;
       
   365 		}
       
   366 	__FLOG(_L8("ServiceObjectPropertiesL - Exit"));
       
   367 	}
       
   368 
       
   369 /**
       
   370 SendObject request handler
       
   371 */
       
   372 void CMTPSvcCompoundProcessor::ServiceSendObjectL()
       
   373 	{
       
   374 	__FLOG(_L8("ServiceSendObjectL - Entry"));
       
   375 	MMTPSvcObjectHandler* pHandler = iDataProvider.ObjectHandler(iFormatCode);
       
   376 	if (pHandler)
       
   377 		{
       
   378 		pHandler->GetBufferForSendObjectL(*iReceivedObjectMetaData, &iObjectContent);
       
   379 		}
       
   380 	else
       
   381 		{
       
   382 		User::Leave(KErrGeneral);
       
   383 		}
       
   384 	ReceiveDataL(*iObjectContent);
       
   385 	iState = EObjectSendProcessing;
       
   386 	__FLOG(_L8("ServiceSendObjectL - Exit"));
       
   387 	}
       
   388 
       
   389 /**
       
   390 SendObjectInfo request handler
       
   391 */
       
   392 void CMTPSvcCompoundProcessor::ServiceSendObjectInfoL()
       
   393 	{
       
   394 	__FLOG(_L8("ServiceSendObjectInfoL - Entry"));
       
   395 	delete iObjectInfo;
       
   396 	iObjectInfo = NULL;
       
   397 	iObjectInfo = CMTPTypeObjectInfo::NewL();
       
   398 	ReceiveDataL(*iObjectInfo);
       
   399 	iState = EObjectInfoProcessing;
       
   400 	__FLOG(_L8("ServiceSendObjectInfoL - Exit"));
       
   401 	}
       
   402 
       
   403 /**
       
   404 SendObjectPropList request handler
       
   405 */
       
   406 void CMTPSvcCompoundProcessor::ServiceSendObjectPropListL()
       
   407 	{
       
   408 	__FLOG(_L8("ServiceSendObjectPropListL - Entry"));
       
   409 	delete iObjectPropList;
       
   410 	iObjectPropList = NULL;
       
   411 	iObjectPropList = CMTPTypeObjectPropList::NewL();
       
   412 	ReceiveDataL(*iObjectPropList);
       
   413 	iState = EObjectInfoProcessing;
       
   414 	__FLOG(_L8("ServiceSendObjectPropListL - Exit"));
       
   415 	}
       
   416 
       
   417 /**
       
   418 Override to handle the response phase of SendObjectInfo/SendObjectPropList and SendObject requests
       
   419 @return EFalse
       
   420 */
       
   421 TBool CMTPSvcCompoundProcessor::DoHandleResponsePhaseL()
       
   422 	{
       
   423 	__FLOG(_L8("DoHandleResponsePhaseL - Entry"));
       
   424 	TBool successful = !iCancelled;
       
   425 	switch (iState)
       
   426 		{
       
   427 		case EObjectInfoProcessing:
       
   428 			{
       
   429 			if (iOperationCode == EMTPOpCodeSendObjectInfo)
       
   430 				{
       
   431 				successful = DoHandleResponseSendObjectInfoL();
       
   432 				}
       
   433 			else if (iOperationCode == EMTPOpCodeSendObjectPropList)
       
   434 				{
       
   435 				successful = DoHandleResponseSendObjectPropListL();
       
   436 				}
       
   437 			else if (iOperationCode == EMTPOpCodeUpdateObjectPropList)
       
   438 				{
       
   439 				successful = DoHandleResponseUpdateObjectPropListL();
       
   440 				}
       
   441 			iState = (successful ? EObjectInfoSucceed : EIdle);
       
   442 			break;
       
   443 			}
       
   444 		case EObjectSendProcessing:
       
   445 			{
       
   446 			successful = DoHandleResponseSendObjectL();
       
   447 			iState = (successful ? EObjectSendSucceed : EObjectSendFail);
       
   448 			break;
       
   449 			}
       
   450 		default:
       
   451 			// Wrong State value.
       
   452 			__FLOG_VA((_L8("DoHandleResponsePhaseL enter an abnormal state %d"), iState));
       
   453 			break;
       
   454 		}
       
   455 	__FLOG(_L8("DoHandleResponsePhaseL - Exit"));
       
   456 	return EFalse;
       
   457 	}
       
   458 
       
   459 /**
       
   460 Override to handle the completing phase of SendObjectInfo/SendObjectPropList and SendObject requests
       
   461 @return ETrue if succesfully received the object content, otherwise EFalse
       
   462 */
       
   463 TBool CMTPSvcCompoundProcessor::DoHandleCompletingPhaseL()
       
   464 	{
       
   465 	__FLOG(_L8("DoHandleCompletingPhaseL - Entry"));
       
   466 	TBool result = ETrue;
       
   467 	CMTPRequestProcessor::DoHandleCompletingPhaseL();
       
   468 	
       
   469 	__FLOG_VA((_L8("DoHandleCompletingPhaseL - Progress State: %u"), iState));
       
   470 	switch (iState)
       
   471 		{
       
   472 		case EObjectInfoSucceed:
       
   473 			{
       
   474 			// Two cases will come here:
       
   475 			// 1. SendObjInfo OK, Store ID for next SendObject checking;
       
   476 			// 2. SendObject check request fail, such as wrong transaction id or wrong session id.
       
   477 			//    needn't change transaction id.
       
   478 			if (iOperationCode == EMTPOpCodeSendObjectInfo || 
       
   479 				iOperationCode == EMTPOpCodeUpdateObjectPropList ||
       
   480 				iOperationCode == EMTPOpCodeSendObjectPropList)
       
   481 				{
       
   482 				// Reset transaction id for new SendObjInfo request, but ignore wrong SendObject.
       
   483 				iLastTransactionID = iTransactionCode;
       
   484 				iLastSessionID = iSessionId;
       
   485 				iLastInfoOperationCode = iOperationCode;
       
   486 				}
       
   487 			result = EFalse;
       
   488 			__FLOG_VA((_L8("EObjectInfoSucceed: Save send info transaction id: %u, operation: 0x%x"), iLastTransactionID, iOperationCode));
       
   489 			break;
       
   490 			}
       
   491 		case EObjectSendFail:
       
   492 			{
       
   493 			// When process SendObject fail, such as received size is wrong.
       
   494 			iLastTransactionID++;
       
   495 			iState = EObjectInfoSucceed;
       
   496 			result = EFalse;
       
   497 			break;
       
   498 			}
       
   499 		default:
       
   500 			// The other cases will delete the processor:
       
   501 			// 1. SendObject OK
       
   502 			// 2. Framework error and call complete with error state.
       
   503 			// 3. SendObjInfo fail
       
   504 			// 4. First request is orphan SendObject, state is Idle
       
   505 			break;
       
   506 		}
       
   507 	__FLOG(_L8("DoHandleCompletingPhaseL - Exit"));
       
   508 	return result;
       
   509 	}
       
   510 
       
   511 /**
       
   512 Handling the completing phase of SendObjectInfo request
       
   513 @return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
       
   514 */
       
   515 TBool CMTPSvcCompoundProcessor::DoHandleResponseSendObjectInfoL()
       
   516 	{
       
   517 	__FLOG(_L8("DoHandleResponseSendObjectInfoL - Entry"));
       
   518 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   519 	TBool result(ETrue);
       
   520 	iFormatCode = iObjectInfo->Uint16L(CMTPTypeObjectInfo::EObjectFormat);
       
   521 	// Check format code and set object handler
       
   522 	responseCode = CheckFmtAndSetHandler(iFormatCode);
       
   523 	if (responseCode != EMTPRespCodeOK)
       
   524 		{
       
   525 		SendResponseL(responseCode);
       
   526 		}
       
   527 	else
       
   528 		{
       
   529 		iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EFormatCode, iFormatCode);
       
   530 		iObjectSize = iObjectInfo->Uint32L(CMTPTypeObjectInfo::EObjectCompressedSize);
       
   531 		
       
   532 		TBuf<KMaxSUIDLength> suid;
       
   533 		// Object mgr process dataset and create a temp object.
       
   534 		responseCode = iObjectHandler->SendObjectInfoL(*iObjectInfo, iParentHandle, suid);
       
   535 		if (responseCode != EMTPRespCodeOK)
       
   536 			{
       
   537 			SendResponseL(responseCode);
       
   538 			}
       
   539 		else
       
   540 			{
       
   541 			//if object size is zero, then directly store object without waiting for sendobject operation.
       
   542 			if (iObjectSize == 0)
       
   543 				{
       
   544 				__FLOG(_L8("CommitReservedObject because object size is 0 and register for SendObject"));
       
   545 				// Commit new temp object to object mgr, if leave, CleanupStack will rollback new temp object. 
       
   546 				TCleanupItem rollBackTempObject(RollBackObject, this);
       
   547 				CleanupStack::PushL(rollBackTempObject);
       
   548 				// Commit prop to obj mgr
       
   549 				iObjectHandler->CommitForNewObjectL(suid);
       
   550 				CleanupStack::Pop(this);
       
   551 	
       
   552 				// Prepare to store the created object to framework
       
   553 				iIsRollBackHandlerObject = ETrue;
       
   554 				TCleanupItem rollBackTempObjectAndSuid(RollBackObject, this);
       
   555 				CleanupStack::PushL(rollBackTempObjectAndSuid);
       
   556 				// Set the created suid to meta
       
   557 				iReceivedObjectMetaData->SetDesCL(CMTPObjectMetaData::ESuid, suid);
       
   558 				// An object handle issued during a successful SendObjectInfo or SendObjectPropList operation should 
       
   559 				// be reserved for the duration of the MTP session
       
   560 				ReserveObjectL();
       
   561 				// Commit the created object to framework, if leave, then framework will return General Error
       
   562 				// CleanupStack will rollback the new created object via delete object operation.
       
   563 				iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObjectMetaData);
       
   564 				CleanupStack::Pop(this);
       
   565 				iIsRollBackHandlerObject = EFalse;
       
   566 				iIsCommited = ETrue;
       
   567 				RegisterRequestAndSendResponseL(responseCode);
       
   568 				}
       
   569 			else
       
   570 				{
       
   571 				// An object handle issued during a successful SendObjectInfo or SendObjectPropList operation should 
       
   572 				// be reserved for the duration of the MTP session
       
   573 				ReserveObjectL();
       
   574 				RegisterRequestAndSendResponseL(responseCode);
       
   575 				}
       
   576 			}
       
   577 		}
       
   578 	result = (responseCode == EMTPRespCodeOK) ? ETrue : EFalse;
       
   579 	__FLOG_VA((_L8("DoHandleResponseSendObjectInfoL exit with code: 0x%x"), responseCode));
       
   580 	return result;
       
   581 	}
       
   582 
       
   583 /**
       
   584 Handling the completing phase of SendObjectPropList request
       
   585 @return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
       
   586 */
       
   587 TBool CMTPSvcCompoundProcessor::DoHandleResponseSendObjectPropListL()
       
   588 	{
       
   589 	__FLOG(_L8("DoHandleResponseSendObjectPropListL - Entry"));
       
   590 	TBool result = ETrue;
       
   591 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   592 	
       
   593 	TBuf<KMaxSUIDLength> suid;
       
   594 	TUint32 parameter = 0;
       
   595 	responseCode = SendObjectPropListL(*iObjectPropList, iParentHandle, parameter, suid, iObjectSize);
       
   596 	if (responseCode != EMTPRespCodeOK)
       
   597 		{
       
   598 		SendResponseL(responseCode, 4, &parameter);
       
   599 		}
       
   600 	else
       
   601 		{
       
   602 		//if object size is zero, then directly store object without waiting for sendobject operation.
       
   603 		if (iObjectSize == 0)
       
   604 			{
       
   605 			__FLOG(_L8("CommitReservedObject because object size is 0 and register for SendObject"));
       
   606 			// Commit new temp object to object mgr, if leave, CleanupStack will rollback new temp object. 
       
   607 			TCleanupItem rollBackTempObject(RollBackObject, this);
       
   608 			CleanupStack::PushL(rollBackTempObject);
       
   609 			// Commit prop to obj mgr
       
   610 			iObjectHandler->CommitForNewObjectL(suid);
       
   611 			CleanupStack::Pop(this);
       
   612 
       
   613 			// Prepare to store the created object to framework
       
   614 			iIsRollBackHandlerObject = ETrue;
       
   615 			TCleanupItem rollBackTempObjectAndSuid(RollBackObject, this);
       
   616 			CleanupStack::PushL(rollBackTempObjectAndSuid);
       
   617 			// Set the created suid to meta
       
   618 			iReceivedObjectMetaData->SetDesCL(CMTPObjectMetaData::ESuid, suid);
       
   619 			// An object handle issued during a successful SendObjectInfo or SendObjectPropList operation should 
       
   620 			// be reserved for the duration of the MTP session
       
   621 			ReserveObjectL();
       
   622 			// Commit the created object to framework, if leave, then framework will return General Error
       
   623 			// CleanupStack will rollback the new created object via delete object operation.
       
   624 			iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObjectMetaData);
       
   625 			CleanupStack::Pop(this);
       
   626 			iIsRollBackHandlerObject = EFalse;
       
   627 			iIsCommited = ETrue;
       
   628 			RegisterRequestAndSendResponseL(responseCode);
       
   629 			}
       
   630 		else
       
   631 			{
       
   632 			// An object handle issued during a successful SendObjectInfo or SendObjectPropList operation should 
       
   633 			// be reserved for the duration of the MTP session
       
   634 			ReserveObjectL();
       
   635 			RegisterRequestAndSendResponseL(responseCode);
       
   636 			}
       
   637 		}
       
   638 
       
   639 	result = (responseCode == EMTPRespCodeOK) ? ETrue : EFalse;
       
   640 	__FLOG_VA((_L8("DoHandleResponseSendObjectPropListL exit with code = 0x%x"), responseCode));
       
   641 	return result;
       
   642 	}
       
   643 
       
   644 /**
       
   645 Handling the completing phase of UpdateObjectPropList request
       
   646 @return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
       
   647 */
       
   648 TBool CMTPSvcCompoundProcessor::DoHandleResponseUpdateObjectPropListL()
       
   649 	{
       
   650 	__FLOG(_L8("DoHandleResponseUpdateObjectPropListL - Entry"));
       
   651 	TBool result = ETrue;
       
   652 	TUint32 parameter = 0;
       
   653 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   654 	// Check object size property with format
       
   655 	responseCode = ExtractObjectSizeL();
       
   656 	if (responseCode == EMTPRespCodeOK)
       
   657 		{
       
   658 		responseCode = UpdateObjectPropListL(*iReceivedObjectMetaData, *iObjectPropList, parameter);
       
   659 		}
       
   660 
       
   661 	if (responseCode == EMTPRespCodeOK)
       
   662 		{
       
   663 		if (iObjectSize == 0)
       
   664 			{
       
   665 			// If commit leave, roll back the temp object.
       
   666 			TCleanupItem rollBackTempObject(RollBackObject, this);
       
   667 			CleanupStack::PushL(rollBackTempObject);
       
   668 			// Commit prop to obj mgr
       
   669 			iObjectHandler->CommitL();
       
   670 			CleanupStack::Pop(this);
       
   671 			// Commit to obj mgr is ok
       
   672 			iIsCommited = ETrue;
       
   673 			// Update operation needn't change framework property so far.
       
   674 			iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   675 			iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   676 			}
       
   677 		else
       
   678 			{
       
   679 			iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   680 			iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   681 			}
       
   682 		}
       
   683 	SendResponseL(responseCode, 1, &parameter);
       
   684 	result = (responseCode == EMTPRespCodeOK) ? ETrue: EFalse;
       
   685 	__FLOG_VA((_L8("DoHandleResponseUpdateObjectPropListL exit with code: 0x%x"), responseCode));
       
   686 	return result;
       
   687 	}
       
   688 
       
   689 /**
       
   690 Handling the completing phase of SendObject request
       
   691 @return ETrue if the object has been successfully saved on the device, otherwise, EFalse
       
   692 */
       
   693 TBool CMTPSvcCompoundProcessor::DoHandleResponseSendObjectL()
       
   694 	{
       
   695 	__FLOG(_L8("DoHandleResponseSendObjectL - Entry"));
       
   696 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   697 	TBool result = ETrue;
       
   698 
       
   699 	if (iCancelled)
       
   700 		{
       
   701 		iObjectHandler->RollBack();
       
   702 		responseCode = EMTPRespCodeTransactionCancelled;
       
   703 		}
       
   704 	else if (iObjectSize != 0)
       
   705 		{
       
   706 		// For 0 sized object, ignore the object content verify
       
   707 		TUint64 receiveSize = iObjectContent->Size();
       
   708 		if (iObjectSize < receiveSize)
       
   709 			{
       
   710 			// If the object sent in the data phase of this operation is larger than 
       
   711 			// the size indicated in the ObjectInfo dataset sent in the SendObjectInfo 
       
   712 			// which precedes this operation, this operation should fail and a response 
       
   713 			// code of Store_Full should be returned.
       
   714 			responseCode = EMTPRespCodeStoreFull;
       
   715 			}
       
   716 		else if (iObjectSize > receiveSize)
       
   717 			{
       
   718 			responseCode = EMTPRespCodeIncompleteTransfer;
       
   719 			}
       
   720 		// If size is ok, then just need commit the object to data store.
       
   721 		}
       
   722 	
       
   723 	// Commit or Unreserver from framework if object size is not 0.
       
   724 	if (responseCode == EMTPRespCodeOK && iObjectSize != 0)
       
   725 		{
       
   726 		// For create new object, need commit the reserved handle to framework, but update needn't do that
       
   727 		if (iLastInfoOperationCode != EMTPOpCodeUpdateObjectPropList)
       
   728 			{
       
   729 			TBuf<KMaxSUIDLength> suid;
       
   730 			// Commit new temp object to object mgr, if leave, CleanupStack will rollback new temp object. 
       
   731 			TCleanupItem rollBackTempObject(RollBackObject, this);
       
   732 			CleanupStack::PushL(rollBackTempObject);
       
   733 			// Commit prop to obj mgr
       
   734 			iObjectHandler->CommitForNewObjectL(suid);
       
   735 			CleanupStack::Pop(this);
       
   736 
       
   737 			// Prepare to store the created object to framework
       
   738 			iIsRollBackHandlerObject = ETrue;
       
   739 			TCleanupItem rollBackTempObjectAndSuid(RollBackObject, this);
       
   740 			CleanupStack::PushL(rollBackTempObjectAndSuid);
       
   741 			// Set the created suid to meta
       
   742 			iReceivedObjectMetaData->SetDesCL(CMTPObjectMetaData::ESuid, suid);
       
   743 			// Commit the created object to framework, if leave, then framework will return General Error
       
   744 			// CleanupStack will rollback the new created object via delete object operation.
       
   745 			iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObjectMetaData);
       
   746 			CleanupStack::Pop(this);
       
   747 			iIsRollBackHandlerObject = EFalse;
       
   748 			iIsCommited = ETrue;
       
   749 			}
       
   750 		else
       
   751 			{
       
   752 			// If commit leave, roll back the temp object.
       
   753 			TCleanupItem rollBackNewObject(RollBackObject, this);
       
   754 			CleanupStack::PushL(rollBackNewObject);
       
   755 			// Commit prop to obj mgr
       
   756 			iObjectHandler->CommitL();
       
   757 			CleanupStack::Pop(this);
       
   758 			// Commit to obj mgr is ok
       
   759 			iIsCommited = ETrue;
       
   760 			}
       
   761 		}
       
   762 
       
   763 	SendResponseL(responseCode);
       
   764 	// Release the processor when SendObject or Transaction Canceled and unregister SendObject.
       
   765 	result = (responseCode == EMTPRespCodeOK || responseCode == EMTPRespCodeTransactionCancelled) ? ETrue : EFalse;
       
   766 	if (result)
       
   767 		{
       
   768 		iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   769 		}
       
   770 	__FLOG_VA((_L8("DoHandleResponseSendObjectL exit with code = 0x%x"), responseCode));
       
   771 	return result;
       
   772 	}
       
   773 
       
   774 TMTPResponseCode CMTPSvcCompoundProcessor::ExtractObjectSizeL()
       
   775 	{
       
   776 	__FLOG(_L8("ExtractObjectSizeL - Entry"));
       
   777 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   778 	TBool foundSizeProp  = EFalse;
       
   779 	const TUint KCount(iObjectPropList->NumberOfElements());
       
   780 	iObjectPropList->ResetCursor();
       
   781 	for (TUint i = 0; i < KCount; i++)
       
   782 		{
       
   783 		const CMTPTypeObjectPropListElement& KElement = iObjectPropList->GetNextElementL();
       
   784 		if (EMTPObjectPropCodeObjectSize == KElement.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode))
       
   785 			{
       
   786 			iObjectSize = KElement.Uint64L(CMTPTypeObjectPropListElement::EValue);
       
   787 			foundSizeProp = ETrue;
       
   788 			break;
       
   789 			}
       
   790 		}
       
   791 	
       
   792 	if (!foundSizeProp)
       
   793 		{
       
   794 		// Object size in data set is not available, get the corresponding object's current size property.
       
   795 		const TDesC& suid = iReceivedObjectMetaData->DesC(CMTPObjectMetaData::ESuid);
       
   796 		responseCode = iObjectHandler->GetObjectSizeL(suid, iObjectSize);
       
   797 		if (iObjectSize == KObjectSizeNotAvaiable)
       
   798 			{
       
   799 			responseCode = EMTPRespCodeGeneralError;
       
   800 			}
       
   801 		}
       
   802 
       
   803 	__FLOG(_L8("ExtractObjectSizeL - Exit"));
       
   804 	return responseCode;
       
   805 	}
       
   806 
       
   807 /**
       
   808 Reserves space for and assigns an object handle to the received object, then
       
   809 sends a success response.
       
   810 */
       
   811 void CMTPSvcCompoundProcessor::ReserveObjectL()
       
   812 	{
       
   813 	__FLOG(_L8("ReserveObjectL - Entry"));
       
   814 	iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
       
   815 	iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EParentHandle, iParentHandle);
       
   816 	iReceivedObjectMetaData->SetUint(CMTPObjectMetaData::EFormatCode, iFormatCode);
       
   817 	iFramework.ObjectMgr().ReserveObjectHandleL(*iReceivedObjectMetaData, iObjectSize);
       
   818 	__FLOG_VA((_L8("ReserveObjectL Exit Storage:%u, ParentHandle:%u, FormatCode:%u, Size:%u "), iStorageId, iParentHandle, iFormatCode, iObjectSize));
       
   819 	}
       
   820 
       
   821 void CMTPSvcCompoundProcessor::RegisterRequestAndSendResponseL(TMTPResponseCode aResponseCode)
       
   822 	{
       
   823 	__FLOG(_L8("RegisterRequestAndSendResponseL - Entry"));
       
   824 	// Register to framework for handle the next sendobj request
       
   825 	iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   826 	iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   827 	TUint32 parameters[3];
       
   828 	parameters[0] = iStorageId;
       
   829 	parameters[1] = iParentHandle;
       
   830 	// Responder’s reserved ObjectHandle for the incoming object
       
   831 	parameters[2] = iReceivedObjectMetaData->Uint(CMTPObjectMetaData::EHandle);
       
   832 	SendResponseL(aResponseCode, 3, parameters);
       
   833 	__FLOG(_L8("RegisterRequestAndSendResponseL - Exit"));
       
   834 	}
       
   835 
       
   836 void CMTPSvcCompoundProcessor::RollBackObject(TAny* aObject)
       
   837 	{
       
   838 	reinterpret_cast<CMTPSvcCompoundProcessor*>(aObject)->RollBack();
       
   839 	}
       
   840 
       
   841 void CMTPSvcCompoundProcessor::RollBack()
       
   842 	{
       
   843 	iObjectHandler->RollBack();
       
   844 	if (iIsRollBackHandlerObject)
       
   845 		{
       
   846 		TRAP_IGNORE(iObjectHandler->DeleteObjectL(*iReceivedObjectMetaData));
       
   847 		iIsRollBackHandlerObject = EFalse;
       
   848 		}
       
   849 	}
       
   850 
       
   851 TMTPResponseCode CMTPSvcCompoundProcessor::CheckFmtAndSetHandler(TUint32 aFormatCode)
       
   852 	{
       
   853 	__FLOG(_L8("CheckFmtAndSetHandler - Entry")); 
       
   854 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   855 	iObjectHandler = iDataProvider.ObjectHandler(aFormatCode);
       
   856 	if (!iObjectHandler)
       
   857 		{
       
   858 		responseCode = EMTPRespCodeInvalidObjectFormatCode;
       
   859 		}
       
   860 	__FLOG(_L8("CheckFmtAndSetHandler - Exit"));
       
   861 	return responseCode;
       
   862 	}
       
   863 
       
   864 TMTPResponseCode CMTPSvcCompoundProcessor::SendObjectPropListL(const CMTPTypeObjectPropList& aObjectPropList, TUint32& aParentHandle, 
       
   865 														TUint32& aParameter, TDes& aSuid, TUint64 aObjectSize)
       
   866 	{
       
   867 	__FLOG(_L8("SendObjectPropListL - Entry"));
       
   868 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   869 	aParameter = 0;
       
   870 
       
   871 	responseCode = iObjectHandler->SendObjectPropListL(aObjectSize, aObjectPropList, aParentHandle, aSuid);
       
   872 	// If handler cache an entry in SendObjectPropList, then it should never return error code. Processor will 
       
   873 	// not rollback in this case
       
   874 	if (EMTPRespCodeOK == responseCode)
       
   875 		{
       
   876 		// Parse elements and set property for the object.
       
   877 		const TUint count(aObjectPropList.NumberOfElements());
       
   878 		aObjectPropList.ResetCursor();
       
   879 		for (TUint i = 0; i < count && responseCode == EMTPRespCodeOK; i++)
       
   880 			{
       
   881 			CMTPTypeObjectPropListElement& element = aObjectPropList.GetNextElementL();
       
   882 			TUint32 handle = element.Uint32L(CMTPTypeObjectPropListElement::EObjectHandle);
       
   883 			// All ObjectHandle fields must contain the value 0x00000000, and all properties that are defined in 
       
   884 			// this operation will be applied to the object, need check every handle value and keep all properties is atomic.
       
   885 			if (handle != KMTPHandleNone)
       
   886 				{
       
   887 				responseCode = EMTPRespCodeInvalidDataset;
       
   888 				aParameter = i;
       
   889 				break;
       
   890 				}
       
   891 			else
       
   892 				{
       
   893 				// Create a new object, don't commit, it will be done in processor.
       
   894 				responseCode = iObjectHandler->SetObjectPropertyL(aSuid, element, EMTPOpCodeSendObjectPropList);
       
   895 				}
       
   896 			if (responseCode != EMTPRespCodeOK)
       
   897 				{
       
   898 				aParameter = i;
       
   899 				break;
       
   900 				}
       
   901 			}
       
   902 		// Roll back the temp object
       
   903 		if (EMTPRespCodeOK != responseCode)
       
   904 			{
       
   905 			iObjectHandler->RollBack();
       
   906 			}
       
   907 		}
       
   908 	__FLOG_VA((_L8("SendObjectPropListL - Exit with responseCode = 0x%04X"), responseCode));
       
   909 	return responseCode;
       
   910 	}
       
   911 
       
   912 // All object handlers current don't support partial update, so once update one parameter failed,
       
   913 // all updated will be reverted.
       
   914 TMTPResponseCode CMTPSvcCompoundProcessor::UpdateObjectPropListL(CMTPObjectMetaData& aObjectMetaData, 
       
   915 														const CMTPTypeObjectPropList& aObjectPropList, 
       
   916 														TUint32& /*aParameter*/)
       
   917 	{
       
   918 	__FLOG(_L8("UpdateObjectPropList - Entry")); 
       
   919 	TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   920 	const TUint count = aObjectPropList.NumberOfElements();
       
   921 	aObjectPropList.ResetCursor();
       
   922 	for (TUint i = 0; i < count; i++)
       
   923 		{
       
   924 		CMTPTypeObjectPropListElement& element = aObjectPropList.GetNextElementL();
       
   925 		TUint32 handle = element.Uint32L(CMTPTypeObjectPropListElement::EObjectHandle);
       
   926 		// All object handle in dataset must contain either 0x00000000 or match with the parameter 1
       
   927 		if (handle != aObjectMetaData.Uint(CMTPObjectMetaData::EHandle) && handle != KMTPHandleNone)
       
   928 			{
       
   929 			responseCode = EMTPRespCodeInvalidObjectHandle;
       
   930 			}
       
   931 		else
       
   932 			{
       
   933 			const TDesC& suid = aObjectMetaData.DesC(CMTPObjectMetaData::ESuid);
       
   934 			// Update will be treated as adding a new object for RO object property.
       
   935 			responseCode = iObjectHandler->SetObjectPropertyL(suid, element, EMTPOpCodeUpdateObjectPropList);
       
   936 			}
       
   937 		if(EMTPRespCodeOK != responseCode)
       
   938 			{
       
   939 			iObjectHandler->RollBack();
       
   940 			break;
       
   941 			}
       
   942 		}
       
   943 	__FLOG_VA((_L8("UpdateObjectPropListL - Exit with responseCode = 0x%04X"), responseCode));
       
   944 	return responseCode;
       
   945 	}