mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csendobject.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
child 25 d881023c13eb
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implement the operation: SendObjectInfo/SendObjectPropList/SendObject
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <mtp/mmtpdataproviderframework.h>
       
    20 #include <mtp/mmtpobjectmgr.h>
       
    21 #include <mtp/cmtptypestring.h>
       
    22 #include <mtp/cmtptypearray.h>
       
    23 #include <mtp/cmtptypeobjectinfo.h>
       
    24 #include <mtp/cmtptypefile.h>
       
    25 #include <mtp/mmtpstoragemgr.h>
       
    26 #include <mtp/cmtpobjectmetadata.h>
       
    27 #include <bautils.h>
       
    28 #include <mtp/cmtptypeobjectproplist.h>
       
    29 
       
    30 #include "csendobject.h"
       
    31 #include "mmmtpdpconfig.h"
       
    32 #include "mmmtpdputility.h"
       
    33 #include "tmmmtpdppanic.h"
       
    34 #include "mmmtpdplogger.h"
       
    35 #include "cmmmtpdpmetadataaccesswrapper.h"
       
    36 
       
    37 // Verification data for the SendObjectInfo request
       
    38 const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] =
       
    39     {
       
    40         {
       
    41         TMTPTypeRequest::ERequestParameter1,
       
    42         EMTPElementTypeStorageId,
       
    43         EMTPElementAttrWrite,
       
    44         1,
       
    45         0,
       
    46         0
       
    47         },
       
    48 
       
    49         {
       
    50         TMTPTypeRequest::ERequestParameter2,
       
    51         EMTPElementTypeObjectHandle,
       
    52         EMTPElementAttrDir | EMTPElementAttrWrite,
       
    53         2,
       
    54         KMTPHandleAll,
       
    55         KMTPHandleNone
       
    56         }
       
    57     };
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // CSendObject::~CSendObject
       
    61 // Destructor
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 EXPORT_C CSendObject::~CSendObject()
       
    65     {
       
    66     if ( ( iProgress == EObjectInfoSucceed
       
    67             || iProgress == EObjectInfoFail
       
    68             || iProgress == EObjectInfoInProgress )
       
    69         && !iNoRollback )
       
    70         {
       
    71         // Not finished SendObjectInfo \ SendObject pair detected.
       
    72         Rollback();
       
    73         PRINT( _L( "MM MTP <> CSendObject::~CSendObject, Rollback" ) );
       
    74         }
       
    75 
       
    76     delete iFileReceived;
       
    77     delete iParentSuid;
       
    78     delete iObjectInfo;
       
    79     delete iObjectPropList;
       
    80     delete iDateMod;
       
    81     delete iReceivedObjectInfo;
       
    82 
       
    83     PRINT( _L( "MM MTP <= CSendObject::~CSendObject" ) );
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CSendObject::CSendObject
       
    88 // Standard C++ Constructor
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 EXPORT_C CSendObject::CSendObject( MMTPDataProviderFramework& aFramework,
       
    92     MMTPConnection& aConnection,
       
    93     MMmMtpDpConfig& aDpConfig ) :
       
    94         CRequestProcessor( aFramework, aConnection, 0, NULL),
       
    95         iFs( iFramework.Fs() ),
       
    96         iObjectMgr( iFramework.ObjectMgr() ),
       
    97         iDpConfig( aDpConfig )
       
    98     {
       
    99     PRINT( _L( "Operation: SendObjectInfo/SendObject/SendObjectPropList(0x100C/0x100D/0x9808)" ) );
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CSendObject::ConstructL
       
   104 // 2nd Phase Constructor
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 EXPORT_C void CSendObject::ConstructL()
       
   108     {
       
   109     PRINT( _L( "MM MTP => CSendObject::ConstructL" ) );
       
   110 
       
   111     iExpectedSendObjectRequest.SetUint16( TMTPTypeRequest::ERequestOperationCode,
       
   112         EMTPOpCodeSendObject );
       
   113 
       
   114     iReceivedObjectInfo = CMTPObjectMetaData::NewL();
       
   115     iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EDataProviderId,
       
   116         iFramework.DataProviderId() );
       
   117 
       
   118     PRINT1( _L( "MM MTP <> CSendObject::ConstructL DataProviderId = 0x%x" ), iFramework.DataProviderId());
       
   119 
       
   120     iNoRollback = EFalse;
       
   121 
       
   122     SetPSStatus();
       
   123     PRINT( _L( "MM MTP <= CSendObject::ConstructL" ) );
       
   124     }
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CSendObject::Match
       
   128 // Override to match both the SendObjectInfo and SendObject requests
       
   129 // @param aRequest    The request to match
       
   130 // @param aConnection The connection from which the request comes
       
   131 // @return ETrue if the processor can handle the request, otherwise EFalse
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 EXPORT_C TBool CSendObject::Match( const TMTPTypeRequest& aRequest,
       
   135     MMTPConnection& aConnection ) const
       
   136     {
       
   137     TBool result = EFalse;
       
   138 
       
   139     TUint16 operationCode = aRequest.Uint16( TMTPTypeRequest::ERequestOperationCode );
       
   140     if ( ( operationCode == EMTPOpCodeSendObjectInfo
       
   141             || operationCode == EMTPOpCodeSendObject
       
   142             || operationCode == EMTPOpCodeSendObjectPropList )
       
   143             && ( &iConnection == &aConnection ) )
       
   144         {
       
   145         result = ETrue;
       
   146         }
       
   147 
       
   148     return result;
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CSendObject::CheckSendingState
       
   153 // Helper Functions
       
   154 // Verify if the SendObject request comes after SendObjectInfo request
       
   155 // @return EMTPRespCodeOK if SendObject request comes after a valid SendObjectInfo request, otherwise
       
   156 // EMTPRespCodeNoValidObjectInfo
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 TMTPResponseCode CSendObject::CheckSendingStateL()
       
   160     {
       
   161     PRINT( _L( "MM MTP => CSendObject::CheckSendingState" ) );
       
   162 
       
   163     TMTPResponseCode result = EMTPRespCodeOK;
       
   164     iOperationCode = Request().Uint16( TMTPTypeRequest::ERequestOperationCode );
       
   165     PRINT1( _L( "MM MTP <> CSendObject iOperationCode = 0x%x" ), iOperationCode );
       
   166 
       
   167     if ( iOperationCode == EMTPOpCodeSendObject )
       
   168         {
       
   169         // In ParseRouter everytime SendObject gets resolved then will be removed from Registry
       
   170         // right away therefore we need reRegister it here again in case possible cancelRequest
       
   171         // against this SendObject being raised.
       
   172         iExpectedSendObjectRequest.SetUint32( TMTPTypeRequest::ERequestSessionID,
       
   173             iSessionId );
       
   174         iFramework.RouteRequestRegisterL( iExpectedSendObjectRequest,
       
   175             iConnection );
       
   176         }
       
   177 
       
   178     if ( iProgress == EObjectNone )
       
   179         {
       
   180         if ( iOperationCode == EMTPOpCodeSendObject )
       
   181             {
       
   182             PRINT( _L( "MM MTP <> CSendObject::CheckSendingState  EMTPRespCodeNoValidObjectInfo" ) );
       
   183             result = EMTPRespCodeNoValidObjectInfo;
       
   184             }
       
   185         }
       
   186     else if ( iProgress == EObjectInfoSucceed )
       
   187         {
       
   188         if ( iOperationCode == EMTPOpCodeSendObjectInfo )
       
   189             {
       
   190             delete iObjectInfo;
       
   191             iObjectInfo = NULL;
       
   192             iProgress = EObjectNone;
       
   193             }
       
   194         else if ( iOperationCode == EMTPOpCodeSendObjectPropList )
       
   195             {
       
   196             delete iObjectPropList;
       
   197             iObjectPropList = NULL;
       
   198             iProgress = EObjectNone;
       
   199             }
       
   200         }
       
   201     else
       
   202         {
       
   203         Panic( EMmMTPDpSendObjectStateInvalid );
       
   204         }
       
   205 
       
   206     PRINT1( _L( "MM MTP <= CSendObject::CheckSendingState result = 0x%x" ), result );
       
   207 
       
   208     return result;
       
   209     }
       
   210 
       
   211 // -----------------------------------------------------------------------------
       
   212 // CSendObject::CheckRequestL
       
   213 // Verify the reqeust
       
   214 // -----------------------------------------------------------------------------
       
   215 //
       
   216 EXPORT_C TMTPResponseCode CSendObject::CheckRequestL()
       
   217     {
       
   218     PRINT( _L( "MM MTP => CSendObject::CheckRequestL" ) );
       
   219 
       
   220     TMTPResponseCode responseCode = CheckSendingStateL();
       
   221 
       
   222     if ( responseCode != EMTPRespCodeOK )
       
   223         {
       
   224         return responseCode;
       
   225         }
       
   226 
       
   227     if ( iProgress == EObjectNone )
       
   228     // Only SendObjectInfo/SendObjectPropList's request phase will enter into this function,
       
   229     // otherwise, state machine of fw should be wrong.
       
   230         {
       
   231         iElementCount = sizeof( KMTPSendObjectInfoPolicy ) / sizeof( TMTPRequestElementInfo );
       
   232         iElements = KMTPSendObjectInfoPolicy;
       
   233         }
       
   234     else if ( iProgress == EObjectInfoSucceed )
       
   235         {
       
   236         iElementCount = 0;
       
   237         iElements = NULL;
       
   238         }
       
   239 
       
   240     if ( iElements != NULL )
       
   241         {
       
   242         responseCode = CRequestProcessor::CheckRequestL();
       
   243         if ( responseCode != EMTPRespCodeOK )
       
   244             {
       
   245             return responseCode;
       
   246             }
       
   247 
       
   248         // Reserve storageId and parent into member data variables if they are matched.
       
   249         responseCode = MatchStoreAndParentL();
       
   250         if ( responseCode != EMTPRespCodeOK )
       
   251             {
       
   252             return responseCode;
       
   253             }
       
   254 
       
   255         if ( iOperationCode == EMTPOpCodeSendObjectPropList )
       
   256             {
       
   257             // check if it is what dp supported
       
   258             iObjectFormat = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
       
   259             if ( iObjectFormat != KMTPFormatsAll )
       
   260                 {
       
   261                 responseCode = EMTPRespCodeInvalidObjectFormatCode;
       
   262 
       
   263                 const RArray<TUint>* format = iDpConfig.GetSupportedFormat();
       
   264                 TInt count = format->Count();
       
   265 
       
   266                 for ( TInt i = 0; i < count; i++ )
       
   267                     {
       
   268                     if ( iObjectFormat == ( *format )[i] )
       
   269                         {
       
   270                         responseCode = EMTPRespCodeOK;
       
   271                         break;
       
   272                         }
       
   273                     }
       
   274                 if ( responseCode != EMTPRespCodeOK )
       
   275                     {
       
   276                     return responseCode;
       
   277                     }
       
   278                 } // end of if ( iObjectFormat != KMTPFormatsAll )
       
   279 
       
   280             // check object size
       
   281             TUint32 objectSizeHigh = Request().Uint32( TMTPTypeRequest::ERequestParameter4 );
       
   282             TUint32 objectSizeLow = Request().Uint32( TMTPTypeRequest::ERequestParameter5 );
       
   283             iObjectSize = MAKE_TUINT64( objectSizeHigh, objectSizeLow );
       
   284             PRINT1( _L( "MM MTP <> CSendObject::CheckRequestL iObjectSize = %Lu" ), iObjectSize );
       
   285 
       
   286             if ( IsTooLarge( iObjectSize ) )
       
   287                 {
       
   288                 responseCode = EMTPRespCodeObjectTooLarge;
       
   289                 }
       
   290 
       
   291             if ( ( responseCode != EMTPRespCodeOK ) && !CanStoreFileL( iStorageId, iObjectSize ) )
       
   292                 {
       
   293                 responseCode = EMTPRespCodeStoreFull;
       
   294                 }
       
   295             }
       
   296         }
       
   297 
       
   298     PRINT1( _L( "MM MTP <= CSendObject::CheckRequestL, responseCode = 0x%x" ), responseCode );
       
   299     return responseCode;
       
   300     }
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // CSendObject::HasDataphase
       
   304 // Exception handling. CRequestProcessor will receive data if this operation
       
   305 // won't by return ETrue.
       
   306 // @return ETrue if there is data need to be received from initiator
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 EXPORT_C TBool CSendObject::HasDataphase() const
       
   310     {
       
   311     return ETrue;
       
   312     }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // CSendObject::ServiceL
       
   316 // ServiceL request handler
       
   317 // -----------------------------------------------------------------------------
       
   318 //
       
   319 EXPORT_C void CSendObject::ServiceL()
       
   320     {
       
   321     PRINT( _L( "MM MTP => CSendObject::ServiceL" ) );
       
   322 
       
   323     if ( iProgress == EObjectNone )
       
   324         {
       
   325         if ( iOperationCode == EMTPOpCodeSendObjectInfo )
       
   326             {
       
   327             ServiceInfoL();
       
   328             }
       
   329         else
       
   330             {
       
   331             ServicePropListL();
       
   332             }
       
   333         }
       
   334     else
       
   335         {
       
   336         PRINT1( _L( "MM MTP <> CSendObject::ServiceL, iProgress = %d" ), iProgress );
       
   337         ServiceObjectL();
       
   338         }
       
   339     PRINT( _L( "MM MTP <= CSendObject::ServiceL" ) );
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CSendObject::ServiceInfoL
       
   344 // ServiceL - Recieves the objectinfo data
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 void CSendObject::ServiceInfoL()
       
   348     {
       
   349     PRINT( _L( "MM MTP => CSendObject::ServiceInfoL" ) );
       
   350 
       
   351     iObjectInfo = CMTPTypeObjectInfo::NewL();
       
   352     ReceiveDataL( *iObjectInfo );
       
   353     iProgress = EObjectInfoInProgress;
       
   354 
       
   355     PRINT( _L( "MM MTP <= CSendObject::ServiceInfoL" ) );
       
   356     }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // CSendObject::ServicePropListL
       
   360 // SendObjectPropList
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 void CSendObject::ServicePropListL()
       
   364     {
       
   365     PRINT( _L( "MM MTP => CSendObject::ServicePropListL" ) );
       
   366 
       
   367     iObjectPropList = CMTPTypeObjectPropList::NewL();
       
   368     ReceiveDataL( *iObjectPropList );
       
   369     iProgress = EObjectInfoInProgress;
       
   370 
       
   371     PRINT( _L( "MM MTP <= CSendObject::ServicePropListL" ) );
       
   372     }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // CSendObject::ServiceObjectL
       
   376 // SendObject
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 void CSendObject::ServiceObjectL()
       
   380     {
       
   381     PRINT( _L( "MM MTP => CSendObject::ServiceObjectL" ) );
       
   382 
       
   383     delete iFileReceived;
       
   384     iFileReceived = NULL;
       
   385 
       
   386     PRINT2( _L( "MM MTP <> CSendObject::ServiceObjectL, iFullPath is %S, iObjectSize: %Lu" ), &iFullPath, iObjectSize );
       
   387     TRAPD( err, iFileReceived = CMTPTypeFile::NewL( iFs,
       
   388         iFullPath,
       
   389         EFileWrite ) );
       
   390 
       
   391     PRINT1( _L("MM MTP <> CSendObject::ServiceObjectL, Leave Code is: %d"), err );
       
   392     User::LeaveIfError( err );
       
   393 
       
   394     iFileReceived->SetSizeL( iObjectSize );
       
   395 
       
   396     ReceiveDataL( *iFileReceived );
       
   397 
       
   398     iProgress = ESendObjectInProgress;
       
   399 
       
   400     PRINT( _L( "MM MTP <= CSendObject::ServiceObjectL" ) );
       
   401     }
       
   402 
       
   403 // -----------------------------------------------------------------------------
       
   404 // CSendObject::DoHandleResponsePhaseL
       
   405 // Response Phase Handler
       
   406 // -----------------------------------------------------------------------------
       
   407 //
       
   408 EXPORT_C TBool CSendObject::DoHandleResponsePhaseL()
       
   409     {
       
   410     PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseL" ) );
       
   411 
       
   412     // check if the sending/receiving data is successful
       
   413     TBool successful = !iCancelled;
       
   414     if ( iProgress == EObjectInfoInProgress )
       
   415         {
       
   416         if ( iOperationCode == EMTPOpCodeSendObjectInfo )
       
   417             {
       
   418             successful = DoHandleResponsePhaseInfoL();
       
   419             }
       
   420         else if ( iOperationCode == EMTPOpCodeSendObjectPropList )
       
   421             {
       
   422             successful = DoHandleResponsePhasePropListL();
       
   423             }
       
   424         iProgress = ( successful ? EObjectInfoSucceed : EObjectInfoFail );
       
   425         iPreviousOperation = iOperationCode;
       
   426         }
       
   427     else if ( iProgress == ESendObjectInProgress )
       
   428         {
       
   429         successful = DoHandleResponsePhaseObjectL();
       
   430         iProgress = ( successful ? ESendObjectSucceed : ESendObjectFail );
       
   431         }
       
   432     PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseL iProgress = %d" ), iProgress );
       
   433 
       
   434     return EFalse;
       
   435     }
       
   436 
       
   437 // -----------------------------------------------------------------------------
       
   438 // CSendObject::DoHandleResponsePhaseInfoL
       
   439 // Handle Response - Checks whether the request was successful
       
   440 // -----------------------------------------------------------------------------
       
   441 //
       
   442 TBool CSendObject::DoHandleResponsePhaseInfoL()
       
   443     {
       
   444     PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseInfoL" ) );
       
   445 
       
   446     TBool result = ETrue;
       
   447 
       
   448     // cache the width and height of video file
       
   449     iObjectFormat = iObjectInfo->Uint16L( CMTPTypeObjectInfo::EObjectFormat );
       
   450     iWidth = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EImagePixWidth );
       
   451     iHeight = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EImagePixWidth );
       
   452     PRINT3( _L("MM MTP <> CSendObject::DoHandleResponsePhaseInfoL iObjectFormat = 0x%x, iWidth = %d, iHeight = %d"),
       
   453         iObjectFormat,
       
   454         iWidth,
       
   455         iHeight );
       
   456 
       
   457     // TODO: dateModified is reserved for extention usage.
       
   458     delete iDateMod;
       
   459     iDateMod = NULL;
       
   460     iDateMod = iObjectInfo->StringCharsL( CMTPTypeObjectInfo::EDateModified ).AllocL();
       
   461 
       
   462     // check if storage is full
       
   463     iObjectSize = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EObjectCompressedSize );
       
   464     PRINT1( _L("MM MTP <> CSendObject::DoHandleResponsePhaseInfoL, iObjectSize = %Lu"), iObjectSize );
       
   465 
       
   466     if ( IsTooLarge( iObjectSize ) )
       
   467         {
       
   468         SendResponseL( EMTPRespCodeObjectTooLarge );
       
   469         result = EFalse;
       
   470         }
       
   471 
       
   472     if ( result && !CanStoreFileL( iStorageId, iObjectSize ) )
       
   473         {
       
   474         SendResponseL( EMTPRespCodeStoreFull );
       
   475         result = EFalse;
       
   476         }
       
   477 
       
   478     if ( result )
       
   479         {
       
   480         iProtectionStatus = iObjectInfo->Uint16L( CMTPTypeObjectInfo::EProtectionStatus );
       
   481         PRINT1( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseInfoL iProtectionStatus = %d" ), iProtectionStatus );
       
   482         if ( iProtectionStatus != EMTPProtectionNoProtection
       
   483             && iProtectionStatus != EMTPProtectionReadOnly )
       
   484             {
       
   485             SendResponseL( EMTPRespCodeParameterNotSupported );
       
   486             result = EFalse;
       
   487             }
       
   488         }
       
   489 
       
   490     if ( result )
       
   491         {
       
   492         result = GetFullPathNameL( iObjectInfo->StringCharsL( CMTPTypeObjectInfo::EFilename ) );
       
   493         if ( !result )
       
   494             {
       
   495             // File and/or parent pathname invalid.
       
   496             SendResponseL( EMTPRespCodeInvalidDataset );
       
   497             }
       
   498         }
       
   499 
       
   500     if ( result )
       
   501         {
       
   502         if ( ExistsL( iFullPath ) )
       
   503             {
       
   504             // Object with the same name already exists.
       
   505             iNoRollback = ETrue;
       
   506             SendResponseL( EMTPRespCodeAccessDenied );
       
   507             result = EFalse;
       
   508             }
       
   509         }
       
   510 
       
   511     if ( result )
       
   512         ReserveObjectL();
       
   513 
       
   514     PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseInfoL result = %d" ), result );
       
   515 
       
   516     return result;
       
   517     }
       
   518 
       
   519 // -----------------------------------------------------------------------------
       
   520 // CSendObject::DoHandleResponsePhasePropListL
       
   521 // SendObjectPropList
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 TBool CSendObject::DoHandleResponsePhasePropListL()
       
   525     {
       
   526     PRINT( _L("MM MTP => CSendObject::DoHandleResponsePhasePropListL" ) );
       
   527 
       
   528     TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   529 
       
   530     TInt invalidParameterIndex = KErrNotFound;
       
   531     responseCode = VerifyObjectPropListL( invalidParameterIndex );
       
   532 
       
   533     if ( responseCode != EMTPRespCodeOK )
       
   534         {
       
   535         TUint32 parameters[4];
       
   536         parameters[0] = 0;
       
   537         parameters[1] = 0;
       
   538         parameters[2] = 0;
       
   539         parameters[3] = invalidParameterIndex;
       
   540         SendResponseL( responseCode, 4, parameters );
       
   541         }
       
   542     else if ( ExistsL( iFullPath ) )
       
   543         {
       
   544         // Object with the same name already exists.
       
   545         iNoRollback = ETrue;
       
   546         SendResponseL( EMTPRespCodeAccessDenied );
       
   547         }
       
   548     else
       
   549         ReserveObjectL();
       
   550 
       
   551     PRINT( _L( "MM MTP <= CSendObject::DoHandleResponsePhasePropListL" ) );
       
   552     return ( responseCode == EMTPRespCodeOK );
       
   553     }
       
   554 
       
   555 // -----------------------------------------------------------------------------
       
   556 // CSendObject::DoHandleResponsePhaseObjectL
       
   557 // SendObject
       
   558 // -----------------------------------------------------------------------------
       
   559 //
       
   560 TBool CSendObject::DoHandleResponsePhaseObjectL()
       
   561     {
       
   562     PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseObjectL" ) );
       
   563 
       
   564     TBool result = ETrue;
       
   565 
       
   566     delete iFileReceived;
       
   567     iFileReceived = NULL;
       
   568 
       
   569     TEntry fileEntry;
       
   570     User::LeaveIfError( iFs.Entry( iFullPath, fileEntry ) );
       
   571     if ( fileEntry.iSize != iObjectSize )
       
   572         {
       
   573         iFs.Delete( iFullPath );
       
   574         iObjectMgr.UnreserveObjectHandleL( *iReceivedObjectInfo );
       
   575         TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge;
       
   576         if ( fileEntry.iSize < iObjectSize )
       
   577             {
       
   578             responseCode = EMTPRespCodeIncompleteTransfer;
       
   579             }
       
   580         SendResponseL( responseCode );
       
   581         result = EFalse;
       
   582         }
       
   583 
       
   584     // SendObject is cancelled or connection is dropped.
       
   585     if ( result && iCancelled )
       
   586         {
       
   587         iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest,
       
   588             iConnection );
       
   589         Rollback();
       
   590         SendResponseL( EMTPRespCodeTransactionCancelled );
       
   591         }
       
   592     else if ( result && !iCancelled )
       
   593         {
       
   594         if ( iObjectSize > 0 ) // media file
       
   595             {
       
   596             AddMediaToStoreL();
       
   597 
       
   598             if( iPreviousOperation == EMTPOpCodeSendObjectPropList )
       
   599                 {
       
   600                 SetObjectPropListL( *iObjectPropList );
       
   601                 }
       
   602 
       
   603             // Commits into MTP data object enumeration store the object handle and
       
   604             // storage space previously reserved for the specified object.
       
   605             iFramework.ObjectMgr().CommitReservedObjectHandleL( *iReceivedObjectInfo );
       
   606             }
       
   607 
       
   608         // Commit object to MTP data store
       
   609         iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest,
       
   610             iConnection );
       
   611 
       
   612         SendResponseL( EMTPRespCodeOK );
       
   613         }
       
   614 
       
   615     PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseObjectL result = %d" ), result );
       
   616 
       
   617     return result;
       
   618     }
       
   619 
       
   620 // -----------------------------------------------------------------------------
       
   621 // CSendObject::DoHandleCompletingPhaseL
       
   622 // Completeing phase Handler
       
   623 // -----------------------------------------------------------------------------
       
   624 //
       
   625 EXPORT_C TBool CSendObject::DoHandleCompletingPhaseL()
       
   626     {
       
   627     TBool result = ETrue;
       
   628 
       
   629     PRINT( _L( "MM MTP => CSendObject::DoHandleCompletingPhaseL" ) );
       
   630 
       
   631     CRequestProcessor::DoHandleCompletingPhaseL();
       
   632     //Ensure that, even though the SendObjectInfo was successul, the request responder is not deleted
       
   633     if ( iProgress == EObjectInfoSucceed )
       
   634         {
       
   635         result = EFalse;
       
   636         }
       
   637     else if ( iProgress == ESendObjectFail )
       
   638         {
       
   639         //Sending Object failed, but still do not delete request, can try again with current info
       
   640         iProgress = EObjectInfoSucceed;
       
   641         result = EFalse;
       
   642         }
       
   643 
       
   644     PRINT2( _L( "MM MTP <= CSendObject::DoHandleCompletingPhaseL iProgress= %d, result = %d" ),
       
   645         iProgress,
       
   646         result );
       
   647 
       
   648     return result;
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // Check if the property list is valid and extract necessary properties
       
   653 // @param aInvalidParameterIndex if invalid, contains the index of the property.
       
   654 //        Undefined, if it is valid.
       
   655 // @return if error, one of the error response code; otherwise EMTPRespCodeOK
       
   656 // -----------------------------------------------------------------------------
       
   657 TMTPResponseCode CSendObject::VerifyObjectPropListL( TInt& aInvalidParameterIndex )
       
   658     {
       
   659     PRINT( _L( "MM MTP => CSendObject::VerifyObjectPropListL" ) );
       
   660 
       
   661     TMTPResponseCode responseCode( EMTPRespCodeOK );
       
   662     const TInt count = iObjectPropList->NumberOfElements();
       
   663     iObjectPropList->ResetCursor();
       
   664     for ( TInt i = 0; i < count; i++ )
       
   665         {
       
   666         const CMTPTypeObjectPropListElement& element( iObjectPropList->GetNextElementL() );
       
   667         const TUint32 handle( element.Uint32L( CMTPTypeObjectPropListElement::EObjectHandle ) );
       
   668         aInvalidParameterIndex = i;
       
   669         if ( handle != KMTPHandleNone )
       
   670             {
       
   671             responseCode = EMTPRespCodeInvalidObjectHandle;
       
   672             break;
       
   673             }
       
   674 
       
   675         responseCode = CheckPropCodeL( element );
       
   676         if ( responseCode != EMTPRespCodeOK )
       
   677             {
       
   678             break;
       
   679             }
       
   680         responseCode = ExtractPropertyL( element );
       
   681         if ( responseCode != EMTPRespCodeOK )
       
   682             {
       
   683             break;
       
   684             }
       
   685         }
       
   686 
       
   687     PRINT1( _L( "MM MTP <= CSendObject::VerifyObjectPropListL, responseCode = 0x%X" ), responseCode );
       
   688     return responseCode;
       
   689     }
       
   690 
       
   691 // -----------------------------------------------------------------------------
       
   692 // Validates the data type for a given property code.
       
   693 // @param aElement an object property list element
       
   694 // @param aPropertyCode MTP property code for the element
       
   695 // @return EMTPRespCodeOK if the combination is valid, or another MTP response code if not
       
   696 // -----------------------------------------------------------------------------
       
   697 TMTPResponseCode CSendObject::CheckPropCodeL( const CMTPTypeObjectPropListElement& aElement )
       
   698     {
       
   699     PRINT( _L( "MM MTP => CSendObject::CheckPropCodeL" ) );
       
   700     TMTPResponseCode responseCode( EMTPRespCodeOK );
       
   701 
       
   702     // Checking if the propCode is supported first then check its type
       
   703     const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( iObjectFormat );
       
   704     TUint16 propCode = aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode );
       
   705     TUint16 dataType = aElement.Uint16L( CMTPTypeObjectPropListElement::EDatatype );
       
   706     PRINT2( _L( "MM MTP => CSendObject::CheckPropCodeL propCode = 0x%X, dataType = 0x%X" ), propCode, dataType );
       
   707 
       
   708     responseCode = EMTPRespCodeInvalidObjectPropCode;
       
   709     const TInt count = properties->Count();
       
   710     for ( TInt i = 0; i < count; i++ )
       
   711         {
       
   712         if ( ( *properties )[i] == propCode )
       
   713             {
       
   714             responseCode = EMTPRespCodeOK;
       
   715             break;
       
   716             }
       
   717         }
       
   718 
       
   719     if ( responseCode != EMTPRespCodeOK )
       
   720         return responseCode;
       
   721 
       
   722     // TODO: abstractmedia and media dp have different supported propCode, need check common prop code and check others in dp derived processors.
       
   723     // also need to check if the propCode is supported
       
   724     switch ( propCode )
       
   725         {
       
   726         case EMTPObjectPropCodeStorageID:
       
   727             if ( dataType != EMTPTypeUINT32 )
       
   728                 {
       
   729                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   730                 }
       
   731             else if ( iStorageId != aElement.Uint32L( CMTPTypeObjectPropListElement::EValue ) )
       
   732                 {
       
   733                 responseCode = EMTPRespCodeInvalidDataset;
       
   734                 }
       
   735             break;
       
   736 
       
   737         case EMTPObjectPropCodeObjectFormat:
       
   738             if ( dataType != EMTPTypeUINT16 )
       
   739                 {
       
   740                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   741                 }
       
   742             else if ( iObjectFormat != aElement.Uint16L( CMTPTypeObjectPropListElement::EValue ) )
       
   743                 {
       
   744                 responseCode = EMTPRespCodeInvalidDataset;
       
   745                 }
       
   746             break;
       
   747 
       
   748         case EMTPObjectPropCodeObjectSize:
       
   749             if ( dataType != EMTPTypeUINT64 )
       
   750                 {
       
   751                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   752                 }
       
   753             else if ( iObjectSize != aElement.Uint64L( CMTPTypeObjectPropListElement::EValue ) )
       
   754                 {
       
   755                 responseCode = EMTPRespCodeInvalidDataset;
       
   756                 }
       
   757             PRINT1(_L("MM MTP => CSendObject::CheckPropCodeL Checking ObjectSize %d"), responseCode );
       
   758             break;
       
   759 
       
   760         case EMTPObjectPropCodeParentObject:
       
   761             if ( dataType != EMTPTypeUINT32 )
       
   762                 {
       
   763                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   764                 }
       
   765             else if ( ( iParentHandle != aElement.Uint32L( CMTPTypeObjectPropListElement::EValue ) )
       
   766                 || ( KMTPHandleNone != aElement.Uint32L( CMTPTypeObjectPropListElement::EValue ) ) )
       
   767                 // iParentHandle might be changed in CheckRequestL
       
   768                 {
       
   769                 responseCode = EMTPRespCodeInvalidDataset;
       
   770                 }
       
   771             break;
       
   772 
       
   773         case EMTPObjectPropCodePersistentUniqueObjectIdentifier:    // read-only
       
   774             if ( dataType != EMTPTypeUINT128 )
       
   775                 {
       
   776                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   777                 }
       
   778             break;
       
   779 
       
   780         case EMTPObjectPropCodeProtectionStatus:
       
   781             if ( dataType != EMTPTypeUINT16 )
       
   782                 {
       
   783                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   784                 }
       
   785             break;
       
   786 
       
   787         case EMTPObjectPropCodeDateCreated:
       
   788             // TODO: this property is read-only, should response EMTPRespCodeAccessDenied or set nothing?
       
   789         case EMTPObjectPropCodeDateModified:
       
   790         case EMTPObjectPropCodeObjectFileName:
       
   791         case EMTPObjectPropCodeName:
       
   792             if ( dataType != EMTPTypeString )
       
   793                 {
       
   794                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   795                 }
       
   796             break;
       
   797 
       
   798         case EMTPObjectPropCodeNonConsumable:
       
   799             if ( dataType != EMTPTypeUINT8 )
       
   800                 {
       
   801                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   802                 }
       
   803             break;
       
   804 
       
   805         default:
       
   806             // check types of DP specific properties
       
   807             // TODO: Is there anything except datatype need to be checked?
       
   808             responseCode = CheckSepecificPropType( propCode, dataType );
       
   809             break;
       
   810         }
       
   811 
       
   812     PRINT1( _L( "MM MTP <= CSendObject::CheckPropCode, responseCode = 0x%X" ), responseCode );
       
   813     return responseCode;
       
   814     }
       
   815 
       
   816 // -----------------------------------------------------------------------------
       
   817 // Extracts the file information from the object property list element
       
   818 // @param aElement an object property list element
       
   819 // @param aPropertyCode MTP property code for the element
       
   820 // @return MTP response code
       
   821 // -----------------------------------------------------------------------------
       
   822 TMTPResponseCode CSendObject::ExtractPropertyL( const CMTPTypeObjectPropListElement& aElement )
       
   823     {
       
   824     PRINT( _L ( "MM MTP => CSendObject::ExtractPropertyL" ) );
       
   825     TMTPResponseCode responseCode( EMTPRespCodeOK );
       
   826     switch ( aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ) )
       
   827         {
       
   828         case EMTPObjectPropCodeObjectFileName:
       
   829             {
       
   830             const TDesC& fileName = aElement.StringL( CMTPTypeObjectPropListElement::EValue );
       
   831             if ( !GetFullPathNameL( fileName ) )
       
   832                 {
       
   833                 responseCode = EMTPRespCodeInvalidDataset;
       
   834                 }
       
   835             }
       
   836             break;
       
   837 
       
   838         case EMTPObjectPropCodeProtectionStatus:
       
   839             {
       
   840             iProtectionStatus = aElement.Uint16L( CMTPTypeObjectPropListElement::EValue );
       
   841             if ( iProtectionStatus != EMTPProtectionNoProtection
       
   842                 && iProtectionStatus != EMTPProtectionReadOnly )
       
   843                 {
       
   844                 responseCode = EMTPRespCodeParameterNotSupported;
       
   845                 }
       
   846             }
       
   847             break;
       
   848 
       
   849         case EMTPObjectPropCodeDateModified:
       
   850             delete iDateMod;
       
   851             iDateMod = NULL;
       
   852             iDateMod = aElement.StringL( CMTPTypeObjectPropListElement::EValue ).AllocL();
       
   853             // Cache it for further usage.
       
   854             break;
       
   855 
       
   856         default:
       
   857             // Only extract necessary properties which conform to SendObjectInfo.
       
   858             break;
       
   859         }
       
   860 
       
   861     PRINT1( _L( "MM MTP <= CSendObject::ExtractPropertyL, responseCode = 0x%X" ), responseCode );
       
   862     return responseCode;
       
   863     }
       
   864 
       
   865 // -----------------------------------------------------------------------------
       
   866 // CSendObject::SetObjectPropListL
       
   867 // Reserve object proplist into database
       
   868 // -----------------------------------------------------------------------------
       
   869 //
       
   870 TMTPResponseCode CSendObject::SetObjectPropListL( const CMTPTypeObjectPropList& aPropList )
       
   871     {
       
   872     PRINT( _L( "MM MTP => CSendObject::SetObjectPropListL" ) );
       
   873 
       
   874     TMTPResponseCode responseCode( EMTPRespCodeOK );
       
   875 
       
   876     const TUint count( iObjectPropList->NumberOfElements() );
       
   877     iObjectPropList->ResetCursor();
       
   878     for ( TInt i = 0; i < count; i++ )
       
   879         {
       
   880         const CMTPTypeObjectPropListElement& element( iObjectPropList->GetNextElementL() );
       
   881 
       
   882         TUint16 propertyCode = element.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode );
       
   883         TUint16 dataType = element.Uint16L( CMTPTypeObjectPropListElement::EDatatype );
       
   884         PRINT2( _L( "MM MTP <> SetObjectPropListL propertyCode = 0x%x, dataType = 0x%x" ),
       
   885             propertyCode, dataType );
       
   886 
       
   887         switch ( propertyCode )
       
   888             {
       
   889             case EMTPObjectPropCodeStorageID:
       
   890             case EMTPObjectPropCodeObjectFormat:
       
   891             case EMTPObjectPropCodeProtectionStatus:
       
   892             case EMTPObjectPropCodeObjectSize:
       
   893             case EMTPObjectPropCodeParentObject:
       
   894             case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
       
   895                 // Do nothing for those properties are already set.
       
   896                 break;
       
   897 
       
   898             case EMTPObjectPropCodeNonConsumable:
       
   899             case EMTPObjectPropCodeDateAdded:
       
   900             case EMTPObjectPropCodeDateCreated:
       
   901             case EMTPObjectPropCodeDateModified:
       
   902             case EMTPObjectPropCodeObjectFileName:
       
   903                 // TODO: Does anything need to be done on these read-only properties?
       
   904                 /* spec:
       
   905                  * Object properties that are get-only (0x00 GET)
       
   906                  * should accept values during object creation by
       
   907                  * way of the SendObjectPropList command.
       
   908                  */
       
   909                 break;
       
   910 
       
   911             case EMTPObjectPropCodeName:
       
   912                 {
       
   913                 CMTPTypeString* stringData = CMTPTypeString::NewLC( element.StringL( CMTPTypeObjectPropListElement::EValue ) );// + stringData
       
   914 
       
   915                 responseCode = SetMetaDataToWrapperL( propertyCode,
       
   916                     *stringData,
       
   917                     *iReceivedObjectInfo );
       
   918 
       
   919                 CleanupStack::PopAndDestroy( stringData );// - stringData
       
   920                 }
       
   921                 break;
       
   922 
       
   923             default:
       
   924                 {
       
   925                 responseCode = SetSpecificObjectPropertyL( propertyCode,
       
   926                     *iReceivedObjectInfo,
       
   927                     element );
       
   928                 }
       
   929                 break;
       
   930             } // end of switch
       
   931         } // end of for
       
   932 
       
   933     PRINT1( _L( "MM MTP <= CSendObject::SetObjectPropListL responseCode = 0x%x" ), responseCode );
       
   934     return responseCode;
       
   935     }
       
   936 
       
   937 // -----------------------------------------------------------------------------
       
   938 // CSendObject::SetMetaDataToWrapperL
       
   939 //
       
   940 // -----------------------------------------------------------------------------
       
   941 //
       
   942 EXPORT_C TMTPResponseCode CSendObject::SetMetaDataToWrapperL( const TUint16 aPropCode,
       
   943     MMTPType& aNewData,
       
   944     const CMTPObjectMetaData& aObjectMetaData )
       
   945     {
       
   946     TMTPResponseCode resCode = EMTPRespCodeOK;
       
   947     TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode,
       
   948             aNewData,
       
   949             aObjectMetaData ) );
       
   950 
       
   951     PRINT1( _L("MM MTP <> CSendObject::SetMetaDataToWrapperL err = %d"), err);
       
   952 
       
   953     if ( err == KErrNone )
       
   954         {
       
   955         resCode = EMTPRespCodeOK;
       
   956         }
       
   957     else if ( err == KErrTooBig )
       
   958     // according to the codes of S60
       
   959         {
       
   960         resCode = EMTPRespCodeInvalidDataset;
       
   961         }
       
   962     else if ( err == KErrPermissionDenied )
       
   963         {
       
   964         resCode = EMTPRespCodeAccessDenied;
       
   965         }
       
   966     else if ( err == KErrNotFound )
       
   967         {
       
   968         if ( MmMtpDpUtility::HasMetadata( aObjectMetaData.Uint( CMTPObjectMetaData::EFormatCode ) ) )
       
   969             SendResponseL( EMTPRespCodeAccessDenied );
       
   970         }
       
   971     else
       
   972         {
       
   973         err = HandleSpecificWrapperError( err, aObjectMetaData );
       
   974 
       
   975         if ( err != KErrNone )
       
   976             resCode = EMTPRespCodeGeneralError;
       
   977         }
       
   978 
       
   979     PRINT1( _L( "MM MTP <= CSendObject::SetMetaDataToWrapperL resCode = 0x%x" ), resCode );
       
   980 
       
   981     return resCode;
       
   982     }
       
   983 
       
   984 // -----------------------------------------------------------------------------
       
   985 // CSendObject::MatchStoreAndParentL
       
   986 // -----------------------------------------------------------------------------
       
   987 //
       
   988 TMTPResponseCode CSendObject::MatchStoreAndParentL()
       
   989     {
       
   990     TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   991 
       
   992     iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
       
   993     iParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
       
   994     PRINT2( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iStorageId = 0x%X, iParentHandle = 0x%X" ),
       
   995         iStorageId,
       
   996         iParentHandle );
       
   997 
       
   998     if ( iStorageId == KMTPStorageDefault )
       
   999         {
       
  1000         iStorageId = iDpConfig.GetDefaultStorageIdL();
       
  1001         PRINT1( _L( "MM MTP <> CSendObject::GetDefaultStorageIdL, iStorageId = 0x%X" ), iStorageId );
       
  1002         }
       
  1003 
       
  1004     delete iParentSuid;
       
  1005     iParentSuid = NULL;
       
  1006 
       
  1007     if( iParentHandle == KMTPHandleNone )   // parentHandle is not used by initiator, set it to root
       
  1008         {
       
  1009         iParentHandle = KMTPHandleAll;
       
  1010         }
       
  1011     if ( iParentHandle == KMTPHandleAll )   // According to spec, KMTPHandleAll means initiator wish to place in the root
       
  1012         {
       
  1013         PRINT( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iParentSuid = KMTPHandleAll" ) );
       
  1014         iParentSuid = iFramework.StorageMgr().StorageL( iStorageId ).DesC( CMTPStorageMetaData::EStorageSuid ).AllocL();
       
  1015         PRINT1( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iParentSuid = %S" ), iParentSuid );
       
  1016         }
       
  1017     else    // parentHandle is specified by initiator
       
  1018         {
       
  1019         // does not take owernship
       
  1020         CMTPObjectMetaData* parentObjInfo = iRequestChecker->GetObjectInfo( iParentHandle );
       
  1021         __ASSERT_DEBUG( parentObjInfo, Panic( EMmMTPDpObjectNull ) );
       
  1022 
       
  1023         if ( parentObjInfo->Uint( CMTPObjectMetaData::EStorageId ) != iStorageId )
       
  1024             {
       
  1025             responseCode = EMTPRespCodeInvalidObjectHandle;
       
  1026             PRINT( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, STORAGEID DOES NOT MATCH WITH PARENTHANDLE!" ) );
       
  1027             }
       
  1028         else
       
  1029             {
       
  1030             iParentSuid = parentObjInfo->DesC( CMTPObjectMetaData::ESuid ).AllocL();
       
  1031             }
       
  1032         }
       
  1033     PRINT1( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iParentSuid = %S" ), iParentSuid );
       
  1034 
       
  1035     if ( ( responseCode == EMTPRespCodeOK ) && !BaflUtils::PathExists( iFramework.Fs(), *iParentSuid ) )
       
  1036         {
       
  1037         responseCode = EMTPRespCodeInvalidDataset;
       
  1038         }
       
  1039 
       
  1040     return responseCode;
       
  1041     }
       
  1042 
       
  1043 // -----------------------------------------------------------------------------
       
  1044 // CSendObject::IsTooLarge
       
  1045 // Check if the object is too large
       
  1046 // @return ETrue if yes, otherwise EFalse
       
  1047 // -----------------------------------------------------------------------------
       
  1048 //
       
  1049 TBool CSendObject::IsTooLarge( TUint32 aObjectSize ) const
       
  1050     {
       
  1051     TBool ret = ( aObjectSize > KMaxTInt );
       
  1052     PRINT2( _L( "MM MTP <> CSendObject::IsTooLarge aObjectSize = %d, ret = %d" ), aObjectSize, ret );
       
  1053     return ret;
       
  1054     }
       
  1055 
       
  1056 // -----------------------------------------------------------------------------
       
  1057 // CSendObject::CanStoreFileL
       
  1058 // Check if we can store the file on the storage
       
  1059 // @return ETrue if yes, otherwise EFalse
       
  1060 // -----------------------------------------------------------------------------
       
  1061 //
       
  1062 TBool CSendObject::CanStoreFileL( TUint32 aStorageId,
       
  1063     TInt64 aObjectSize ) const
       
  1064     {
       
  1065     PRINT( _L( "MM MTP => CSendObject::CanStoreFileL" ) );
       
  1066 
       
  1067     TBool result = ETrue;
       
  1068     TVolumeInfo volumeInfo;
       
  1069     TInt driveNo = iFramework.StorageMgr().DriveNumber( aStorageId );
       
  1070     User::LeaveIfError( iFs.Volume( volumeInfo, driveNo ) );
       
  1071 
       
  1072     if ( volumeInfo.iFree < aObjectSize )
       
  1073         {
       
  1074         result = EFalse;
       
  1075         }
       
  1076 
       
  1077     PRINT1( _L( "MM MTP <= CSendObject::CanStoreFileL , result = %d" ), result );
       
  1078 
       
  1079     return result;
       
  1080     }
       
  1081 
       
  1082 // -----------------------------------------------------------------------------
       
  1083 // CSendObject::GetFullPathNameL
       
  1084 // Get the full path name of the object to be saved
       
  1085 // @param aFileName, on entry, contains the file name of the object,
       
  1086 // on return, contains the full path name of the object to be saved
       
  1087 // -----------------------------------------------------------------------------
       
  1088 //
       
  1089 TBool CSendObject::GetFullPathNameL( const TDesC& aFileName )
       
  1090     {
       
  1091     PRINT1( _L("MM MTP => CSendObject::GetFullPathNameL aFileName = %S"), &aFileName );
       
  1092 
       
  1093     TBool result( EFalse );
       
  1094     if ( aFileName.Length() > 0 )
       
  1095         {
       
  1096         iFullPath.Zero();
       
  1097         iFullPath.Append( *iParentSuid );
       
  1098         if ( ( iFullPath.Length() + aFileName.Length() ) < KMaxFileName )
       
  1099             {
       
  1100             iFullPath.Append( aFileName );
       
  1101             PRINT1( _L( "MM MTP <> CSendObject::GetFullPathNameL iFullPath = %S" ), &iFullPath );
       
  1102             result = iFramework.Fs().IsValidName( iFullPath );
       
  1103             }
       
  1104         }
       
  1105     if ( result && ( iObjectFormat != MmMtpDpUtility::FormatFromFilename( iFullPath ) ) )
       
  1106         {
       
  1107         PRINT2( _L( "MM MTP <> %S does not match 0x%x" ), &iFullPath, iObjectFormat );
       
  1108         result = EFalse;
       
  1109         }
       
  1110 
       
  1111     PRINT1( _L( "MM MTP <= CSendObject::GetFullPathNameL result = %d" ), result );
       
  1112 
       
  1113     return result;
       
  1114     }
       
  1115 
       
  1116 // -----------------------------------------------------------------------------
       
  1117 // CSendObject::ExistsL
       
  1118 // Check if the file already exists on the storage.
       
  1119 // -----------------------------------------------------------------------------
       
  1120 //
       
  1121 TBool CSendObject::ExistsL( const TDesC& aName ) const
       
  1122     {
       
  1123     PRINT1( _L( "MM MTP => CSendObject::Exists aName = %S" ), &aName );
       
  1124     // This detects both files and folders
       
  1125     TBool ret( EFalse );
       
  1126     ret = BaflUtils::FileExists( iFramework.Fs(), aName );
       
  1127 
       
  1128 #ifdef MMMTPDP_REPLACE_EXIST_FILE
       
  1129     if( ret )
       
  1130         {
       
  1131         // delete the old one and replace
       
  1132         TInt delErr = iFramework.Fs().Delete( aName );
       
  1133         PRINT1( _L( "MM MTP <> CSendObject::Exists delErr = %d" ), delErr );
       
  1134         // delete from the metadata DB
       
  1135         TRAPD( err, iFramework.ObjectMgr().RemoveObjectL( aName ) );
       
  1136         PRINT1( _L( "MM MTP <> CSendObject::Exists err = %d" ), err );
       
  1137         if( err == KErrNone )
       
  1138             {
       
  1139             // do nothing, ignore warning
       
  1140             }
       
  1141         // delete from video/mpx DB
       
  1142         CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
       
  1143         if ( iFramework.ObjectMgr().ObjectL( aName, *objectInfo ) )
       
  1144             {
       
  1145             TRAP_IGNORE( iWrapper.DeleteObjectL( aName,
       
  1146                     objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) );
       
  1147             }
       
  1148         CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
       
  1149         ret = EFalse;
       
  1150         }
       
  1151 #endif
       
  1152     PRINT1( _L( "MM MTP <= CSendObject::Exists ret = %d" ), ret );
       
  1153     return ret;
       
  1154     }
       
  1155 
       
  1156 // -----------------------------------------------------------------------------
       
  1157 // CSendObject::ReserveObjectL
       
  1158 // -----------------------------------------------------------------------------
       
  1159 //
       
  1160 void CSendObject::ReserveObjectL()
       
  1161     {
       
  1162     PRINT( _L( "MM MTP => CSendObject::ReserveObjectL" ) );
       
  1163     TInt err = KErrNone;
       
  1164 
       
  1165     iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
       
  1166     iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EParentHandle,
       
  1167         iParentHandle );
       
  1168     iReceivedObjectInfo->SetDesCL( CMTPObjectMetaData::ESuid, iFullPath );
       
  1169     iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EFormatCode,
       
  1170         iObjectFormat );
       
  1171 
       
  1172     // Reserves space for and assigns an object handle to the object described
       
  1173     // by the specified object information record.
       
  1174     TRAP( err, iObjectMgr.ReserveObjectHandleL( *iReceivedObjectInfo,
       
  1175                 iObjectSize ) );
       
  1176 
       
  1177     PRINT2( _L( "MM MTP => CSendObject::ReserveObjectL iObjectsize = %Lu, Operation: 0x%x" ), iObjectSize, iOperationCode );
       
  1178     if ( err != KErrNone )
       
  1179         PRINT1( _L( "MM MTP <> CSendObject::ReserveObjectL err = %d" ), err );
       
  1180     if ( iObjectSize == 0 )
       
  1181         {
       
  1182         SaveEmptyFileL();
       
  1183         iObjectMgr.CommitReservedObjectHandleL( *iReceivedObjectInfo );
       
  1184         }
       
  1185 
       
  1186     iExpectedSendObjectRequest.SetUint32( TMTPTypeRequest::ERequestSessionID,
       
  1187         iSessionId );
       
  1188     iFramework.RouteRequestRegisterL( iExpectedSendObjectRequest, iConnection );
       
  1189 
       
  1190     TUint32 parameters[3];
       
  1191     parameters[0] = iStorageId;
       
  1192     parameters[1] = iParentHandle;
       
  1193     parameters[2] = iReceivedObjectInfo->Uint( CMTPObjectMetaData::EHandle );
       
  1194     SendResponseL( EMTPRespCodeOK, 3, parameters );
       
  1195 
       
  1196     PRINT( _L( "MM MTP <= CSendObject::ReserveObjectL" ) );
       
  1197     }
       
  1198 
       
  1199 // -----------------------------------------------------------------------------
       
  1200 // CSendObject::SetProtectionStatusL
       
  1201 // -----------------------------------------------------------------------------
       
  1202 //
       
  1203 void CSendObject::SetProtectionStatusL()
       
  1204     {
       
  1205     PRINT1( _L( "MM MTP => CSendObject::SetProtectionStatusL iProtectionStatus = %d" ), iProtectionStatus );
       
  1206 
       
  1207     if ( iProtectionStatus == EMTPProtectionNoProtection
       
  1208         || iProtectionStatus == EMTPProtectionReadOnly )
       
  1209         {
       
  1210         // TODO: wait for review
       
  1211         TInt err = KErrNone;
       
  1212         if ( iProtectionStatus == EMTPProtectionNoProtection )
       
  1213             {
       
  1214             iFs.SetAtt( iFullPath, KEntryAttNormal, KEntryAttReadOnly );
       
  1215             }
       
  1216         else
       
  1217             {
       
  1218             iFs.SetAtt( iFullPath, KEntryAttReadOnly, KEntryAttNormal );
       
  1219             }
       
  1220         User::LeaveIfError( err );
       
  1221         }
       
  1222     PRINT( _L( "MM MTP <= CSendObject::SetProtectionStatusL" ) );
       
  1223     }
       
  1224 
       
  1225 // -----------------------------------------------------------------------------
       
  1226 // CSendObject::SaveEmptyFileL
       
  1227 // -----------------------------------------------------------------------------
       
  1228 //
       
  1229 void CSendObject::SaveEmptyFileL()
       
  1230     {
       
  1231     PRINT( _L( "MM MTP => CSendObject::SaveEmptyFileL" ) );
       
  1232 
       
  1233     RFile file;
       
  1234     User::LeaveIfError( file.Create( iFs, iFullPath, EFileWrite ) );
       
  1235     file.Close();
       
  1236 
       
  1237     // set entry protection status and modified date
       
  1238     SetProtectionStatusL();
       
  1239 
       
  1240     // add playlist to MPX DB
       
  1241     TParsePtrC parse( iFullPath );
       
  1242     iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() );
       
  1243     iDpConfig.GetWrapperL().AddObjectL( iFullPath );
       
  1244 
       
  1245     if ( EMTPFormatCodeAbstractAudioVideoPlaylist == iObjectFormat )
       
  1246         {
       
  1247         TInt err = KErrNone;
       
  1248         err = iFs.SetAtt( iFullPath,
       
  1249             KEntryAttSystem | KEntryAttHidden,
       
  1250             KEntryAttReadOnly | KEntryAttNormal );
       
  1251         if ( err != KErrNone )
       
  1252             PRINT1( _L( "MM MTP <> CSendObject::SaveEmptyFileL err = %d" ), err );
       
  1253         iDpConfig.GetWrapperL().AddDummyFileL( iFullPath );
       
  1254         }
       
  1255 
       
  1256     PRINT( _L( "MM MTP <= CSendObject::SaveEmptyFileL" ) );
       
  1257     }
       
  1258 
       
  1259 // -----------------------------------------------------------------------------
       
  1260 // CSendObject::AddMediaToStoreL()
       
  1261 //
       
  1262 // -----------------------------------------------------------------------------
       
  1263 //
       
  1264 void CSendObject::AddMediaToStoreL()
       
  1265     {
       
  1266     PRINT( _L( "MM MTP => CSendObject::AddMediaToStoreL" ) );
       
  1267 
       
  1268     TBool isVideo = EFalse;
       
  1269     switch ( iObjectFormat )
       
  1270         {
       
  1271         case EMTPFormatCode3GPContainer:
       
  1272         case EMTPFormatCodeMP4Container:
       
  1273         case EMTPFormatCodeASF:
       
  1274             {
       
  1275             TMmMtpSubFormatCode subFormatCode;
       
  1276 
       
  1277             if ( MmMtpDpUtility::IsVideoL( iFullPath ) )
       
  1278                 {
       
  1279                 subFormatCode = EMTPSubFormatCodeVideo;
       
  1280                 isVideo = ETrue;
       
  1281                 }
       
  1282             else
       
  1283                 {
       
  1284                 subFormatCode = EMTPSubFormatCodeAudio;
       
  1285                 isVideo = EFalse;
       
  1286                 }
       
  1287 
       
  1288             iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EFormatSubCode,
       
  1289                 ( TUint ) subFormatCode );
       
  1290             }
       
  1291             break;
       
  1292 
       
  1293             // put all just video format codes here
       
  1294         case EMTPFormatCodeWMV:
       
  1295             {
       
  1296             isVideo = ETrue;
       
  1297             }
       
  1298             break;
       
  1299 
       
  1300         default:
       
  1301             PRINT( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseObjectL default" ) );
       
  1302             break;
       
  1303         }
       
  1304 
       
  1305     TPtrC suid( iReceivedObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
       
  1306     PRINT1( _L( "MM MTP <> CSendObject::AddMediaToStoreL suid = %S" ), &suid );
       
  1307     TParsePtrC parse( suid );
       
  1308     iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() );
       
  1309     iDpConfig.GetWrapperL().AddObjectL( iFullPath, isVideo );
       
  1310 
       
  1311     if ( isVideo )
       
  1312         {
       
  1313         TInt err = KErrNone;
       
  1314             TRAP( err, iDpConfig.GetWrapperL().SetImageObjPropL( iFullPath, iWidth, iHeight ) );
       
  1315 
       
  1316         PRINT1( _L( "MM MTP <= CSendObject::AddVideoToStoreL err = %d" ), err );
       
  1317         }
       
  1318 
       
  1319     PRINT( _L( "MM MTP <= CSendObject::AddMediaToStoreL" ) );
       
  1320     }
       
  1321 
       
  1322 // -----------------------------------------------------------------------------
       
  1323 // CSendObject::UsbDisconnect
       
  1324 //
       
  1325 // -----------------------------------------------------------------------------
       
  1326 //
       
  1327 EXPORT_C void CSendObject::UsbDisconnect()
       
  1328     {
       
  1329     PRINT( _L( "MM MTP => CSendObject::UsbDisconnect" ) );
       
  1330     Rollback();
       
  1331     PRINT( _L( "MM MTP <= CSendObject::UsbDisconnect" ) );
       
  1332     }
       
  1333 
       
  1334 // -----------------------------------------------------------------------------
       
  1335 // CSendObject::Rollback()
       
  1336 // delete the file, which transfer incompletely
       
  1337 // -----------------------------------------------------------------------------
       
  1338 //
       
  1339 void CSendObject::Rollback()
       
  1340     {
       
  1341     // Delete this object from file system.
       
  1342     if ( iProgress == ESendObjectInProgress )
       
  1343         {
       
  1344         PRINT1( _L( "MM MTP <> CSendObject::Rollback ROLLBACK_FILE %S" ), &iFullPath );
       
  1345         iFramework.Fs().Delete( iFullPath );
       
  1346             TRAP_IGNORE( iFramework.ObjectMgr().UnreserveObjectHandleL( *iReceivedObjectInfo ) );
       
  1347         iProgress = EObjectNone;
       
  1348         }
       
  1349     }
       
  1350 
       
  1351 // end of file