--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csendobject.cpp Thu Dec 17 08:55:47 2009 +0200
@@ -0,0 +1,1351 @@
+/*
+* Copyright (c) 2009 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: Implement the operation: SendObjectInfo/SendObjectPropList/SendObject
+*
+*/
+
+
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/cmtptypearray.h>
+#include <mtp/cmtptypeobjectinfo.h>
+#include <mtp/cmtptypefile.h>
+#include <mtp/mmtpstoragemgr.h>
+#include <mtp/cmtpobjectmetadata.h>
+#include <bautils.h>
+#include <mtp/cmtptypeobjectproplist.h>
+
+#include "csendobject.h"
+#include "mmmtpdpconfig.h"
+#include "mmmtpdputility.h"
+#include "tmmmtpdppanic.h"
+#include "mmmtpdplogger.h"
+#include "cmmmtpdpmetadataaccesswrapper.h"
+
+// Verification data for the SendObjectInfo request
+const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] =
+ {
+ {
+ TMTPTypeRequest::ERequestParameter1,
+ EMTPElementTypeStorageId,
+ EMTPElementAttrWrite,
+ 1,
+ 0,
+ 0
+ },
+
+ {
+ TMTPTypeRequest::ERequestParameter2,
+ EMTPElementTypeObjectHandle,
+ EMTPElementAttrDir | EMTPElementAttrWrite,
+ 2,
+ KMTPHandleAll,
+ KMTPHandleNone
+ }
+ };
+
+// -----------------------------------------------------------------------------
+// CSendObject::~CSendObject
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSendObject::~CSendObject()
+ {
+ if ( ( iProgress == EObjectInfoSucceed
+ || iProgress == EObjectInfoFail
+ || iProgress == EObjectInfoInProgress )
+ && !iNoRollback )
+ {
+ // Not finished SendObjectInfo \ SendObject pair detected.
+ Rollback();
+ PRINT( _L( "MM MTP <> CSendObject::~CSendObject, Rollback" ) );
+ }
+
+ delete iFileReceived;
+ delete iParentSuid;
+ delete iObjectInfo;
+ delete iObjectPropList;
+ delete iDateMod;
+ delete iReceivedObjectInfo;
+
+ PRINT( _L( "MM MTP <= CSendObject::~CSendObject" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::CSendObject
+// Standard C++ Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSendObject::CSendObject( MMTPDataProviderFramework& aFramework,
+ MMTPConnection& aConnection,
+ MMmMtpDpConfig& aDpConfig ) :
+ CRequestProcessor( aFramework, aConnection, 0, NULL),
+ iFs( iFramework.Fs() ),
+ iObjectMgr( iFramework.ObjectMgr() ),
+ iDpConfig( aDpConfig )
+ {
+ PRINT( _L( "Operation: SendObjectInfo/SendObject/SendObjectPropList(0x100C/0x100D/0x9808)" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ConstructL
+// 2nd Phase Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSendObject::ConstructL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::ConstructL" ) );
+
+ iExpectedSendObjectRequest.SetUint16( TMTPTypeRequest::ERequestOperationCode,
+ EMTPOpCodeSendObject );
+
+ iReceivedObjectInfo = CMTPObjectMetaData::NewL();
+ iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EDataProviderId,
+ iFramework.DataProviderId() );
+
+ PRINT1( _L( "MM MTP <> CSendObject::ConstructL DataProviderId = 0x%x" ), iFramework.DataProviderId());
+
+ iNoRollback = EFalse;
+
+ SetPSStatus();
+ PRINT( _L( "MM MTP <= CSendObject::ConstructL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::Match
+// Override to match both the SendObjectInfo and SendObject requests
+// @param aRequest The request to match
+// @param aConnection The connection from which the request comes
+// @return ETrue if the processor can handle the request, otherwise EFalse
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSendObject::Match( const TMTPTypeRequest& aRequest,
+ MMTPConnection& aConnection ) const
+ {
+ TBool result = EFalse;
+
+ TUint16 operationCode = aRequest.Uint16( TMTPTypeRequest::ERequestOperationCode );
+ if ( ( operationCode == EMTPOpCodeSendObjectInfo
+ || operationCode == EMTPOpCodeSendObject
+ || operationCode == EMTPOpCodeSendObjectPropList )
+ && ( &iConnection == &aConnection ) )
+ {
+ result = ETrue;
+ }
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::CheckSendingState
+// Helper Functions
+// Verify if the SendObject request comes after SendObjectInfo request
+// @return EMTPRespCodeOK if SendObject request comes after a valid SendObjectInfo request, otherwise
+// EMTPRespCodeNoValidObjectInfo
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CSendObject::CheckSendingStateL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::CheckSendingState" ) );
+
+ TMTPResponseCode result = EMTPRespCodeOK;
+ iOperationCode = Request().Uint16( TMTPTypeRequest::ERequestOperationCode );
+ PRINT1( _L( "MM MTP <> CSendObject iOperationCode = 0x%x" ), iOperationCode );
+
+ if ( iOperationCode == EMTPOpCodeSendObject )
+ {
+ // In ParseRouter everytime SendObject gets resolved then will be removed from Registry
+ // right away therefore we need reRegister it here again in case possible cancelRequest
+ // against this SendObject being raised.
+ iExpectedSendObjectRequest.SetUint32( TMTPTypeRequest::ERequestSessionID,
+ iSessionId );
+ iFramework.RouteRequestRegisterL( iExpectedSendObjectRequest,
+ iConnection );
+ }
+
+ if ( iProgress == EObjectNone )
+ {
+ if ( iOperationCode == EMTPOpCodeSendObject )
+ {
+ PRINT( _L( "MM MTP <> CSendObject::CheckSendingState EMTPRespCodeNoValidObjectInfo" ) );
+ result = EMTPRespCodeNoValidObjectInfo;
+ }
+ }
+ else if ( iProgress == EObjectInfoSucceed )
+ {
+ if ( iOperationCode == EMTPOpCodeSendObjectInfo )
+ {
+ delete iObjectInfo;
+ iObjectInfo = NULL;
+ iProgress = EObjectNone;
+ }
+ else if ( iOperationCode == EMTPOpCodeSendObjectPropList )
+ {
+ delete iObjectPropList;
+ iObjectPropList = NULL;
+ iProgress = EObjectNone;
+ }
+ }
+ else
+ {
+ Panic( EMmMTPDpSendObjectStateInvalid );
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::CheckSendingState result = 0x%x" ), result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::CheckRequestL
+// Verify the reqeust
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TMTPResponseCode CSendObject::CheckRequestL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::CheckRequestL" ) );
+
+ TMTPResponseCode responseCode = CheckSendingStateL();
+
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ return responseCode;
+ }
+
+ if ( iProgress == EObjectNone )
+ // Only SendObjectInfo/SendObjectPropList's request phase will enter into this function,
+ // otherwise, state machine of fw should be wrong.
+ {
+ iElementCount = sizeof( KMTPSendObjectInfoPolicy ) / sizeof( TMTPRequestElementInfo );
+ iElements = KMTPSendObjectInfoPolicy;
+ }
+ else if ( iProgress == EObjectInfoSucceed )
+ {
+ iElementCount = 0;
+ iElements = NULL;
+ }
+
+ if ( iElements != NULL )
+ {
+ responseCode = CRequestProcessor::CheckRequestL();
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ return responseCode;
+ }
+
+ // Reserve storageId and parent into member data variables if they are matched.
+ responseCode = MatchStoreAndParentL();
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ return responseCode;
+ }
+
+ if ( iOperationCode == EMTPOpCodeSendObjectPropList )
+ {
+ // check if it is what dp supported
+ iObjectFormat = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
+ if ( iObjectFormat != KMTPFormatsAll )
+ {
+ responseCode = EMTPRespCodeInvalidObjectFormatCode;
+
+ const RArray<TUint>* format = iDpConfig.GetSupportedFormat();
+ TInt count = format->Count();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iObjectFormat == ( *format )[i] )
+ {
+ responseCode = EMTPRespCodeOK;
+ break;
+ }
+ }
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ return responseCode;
+ }
+ } // end of if ( iObjectFormat != KMTPFormatsAll )
+
+ // check object size
+ TUint32 objectSizeHigh = Request().Uint32( TMTPTypeRequest::ERequestParameter4 );
+ TUint32 objectSizeLow = Request().Uint32( TMTPTypeRequest::ERequestParameter5 );
+ iObjectSize = MAKE_TUINT64( objectSizeHigh, objectSizeLow );
+ PRINT1( _L( "MM MTP <> CSendObject::CheckRequestL iObjectSize = %Lu" ), iObjectSize );
+
+ if ( IsTooLarge( iObjectSize ) )
+ {
+ responseCode = EMTPRespCodeObjectTooLarge;
+ }
+
+ if ( ( responseCode != EMTPRespCodeOK ) && !CanStoreFileL( iStorageId, iObjectSize ) )
+ {
+ responseCode = EMTPRespCodeStoreFull;
+ }
+ }
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::CheckRequestL, responseCode = 0x%x" ), responseCode );
+ return responseCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::HasDataphase
+// Exception handling. CRequestProcessor will receive data if this operation
+// won't by return ETrue.
+// @return ETrue if there is data need to be received from initiator
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSendObject::HasDataphase() const
+ {
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ServiceL
+// ServiceL request handler
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSendObject::ServiceL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::ServiceL" ) );
+
+ if ( iProgress == EObjectNone )
+ {
+ if ( iOperationCode == EMTPOpCodeSendObjectInfo )
+ {
+ ServiceInfoL();
+ }
+ else
+ {
+ ServicePropListL();
+ }
+ }
+ else
+ {
+ PRINT1( _L( "MM MTP <> CSendObject::ServiceL, iProgress = %d" ), iProgress );
+ ServiceObjectL();
+ }
+ PRINT( _L( "MM MTP <= CSendObject::ServiceL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ServiceInfoL
+// ServiceL - Recieves the objectinfo data
+// -----------------------------------------------------------------------------
+//
+void CSendObject::ServiceInfoL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::ServiceInfoL" ) );
+
+ iObjectInfo = CMTPTypeObjectInfo::NewL();
+ ReceiveDataL( *iObjectInfo );
+ iProgress = EObjectInfoInProgress;
+
+ PRINT( _L( "MM MTP <= CSendObject::ServiceInfoL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ServicePropListL
+// SendObjectPropList
+// -----------------------------------------------------------------------------
+//
+void CSendObject::ServicePropListL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::ServicePropListL" ) );
+
+ iObjectPropList = CMTPTypeObjectPropList::NewL();
+ ReceiveDataL( *iObjectPropList );
+ iProgress = EObjectInfoInProgress;
+
+ PRINT( _L( "MM MTP <= CSendObject::ServicePropListL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ServiceObjectL
+// SendObject
+// -----------------------------------------------------------------------------
+//
+void CSendObject::ServiceObjectL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::ServiceObjectL" ) );
+
+ delete iFileReceived;
+ iFileReceived = NULL;
+
+ PRINT2( _L( "MM MTP <> CSendObject::ServiceObjectL, iFullPath is %S, iObjectSize: %Lu" ), &iFullPath, iObjectSize );
+ TRAPD( err, iFileReceived = CMTPTypeFile::NewL( iFs,
+ iFullPath,
+ EFileWrite ) );
+
+ PRINT1( _L("MM MTP <> CSendObject::ServiceObjectL, Leave Code is: %d"), err );
+ User::LeaveIfError( err );
+
+ iFileReceived->SetSizeL( iObjectSize );
+
+ ReceiveDataL( *iFileReceived );
+
+ iProgress = ESendObjectInProgress;
+
+ PRINT( _L( "MM MTP <= CSendObject::ServiceObjectL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::DoHandleResponsePhaseL
+// Response Phase Handler
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSendObject::DoHandleResponsePhaseL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseL" ) );
+
+ // check if the sending/receiving data is successful
+ TBool successful = !iCancelled;
+ if ( iProgress == EObjectInfoInProgress )
+ {
+ if ( iOperationCode == EMTPOpCodeSendObjectInfo )
+ {
+ successful = DoHandleResponsePhaseInfoL();
+ }
+ else if ( iOperationCode == EMTPOpCodeSendObjectPropList )
+ {
+ successful = DoHandleResponsePhasePropListL();
+ }
+ iProgress = ( successful ? EObjectInfoSucceed : EObjectInfoFail );
+ iPreviousOperation = iOperationCode;
+ }
+ else if ( iProgress == ESendObjectInProgress )
+ {
+ successful = DoHandleResponsePhaseObjectL();
+ iProgress = ( successful ? ESendObjectSucceed : ESendObjectFail );
+ }
+ PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseL iProgress = %d" ), iProgress );
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::DoHandleResponsePhaseInfoL
+// Handle Response - Checks whether the request was successful
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::DoHandleResponsePhaseInfoL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseInfoL" ) );
+
+ TBool result = ETrue;
+
+ // cache the width and height of video file
+ iObjectFormat = iObjectInfo->Uint16L( CMTPTypeObjectInfo::EObjectFormat );
+ iWidth = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EImagePixWidth );
+ iHeight = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EImagePixWidth );
+ PRINT3( _L("MM MTP <> CSendObject::DoHandleResponsePhaseInfoL iObjectFormat = 0x%x, iWidth = %d, iHeight = %d"),
+ iObjectFormat,
+ iWidth,
+ iHeight );
+
+ // TODO: dateModified is reserved for extention usage.
+ delete iDateMod;
+ iDateMod = NULL;
+ iDateMod = iObjectInfo->StringCharsL( CMTPTypeObjectInfo::EDateModified ).AllocL();
+
+ // check if storage is full
+ iObjectSize = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EObjectCompressedSize );
+ PRINT1( _L("MM MTP <> CSendObject::DoHandleResponsePhaseInfoL, iObjectSize = %Lu"), iObjectSize );
+
+ if ( IsTooLarge( iObjectSize ) )
+ {
+ SendResponseL( EMTPRespCodeObjectTooLarge );
+ result = EFalse;
+ }
+
+ if ( result && !CanStoreFileL( iStorageId, iObjectSize ) )
+ {
+ SendResponseL( EMTPRespCodeStoreFull );
+ result = EFalse;
+ }
+
+ if ( result )
+ {
+ iProtectionStatus = iObjectInfo->Uint16L( CMTPTypeObjectInfo::EProtectionStatus );
+ PRINT1( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseInfoL iProtectionStatus = %d" ), iProtectionStatus );
+ if ( iProtectionStatus != EMTPProtectionNoProtection
+ && iProtectionStatus != EMTPProtectionReadOnly )
+ {
+ SendResponseL( EMTPRespCodeParameterNotSupported );
+ result = EFalse;
+ }
+ }
+
+ if ( result )
+ {
+ result = GetFullPathNameL( iObjectInfo->StringCharsL( CMTPTypeObjectInfo::EFilename ) );
+ if ( !result )
+ {
+ // File and/or parent pathname invalid.
+ SendResponseL( EMTPRespCodeInvalidDataset );
+ }
+ }
+
+ if ( result )
+ {
+ if ( ExistsL( iFullPath ) )
+ {
+ // Object with the same name already exists.
+ iNoRollback = ETrue;
+ SendResponseL( EMTPRespCodeAccessDenied );
+ result = EFalse;
+ }
+ }
+
+ if ( result )
+ ReserveObjectL();
+
+ PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseInfoL result = %d" ), result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::DoHandleResponsePhasePropListL
+// SendObjectPropList
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::DoHandleResponsePhasePropListL()
+ {
+ PRINT( _L("MM MTP => CSendObject::DoHandleResponsePhasePropListL" ) );
+
+ TMTPResponseCode responseCode = EMTPRespCodeOK;
+
+ TInt invalidParameterIndex = KErrNotFound;
+ responseCode = VerifyObjectPropListL( invalidParameterIndex );
+
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ TUint32 parameters[4];
+ parameters[0] = 0;
+ parameters[1] = 0;
+ parameters[2] = 0;
+ parameters[3] = invalidParameterIndex;
+ SendResponseL( responseCode, 4, parameters );
+ }
+ else if ( ExistsL( iFullPath ) )
+ {
+ // Object with the same name already exists.
+ iNoRollback = ETrue;
+ SendResponseL( EMTPRespCodeAccessDenied );
+ }
+ else
+ ReserveObjectL();
+
+ PRINT( _L( "MM MTP <= CSendObject::DoHandleResponsePhasePropListL" ) );
+ return ( responseCode == EMTPRespCodeOK );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::DoHandleResponsePhaseObjectL
+// SendObject
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::DoHandleResponsePhaseObjectL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseObjectL" ) );
+
+ TBool result = ETrue;
+
+ delete iFileReceived;
+ iFileReceived = NULL;
+
+ TEntry fileEntry;
+ User::LeaveIfError( iFs.Entry( iFullPath, fileEntry ) );
+ if ( fileEntry.iSize != iObjectSize )
+ {
+ iFs.Delete( iFullPath );
+ iObjectMgr.UnreserveObjectHandleL( *iReceivedObjectInfo );
+ TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge;
+ if ( fileEntry.iSize < iObjectSize )
+ {
+ responseCode = EMTPRespCodeIncompleteTransfer;
+ }
+ SendResponseL( responseCode );
+ result = EFalse;
+ }
+
+ // SendObject is cancelled or connection is dropped.
+ if ( result && iCancelled )
+ {
+ iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest,
+ iConnection );
+ Rollback();
+ SendResponseL( EMTPRespCodeTransactionCancelled );
+ }
+ else if ( result && !iCancelled )
+ {
+ if ( iObjectSize > 0 ) // media file
+ {
+ AddMediaToStoreL();
+
+ if( iPreviousOperation == EMTPOpCodeSendObjectPropList )
+ {
+ SetObjectPropListL( *iObjectPropList );
+ }
+
+ // Commits into MTP data object enumeration store the object handle and
+ // storage space previously reserved for the specified object.
+ iFramework.ObjectMgr().CommitReservedObjectHandleL( *iReceivedObjectInfo );
+ }
+
+ // Commit object to MTP data store
+ iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest,
+ iConnection );
+
+ SendResponseL( EMTPRespCodeOK );
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseObjectL result = %d" ), result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::DoHandleCompletingPhaseL
+// Completeing phase Handler
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSendObject::DoHandleCompletingPhaseL()
+ {
+ TBool result = ETrue;
+
+ PRINT( _L( "MM MTP => CSendObject::DoHandleCompletingPhaseL" ) );
+
+ CRequestProcessor::DoHandleCompletingPhaseL();
+ //Ensure that, even though the SendObjectInfo was successul, the request responder is not deleted
+ if ( iProgress == EObjectInfoSucceed )
+ {
+ result = EFalse;
+ }
+ else if ( iProgress == ESendObjectFail )
+ {
+ //Sending Object failed, but still do not delete request, can try again with current info
+ iProgress = EObjectInfoSucceed;
+ result = EFalse;
+ }
+
+ PRINT2( _L( "MM MTP <= CSendObject::DoHandleCompletingPhaseL iProgress= %d, result = %d" ),
+ iProgress,
+ result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// Check if the property list is valid and extract necessary properties
+// @param aInvalidParameterIndex if invalid, contains the index of the property.
+// Undefined, if it is valid.
+// @return if error, one of the error response code; otherwise EMTPRespCodeOK
+// -----------------------------------------------------------------------------
+TMTPResponseCode CSendObject::VerifyObjectPropListL( TInt& aInvalidParameterIndex )
+ {
+ PRINT( _L( "MM MTP => CSendObject::VerifyObjectPropListL" ) );
+
+ TMTPResponseCode responseCode( EMTPRespCodeOK );
+ const TInt count = iObjectPropList->NumberOfElements();
+ iObjectPropList->ResetCursor();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ const CMTPTypeObjectPropListElement& element( iObjectPropList->GetNextElementL() );
+ const TUint32 handle( element.Uint32L( CMTPTypeObjectPropListElement::EObjectHandle ) );
+ aInvalidParameterIndex = i;
+ if ( handle != KMTPHandleNone )
+ {
+ responseCode = EMTPRespCodeInvalidObjectHandle;
+ break;
+ }
+
+ responseCode = CheckPropCodeL( element );
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ break;
+ }
+ responseCode = ExtractPropertyL( element );
+ if ( responseCode != EMTPRespCodeOK )
+ {
+ break;
+ }
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::VerifyObjectPropListL, responseCode = 0x%X" ), responseCode );
+ return responseCode;
+ }
+
+// -----------------------------------------------------------------------------
+// Validates the data type for a given property code.
+// @param aElement an object property list element
+// @param aPropertyCode MTP property code for the element
+// @return EMTPRespCodeOK if the combination is valid, or another MTP response code if not
+// -----------------------------------------------------------------------------
+TMTPResponseCode CSendObject::CheckPropCodeL( const CMTPTypeObjectPropListElement& aElement )
+ {
+ PRINT( _L( "MM MTP => CSendObject::CheckPropCodeL" ) );
+ TMTPResponseCode responseCode( EMTPRespCodeOK );
+
+ // Checking if the propCode is supported first then check its type
+ const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( iObjectFormat );
+ TUint16 propCode = aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode );
+ TUint16 dataType = aElement.Uint16L( CMTPTypeObjectPropListElement::EDatatype );
+ PRINT2( _L( "MM MTP => CSendObject::CheckPropCodeL propCode = 0x%X, dataType = 0x%X" ), propCode, dataType );
+
+ responseCode = EMTPRespCodeInvalidObjectPropCode;
+ const TInt count = properties->Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( ( *properties )[i] == propCode )
+ {
+ responseCode = EMTPRespCodeOK;
+ break;
+ }
+ }
+
+ if ( responseCode != EMTPRespCodeOK )
+ return responseCode;
+
+ // TODO: abstractmedia and media dp have different supported propCode, need check common prop code and check others in dp derived processors.
+ // also need to check if the propCode is supported
+ switch ( propCode )
+ {
+ case EMTPObjectPropCodeStorageID:
+ if ( dataType != EMTPTypeUINT32 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ else if ( iStorageId != aElement.Uint32L( CMTPTypeObjectPropListElement::EValue ) )
+ {
+ responseCode = EMTPRespCodeInvalidDataset;
+ }
+ break;
+
+ case EMTPObjectPropCodeObjectFormat:
+ if ( dataType != EMTPTypeUINT16 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ else if ( iObjectFormat != aElement.Uint16L( CMTPTypeObjectPropListElement::EValue ) )
+ {
+ responseCode = EMTPRespCodeInvalidDataset;
+ }
+ break;
+
+ case EMTPObjectPropCodeObjectSize:
+ if ( dataType != EMTPTypeUINT64 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ else if ( iObjectSize != aElement.Uint64L( CMTPTypeObjectPropListElement::EValue ) )
+ {
+ responseCode = EMTPRespCodeInvalidDataset;
+ }
+ PRINT1(_L("MM MTP => CSendObject::CheckPropCodeL Checking ObjectSize %d"), responseCode );
+ break;
+
+ case EMTPObjectPropCodeParentObject:
+ if ( dataType != EMTPTypeUINT32 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ else if ( ( iParentHandle != aElement.Uint32L( CMTPTypeObjectPropListElement::EValue ) )
+ || ( KMTPHandleNone != aElement.Uint32L( CMTPTypeObjectPropListElement::EValue ) ) )
+ // iParentHandle might be changed in CheckRequestL
+ {
+ responseCode = EMTPRespCodeInvalidDataset;
+ }
+ break;
+
+ case EMTPObjectPropCodePersistentUniqueObjectIdentifier: // read-only
+ if ( dataType != EMTPTypeUINT128 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ break;
+
+ case EMTPObjectPropCodeProtectionStatus:
+ if ( dataType != EMTPTypeUINT16 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ break;
+
+ case EMTPObjectPropCodeDateCreated:
+ // TODO: this property is read-only, should response EMTPRespCodeAccessDenied or set nothing?
+ case EMTPObjectPropCodeDateModified:
+ case EMTPObjectPropCodeObjectFileName:
+ case EMTPObjectPropCodeName:
+ if ( dataType != EMTPTypeString )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ break;
+
+ case EMTPObjectPropCodeNonConsumable:
+ if ( dataType != EMTPTypeUINT8 )
+ {
+ responseCode = EMTPRespCodeInvalidObjectPropFormat;
+ }
+ break;
+
+ default:
+ // check types of DP specific properties
+ // TODO: Is there anything except datatype need to be checked?
+ responseCode = CheckSepecificPropType( propCode, dataType );
+ break;
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::CheckPropCode, responseCode = 0x%X" ), responseCode );
+ return responseCode;
+ }
+
+// -----------------------------------------------------------------------------
+// Extracts the file information from the object property list element
+// @param aElement an object property list element
+// @param aPropertyCode MTP property code for the element
+// @return MTP response code
+// -----------------------------------------------------------------------------
+TMTPResponseCode CSendObject::ExtractPropertyL( const CMTPTypeObjectPropListElement& aElement )
+ {
+ PRINT( _L ( "MM MTP => CSendObject::ExtractPropertyL" ) );
+ TMTPResponseCode responseCode( EMTPRespCodeOK );
+ switch ( aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ) )
+ {
+ case EMTPObjectPropCodeObjectFileName:
+ {
+ const TDesC& fileName = aElement.StringL( CMTPTypeObjectPropListElement::EValue );
+ if ( !GetFullPathNameL( fileName ) )
+ {
+ responseCode = EMTPRespCodeInvalidDataset;
+ }
+ }
+ break;
+
+ case EMTPObjectPropCodeProtectionStatus:
+ {
+ iProtectionStatus = aElement.Uint16L( CMTPTypeObjectPropListElement::EValue );
+ if ( iProtectionStatus != EMTPProtectionNoProtection
+ && iProtectionStatus != EMTPProtectionReadOnly )
+ {
+ responseCode = EMTPRespCodeParameterNotSupported;
+ }
+ }
+ break;
+
+ case EMTPObjectPropCodeDateModified:
+ delete iDateMod;
+ iDateMod = NULL;
+ iDateMod = aElement.StringL( CMTPTypeObjectPropListElement::EValue ).AllocL();
+ // Cache it for further usage.
+ break;
+
+ default:
+ // Only extract necessary properties which conform to SendObjectInfo.
+ break;
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::ExtractPropertyL, responseCode = 0x%X" ), responseCode );
+ return responseCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::SetObjectPropListL
+// Reserve object proplist into database
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CSendObject::SetObjectPropListL( const CMTPTypeObjectPropList& aPropList )
+ {
+ PRINT( _L( "MM MTP => CSendObject::SetObjectPropListL" ) );
+
+ TMTPResponseCode responseCode( EMTPRespCodeOK );
+
+ const TUint count( iObjectPropList->NumberOfElements() );
+ iObjectPropList->ResetCursor();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ const CMTPTypeObjectPropListElement& element( iObjectPropList->GetNextElementL() );
+
+ TUint16 propertyCode = element.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode );
+ TUint16 dataType = element.Uint16L( CMTPTypeObjectPropListElement::EDatatype );
+ PRINT2( _L( "MM MTP <> SetObjectPropListL propertyCode = 0x%x, dataType = 0x%x" ),
+ propertyCode, dataType );
+
+ switch ( propertyCode )
+ {
+ case EMTPObjectPropCodeStorageID:
+ case EMTPObjectPropCodeObjectFormat:
+ case EMTPObjectPropCodeProtectionStatus:
+ case EMTPObjectPropCodeObjectSize:
+ case EMTPObjectPropCodeParentObject:
+ case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
+ // Do nothing for those properties are already set.
+ break;
+
+ case EMTPObjectPropCodeNonConsumable:
+ case EMTPObjectPropCodeDateAdded:
+ case EMTPObjectPropCodeDateCreated:
+ case EMTPObjectPropCodeDateModified:
+ case EMTPObjectPropCodeObjectFileName:
+ // TODO: Does anything need to be done on these read-only properties?
+ /* spec:
+ * Object properties that are get-only (0x00 GET)
+ * should accept values during object creation by
+ * way of the SendObjectPropList command.
+ */
+ break;
+
+ case EMTPObjectPropCodeName:
+ {
+ CMTPTypeString* stringData = CMTPTypeString::NewLC( element.StringL( CMTPTypeObjectPropListElement::EValue ) );// + stringData
+
+ responseCode = SetMetaDataToWrapperL( propertyCode,
+ *stringData,
+ *iReceivedObjectInfo );
+
+ CleanupStack::PopAndDestroy( stringData );// - stringData
+ }
+ break;
+
+ default:
+ {
+ responseCode = SetSpecificObjectPropertyL( propertyCode,
+ *iReceivedObjectInfo,
+ element );
+ }
+ break;
+ } // end of switch
+ } // end of for
+
+ PRINT1( _L( "MM MTP <= CSendObject::SetObjectPropListL responseCode = 0x%x" ), responseCode );
+ return responseCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::SetMetaDataToWrapperL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TMTPResponseCode CSendObject::SetMetaDataToWrapperL( const TUint16 aPropCode,
+ MMTPType& aNewData,
+ const CMTPObjectMetaData& aObjectMetaData )
+ {
+ TMTPResponseCode resCode = EMTPRespCodeOK;
+ TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode,
+ aNewData,
+ aObjectMetaData ) );
+
+ PRINT1( _L("MM MTP <> CSendObject::SetMetaDataToWrapperL err = %d"), err);
+
+ if ( err == KErrNone )
+ {
+ resCode = EMTPRespCodeOK;
+ }
+ else if ( err == KErrTooBig )
+ // according to the codes of S60
+ {
+ resCode = EMTPRespCodeInvalidDataset;
+ }
+ else if ( err == KErrPermissionDenied )
+ {
+ resCode = EMTPRespCodeAccessDenied;
+ }
+ else if ( err == KErrNotFound )
+ {
+ if ( MmMtpDpUtility::HasMetadata( aObjectMetaData.Uint( CMTPObjectMetaData::EFormatCode ) ) )
+ SendResponseL( EMTPRespCodeAccessDenied );
+ }
+ else
+ {
+ err = HandleSpecificWrapperError( err, aObjectMetaData );
+
+ if ( err != KErrNone )
+ resCode = EMTPRespCodeGeneralError;
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::SetMetaDataToWrapperL resCode = 0x%x" ), resCode );
+
+ return resCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::MatchStoreAndParentL
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CSendObject::MatchStoreAndParentL()
+ {
+ TMTPResponseCode responseCode = EMTPRespCodeOK;
+
+ iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
+ iParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
+ PRINT2( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iStorageId = 0x%X, iParentHandle = 0x%X" ),
+ iStorageId,
+ iParentHandle );
+
+ if ( iStorageId == KMTPStorageDefault )
+ {
+ iStorageId = iDpConfig.GetDefaultStorageIdL();
+ PRINT1( _L( "MM MTP <> CSendObject::GetDefaultStorageIdL, iStorageId = 0x%X" ), iStorageId );
+ }
+
+ delete iParentSuid;
+ iParentSuid = NULL;
+
+ if( iParentHandle == KMTPHandleNone ) // parentHandle is not used by initiator, set it to root
+ {
+ iParentHandle = KMTPHandleAll;
+ }
+ if ( iParentHandle == KMTPHandleAll ) // According to spec, KMTPHandleAll means initiator wish to place in the root
+ {
+ PRINT( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iParentSuid = KMTPHandleAll" ) );
+ iParentSuid = iFramework.StorageMgr().StorageL( iStorageId ).DesC( CMTPStorageMetaData::EStorageSuid ).AllocL();
+ PRINT1( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iParentSuid = %S" ), iParentSuid );
+ }
+ else // parentHandle is specified by initiator
+ {
+ // does not take owernship
+ CMTPObjectMetaData* parentObjInfo = iRequestChecker->GetObjectInfo( iParentHandle );
+ __ASSERT_DEBUG( parentObjInfo, Panic( EMmMTPDpObjectNull ) );
+
+ if ( parentObjInfo->Uint( CMTPObjectMetaData::EStorageId ) != iStorageId )
+ {
+ responseCode = EMTPRespCodeInvalidObjectHandle;
+ PRINT( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, STORAGEID DOES NOT MATCH WITH PARENTHANDLE!" ) );
+ }
+ else
+ {
+ iParentSuid = parentObjInfo->DesC( CMTPObjectMetaData::ESuid ).AllocL();
+ }
+ }
+ PRINT1( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iParentSuid = %S" ), iParentSuid );
+
+ if ( ( responseCode == EMTPRespCodeOK ) && !BaflUtils::PathExists( iFramework.Fs(), *iParentSuid ) )
+ {
+ responseCode = EMTPRespCodeInvalidDataset;
+ }
+
+ return responseCode;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::IsTooLarge
+// Check if the object is too large
+// @return ETrue if yes, otherwise EFalse
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::IsTooLarge( TUint32 aObjectSize ) const
+ {
+ TBool ret = ( aObjectSize > KMaxTInt );
+ PRINT2( _L( "MM MTP <> CSendObject::IsTooLarge aObjectSize = %d, ret = %d" ), aObjectSize, ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::CanStoreFileL
+// Check if we can store the file on the storage
+// @return ETrue if yes, otherwise EFalse
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::CanStoreFileL( TUint32 aStorageId,
+ TInt64 aObjectSize ) const
+ {
+ PRINT( _L( "MM MTP => CSendObject::CanStoreFileL" ) );
+
+ TBool result = ETrue;
+ TVolumeInfo volumeInfo;
+ TInt driveNo = iFramework.StorageMgr().DriveNumber( aStorageId );
+ User::LeaveIfError( iFs.Volume( volumeInfo, driveNo ) );
+
+ if ( volumeInfo.iFree < aObjectSize )
+ {
+ result = EFalse;
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::CanStoreFileL , result = %d" ), result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::GetFullPathNameL
+// Get the full path name of the object to be saved
+// @param aFileName, on entry, contains the file name of the object,
+// on return, contains the full path name of the object to be saved
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::GetFullPathNameL( const TDesC& aFileName )
+ {
+ PRINT1( _L("MM MTP => CSendObject::GetFullPathNameL aFileName = %S"), &aFileName );
+
+ TBool result( EFalse );
+ if ( aFileName.Length() > 0 )
+ {
+ iFullPath.Zero();
+ iFullPath.Append( *iParentSuid );
+ if ( ( iFullPath.Length() + aFileName.Length() ) < KMaxFileName )
+ {
+ iFullPath.Append( aFileName );
+ PRINT1( _L( "MM MTP <> CSendObject::GetFullPathNameL iFullPath = %S" ), &iFullPath );
+ result = iFramework.Fs().IsValidName( iFullPath );
+ }
+ }
+ if ( result && ( iObjectFormat != MmMtpDpUtility::FormatFromFilename( iFullPath ) ) )
+ {
+ PRINT2( _L( "MM MTP <> %S does not match 0x%x" ), &iFullPath, iObjectFormat );
+ result = EFalse;
+ }
+
+ PRINT1( _L( "MM MTP <= CSendObject::GetFullPathNameL result = %d" ), result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ExistsL
+// Check if the file already exists on the storage.
+// -----------------------------------------------------------------------------
+//
+TBool CSendObject::ExistsL( const TDesC& aName ) const
+ {
+ PRINT1( _L( "MM MTP => CSendObject::Exists aName = %S" ), &aName );
+ // This detects both files and folders
+ TBool ret( EFalse );
+ ret = BaflUtils::FileExists( iFramework.Fs(), aName );
+
+#ifdef MMMTPDP_REPLACE_EXIST_FILE
+ if( ret )
+ {
+ // delete the old one and replace
+ TInt delErr = iFramework.Fs().Delete( aName );
+ PRINT1( _L( "MM MTP <> CSendObject::Exists delErr = %d" ), delErr );
+ // delete from the metadata DB
+ TRAPD( err, iFramework.ObjectMgr().RemoveObjectL( aName ) );
+ PRINT1( _L( "MM MTP <> CSendObject::Exists err = %d" ), err );
+ if( err == KErrNone )
+ {
+ // do nothing, ignore warning
+ }
+ // delete from video/mpx DB
+ CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
+ if ( iFramework.ObjectMgr().ObjectL( aName, *objectInfo ) )
+ {
+ TRAP_IGNORE( iWrapper.DeleteObjectL( aName,
+ objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) );
+ }
+ CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
+ ret = EFalse;
+ }
+#endif
+ PRINT1( _L( "MM MTP <= CSendObject::Exists ret = %d" ), ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::ReserveObjectL
+// -----------------------------------------------------------------------------
+//
+void CSendObject::ReserveObjectL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::ReserveObjectL" ) );
+ TInt err = KErrNone;
+
+ iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
+ iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EParentHandle,
+ iParentHandle );
+ iReceivedObjectInfo->SetDesCL( CMTPObjectMetaData::ESuid, iFullPath );
+ iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EFormatCode,
+ iObjectFormat );
+
+ // Reserves space for and assigns an object handle to the object described
+ // by the specified object information record.
+ TRAP( err, iObjectMgr.ReserveObjectHandleL( *iReceivedObjectInfo,
+ iObjectSize ) );
+
+ PRINT2( _L( "MM MTP => CSendObject::ReserveObjectL iObjectsize = %Lu, Operation: 0x%x" ), iObjectSize, iOperationCode );
+ if ( err != KErrNone )
+ PRINT1( _L( "MM MTP <> CSendObject::ReserveObjectL err = %d" ), err );
+ if ( iObjectSize == 0 )
+ {
+ SaveEmptyFileL();
+ iObjectMgr.CommitReservedObjectHandleL( *iReceivedObjectInfo );
+ }
+
+ iExpectedSendObjectRequest.SetUint32( TMTPTypeRequest::ERequestSessionID,
+ iSessionId );
+ iFramework.RouteRequestRegisterL( iExpectedSendObjectRequest, iConnection );
+
+ TUint32 parameters[3];
+ parameters[0] = iStorageId;
+ parameters[1] = iParentHandle;
+ parameters[2] = iReceivedObjectInfo->Uint( CMTPObjectMetaData::EHandle );
+ SendResponseL( EMTPRespCodeOK, 3, parameters );
+
+ PRINT( _L( "MM MTP <= CSendObject::ReserveObjectL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::SetProtectionStatusL
+// -----------------------------------------------------------------------------
+//
+void CSendObject::SetProtectionStatusL()
+ {
+ PRINT1( _L( "MM MTP => CSendObject::SetProtectionStatusL iProtectionStatus = %d" ), iProtectionStatus );
+
+ if ( iProtectionStatus == EMTPProtectionNoProtection
+ || iProtectionStatus == EMTPProtectionReadOnly )
+ {
+ // TODO: wait for review
+ TInt err = KErrNone;
+ if ( iProtectionStatus == EMTPProtectionNoProtection )
+ {
+ iFs.SetAtt( iFullPath, KEntryAttNormal, KEntryAttReadOnly );
+ }
+ else
+ {
+ iFs.SetAtt( iFullPath, KEntryAttReadOnly, KEntryAttNormal );
+ }
+ User::LeaveIfError( err );
+ }
+ PRINT( _L( "MM MTP <= CSendObject::SetProtectionStatusL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::SaveEmptyFileL
+// -----------------------------------------------------------------------------
+//
+void CSendObject::SaveEmptyFileL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::SaveEmptyFileL" ) );
+
+ RFile file;
+ User::LeaveIfError( file.Create( iFs, iFullPath, EFileWrite ) );
+ file.Close();
+
+ // set entry protection status and modified date
+ SetProtectionStatusL();
+
+ // add playlist to MPX DB
+ TParsePtrC parse( iFullPath );
+ iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() );
+ iDpConfig.GetWrapperL().AddObjectL( iFullPath );
+
+ if ( EMTPFormatCodeAbstractAudioVideoPlaylist == iObjectFormat )
+ {
+ TInt err = KErrNone;
+ err = iFs.SetAtt( iFullPath,
+ KEntryAttSystem | KEntryAttHidden,
+ KEntryAttReadOnly | KEntryAttNormal );
+ if ( err != KErrNone )
+ PRINT1( _L( "MM MTP <> CSendObject::SaveEmptyFileL err = %d" ), err );
+ iDpConfig.GetWrapperL().AddDummyFileL( iFullPath );
+ }
+
+ PRINT( _L( "MM MTP <= CSendObject::SaveEmptyFileL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::AddMediaToStoreL()
+//
+// -----------------------------------------------------------------------------
+//
+void CSendObject::AddMediaToStoreL()
+ {
+ PRINT( _L( "MM MTP => CSendObject::AddMediaToStoreL" ) );
+
+ TBool isVideo = EFalse;
+ switch ( iObjectFormat )
+ {
+ case EMTPFormatCode3GPContainer:
+ case EMTPFormatCodeMP4Container:
+ case EMTPFormatCodeASF:
+ {
+ TMmMtpSubFormatCode subFormatCode;
+
+ if ( MmMtpDpUtility::IsVideoL( iFullPath ) )
+ {
+ subFormatCode = EMTPSubFormatCodeVideo;
+ isVideo = ETrue;
+ }
+ else
+ {
+ subFormatCode = EMTPSubFormatCodeAudio;
+ isVideo = EFalse;
+ }
+
+ iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EFormatSubCode,
+ ( TUint ) subFormatCode );
+ }
+ break;
+
+ // put all just video format codes here
+ case EMTPFormatCodeWMV:
+ {
+ isVideo = ETrue;
+ }
+ break;
+
+ default:
+ PRINT( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseObjectL default" ) );
+ break;
+ }
+
+ TPtrC suid( iReceivedObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
+ PRINT1( _L( "MM MTP <> CSendObject::AddMediaToStoreL suid = %S" ), &suid );
+ TParsePtrC parse( suid );
+ iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() );
+ iDpConfig.GetWrapperL().AddObjectL( iFullPath, isVideo );
+
+ if ( isVideo )
+ {
+ TInt err = KErrNone;
+ TRAP( err, iDpConfig.GetWrapperL().SetImageObjPropL( iFullPath, iWidth, iHeight ) );
+
+ PRINT1( _L( "MM MTP <= CSendObject::AddVideoToStoreL err = %d" ), err );
+ }
+
+ PRINT( _L( "MM MTP <= CSendObject::AddMediaToStoreL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::UsbDisconnect
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSendObject::UsbDisconnect()
+ {
+ PRINT( _L( "MM MTP => CSendObject::UsbDisconnect" ) );
+ Rollback();
+ PRINT( _L( "MM MTP <= CSendObject::UsbDisconnect" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSendObject::Rollback()
+// delete the file, which transfer incompletely
+// -----------------------------------------------------------------------------
+//
+void CSendObject::Rollback()
+ {
+ // Delete this object from file system.
+ if ( iProgress == ESendObjectInProgress )
+ {
+ PRINT1( _L( "MM MTP <> CSendObject::Rollback ROLLBACK_FILE %S" ), &iFullPath );
+ iFramework.Fs().Delete( iFullPath );
+ TRAP_IGNORE( iFramework.ObjectMgr().UnreserveObjectHandleL( *iReceivedObjectInfo ) );
+ iProgress = EObjectNone;
+ }
+ }
+
+// end of file