mtpdataproviders/mtppictbridgedp/src/cmtppictbridgedpsendobjectinfo.cpp
changeset 0 d0791faffa3f
child 11 4843bb5893b6
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #include <f32file.h>
       
    18 #include <bautils.h>
       
    19 #include <mtp/mmtpdataproviderframework.h>
       
    20 #include <mtp/cmtpobjectmetadata.h>
       
    21 #include <mtp/cmtptypefile.h>
       
    22 #include <mtp/cmtptypeobjectinfo.h>
       
    23 #include <mtp/cmtptypeobjectproplist.h>
       
    24 #include <mtp/cmtptypestring.h>
       
    25 #include <mtp/mmtpobjectmgr.h>
       
    26 #include <mtp/mmtpstoragemgr.h>
       
    27 #include <mtp/mtpprotocolconstants.h>
       
    28 #include <mtp/mmtpconnection.h>
       
    29 #include <mtp/tmtptyperequest.h>
       
    30 #include "ptpdef.h"
       
    31 #include "cmtppictbridgedpsendobjectinfo.h"
       
    32 #include "mtppictbridgedppanic.h"
       
    33 #include "mtppictbridgedpconst.h"
       
    34 #include "cmtppictbridgeprinter.h"
       
    35 #include "cptpserver.h"
       
    36 #include "cmtpconnection.h"
       
    37 #include "cmtpconnectionmgr.h"
       
    38 
       
    39 /**
       
    40 Verification data for the SendObjectInfo request
       
    41 */
       
    42 const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] = 
       
    43     {
       
    44     {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeStorageId, EMTPElementAttrWrite, 1, 0, 0},                
       
    45     {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeObjectHandle, EMTPElementAttrWrite, 2, KMTPHandleAll, KMTPHandleNone}
       
    46     };
       
    47 
       
    48 
       
    49 /**
       
    50 Two-phase construction method
       
    51 @param aFramework  The data provider framework
       
    52 @param aConnection The connection from which the request comes
       
    53 @return a pointer to the created request processor object
       
    54 */ 
       
    55 MMTPRequestProcessor* CMTPPictBridgeDpSendObjectInfo::NewL(
       
    56     MMTPDataProviderFramework& aFramework,
       
    57     MMTPConnection& aConnection,
       
    58     CMTPPictBridgeDataProvider& aDataProvider)
       
    59     {
       
    60     CMTPPictBridgeDpSendObjectInfo* self = new (ELeave) CMTPPictBridgeDpSendObjectInfo(aFramework, aConnection, aDataProvider);
       
    61     CleanupStack::PushL(self);
       
    62     self->ConstructL();
       
    63     CleanupStack::Pop(self);
       
    64     return self;
       
    65     }
       
    66 
       
    67 /**
       
    68 Destructor
       
    69 */    
       
    70 CMTPPictBridgeDpSendObjectInfo::~CMTPPictBridgeDpSendObjectInfo()
       
    71     {
       
    72     __FLOG_VA((_L8(">> CMTPPictBridgeDpSendObjectInfo::~CMTPPictBridgeDpSendObjectInfo iProgress=%d iNoRollback=%d "), iProgress, iNoRollback));
       
    73 
       
    74     if ((iProgress == EObjectInfoSucceed || 
       
    75         iProgress == EObjectInfoFail || 
       
    76         iProgress == EObjectInfoInProgress) && !iNoRollback)
       
    77         {
       
    78         // Not finished SendObjectInfo/PropList SendObject pair detected.
       
    79         Rollback();
       
    80         }
       
    81  
       
    82     iDpSingletons.Close();
       
    83     delete iDateModP;
       
    84     delete iFileReceivedP;
       
    85     delete iParentSuidP;    
       
    86     delete iReceivedObjectP;
       
    87     delete iObjectInfoP;
       
    88     delete iObjectPropList;
       
    89 
       
    90     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::~CMTPPictBridgeDpSendObjectInfo"));
       
    91     __FLOG_CLOSE;
       
    92     }
       
    93 
       
    94 /**
       
    95 Standard c++ constructor
       
    96 @param aFramework    The data provider framework
       
    97 @param aConnection    The connection from which the request comes
       
    98 */    
       
    99 CMTPPictBridgeDpSendObjectInfo::CMTPPictBridgeDpSendObjectInfo(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection, CMTPPictBridgeDataProvider& aDataProvider):
       
   100     CMTPRequestProcessor(aFramework, aConnection, 0, NULL),
       
   101     iPictBridgeDP(aDataProvider)
       
   102     {
       
   103     }
       
   104 
       
   105 /**
       
   106 Verify the request
       
   107 @return EMTPRespCodeOK if request is verified, otherwise one of the error response codes
       
   108 */    
       
   109 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::CheckRequestL()
       
   110     {
       
   111     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CheckRequestL"));    
       
   112     TMTPResponseCode result = CheckSendingStateL();
       
   113     
       
   114     if (result != EMTPRespCodeOK) 
       
   115         {
       
   116         return result;
       
   117         }
       
   118     
       
   119     if (iProgress == EObjectNone)    //this is the SendObjectInfo phase
       
   120         {
       
   121         iElementCount = sizeof(KMTPSendObjectInfoPolicy) / sizeof(TMTPRequestElementInfo);
       
   122         iElements = KMTPSendObjectInfoPolicy;            
       
   123         }
       
   124     else if (iProgress == EObjectInfoSucceed)
       
   125         {
       
   126         iElementCount = 0;
       
   127         iElements     = NULL;
       
   128         }
       
   129 
       
   130     if (iElements)
       
   131         {
       
   132         result = CMTPRequestProcessor::CheckRequestL();    
       
   133         }
       
   134 
       
   135     if ( EMTPRespCodeOK == result )
       
   136         {
       
   137         result = MatchStoreAndParentL();
       
   138         }
       
   139 
       
   140     if (( EMTPRespCodeOK == result ) && ( EMTPOpCodeSendObjectPropList == iOperationCode ))
       
   141         {
       
   142         iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   143         TUint32 objectSizeHigh = Request().Uint32(TMTPTypeRequest::ERequestParameter4);
       
   144         TUint32 objectSizeLow = Request().Uint32(TMTPTypeRequest::ERequestParameter5);
       
   145         iObjectSize = MAKE_TUINT64(objectSizeHigh, objectSizeLow);
       
   146         if (IsTooLarge(iObjectSize))
       
   147             {
       
   148              result = EMTPRespCodeObjectTooLarge;            
       
   149             }
       
   150         if(result && !CanStoreFileL(iStorageId, iObjectSize))
       
   151            {
       
   152            result = EMTPRespCodeStoreFull;            
       
   153            }        
       
   154         }
       
   155     // If the previous request is not SendObjectInfo, SendObject fails
       
   156     if (result == EMTPRespCodeOK && iOperationCode == EMTPOpCodeSendObject)
       
   157         {
       
   158         if (iPreviousTransactionID + 1 != Request().Uint32(TMTPTypeRequest::ERequestTransactionID))
       
   159             {
       
   160             result = EMTPRespCodeNoValidObjectInfo;
       
   161             }
       
   162         }
       
   163         
       
   164     __FLOG_VA((_L8("<< CMTPPictBridgeDpSendObjectInfo::CheckRequestL 0x%04x"), result));    
       
   165 
       
   166     return result;    
       
   167     }
       
   168     
       
   169 TBool CMTPPictBridgeDpSendObjectInfo::HasDataphase() const
       
   170     {
       
   171     return ETrue;
       
   172     }
       
   173 
       
   174 /**
       
   175 SendObjectInfo/SendObject request handler
       
   176 NOTE: SendObjectInfo has to be comes before SendObject requests.  To maintain the state information
       
   177 between the two requests, the two requests are combined together in one request processor.
       
   178 */    
       
   179 void CMTPPictBridgeDpSendObjectInfo::ServiceL()
       
   180     {
       
   181     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ServiceL"));
       
   182     if (iProgress == EObjectNone)
       
   183         {
       
   184         if ( EMTPOpCodeSendObjectInfo == iOperationCode )
       
   185             {
       
   186             ServiceSendObjectInfoL();
       
   187             }
       
   188         else
       
   189             {
       
   190             ServiceSendObjectPropListL();
       
   191             }
       
   192         }
       
   193     else
       
   194         {
       
   195         ServiceSendObjectL();
       
   196         }    
       
   197     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ServiceL"));    
       
   198     }
       
   199 
       
   200 /**
       
   201 Second-phase construction
       
   202 */        
       
   203 void CMTPPictBridgeDpSendObjectInfo::ConstructL()
       
   204     {
       
   205     __FLOG_OPEN(KMTPSubsystem, KComponent);
       
   206     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ConstructL"));      
       
   207     iExpectedSendObjectRequest.SetUint16(TMTPTypeRequest::ERequestOperationCode, EMTPOpCodeSendObject);
       
   208     iReceivedObjectP = CMTPObjectMetaData::NewL();
       
   209     iReceivedObjectP->SetUint(CMTPObjectMetaData::EDataProviderId, iFramework.DataProviderId());
       
   210     iDpSingletons.OpenL(iFramework);
       
   211     iNoRollback = EFalse;
       
   212     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ConstructL"));    
       
   213     }
       
   214 
       
   215 /**
       
   216 Override to match both the SendObjectInfo and SendObject requests
       
   217 @param aRequest    The request to match
       
   218 @param aConnection The connection from which the request comes
       
   219 @return ETrue if the processor can handle the request, otherwise EFalse
       
   220 */        
       
   221 TBool CMTPPictBridgeDpSendObjectInfo::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const
       
   222     {
       
   223     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::Match"));    
       
   224     TBool result = EFalse;
       
   225     TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
       
   226     if ((operationCode == EMTPOpCodeSendObjectInfo || 
       
   227         operationCode == EMTPOpCodeSendObject ||
       
   228         operationCode == EMTPOpCodeSendObjectPropList) &&
       
   229         &iConnection == &aConnection)
       
   230         {
       
   231         result = ETrue;
       
   232         }
       
   233     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::Match"));    
       
   234     return result;    
       
   235     }
       
   236 
       
   237 /**
       
   238 Override to handle the response phase of SendObjectInfo and SendObject requests
       
   239 @return EFalse
       
   240 */
       
   241 TBool CMTPPictBridgeDpSendObjectInfo::DoHandleResponsePhaseL()
       
   242     {
       
   243     __FLOG_VA((_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleResponsePhaseL iProgress==%d opCode==0x%x"),iProgress, iOperationCode));
       
   244     //to check if the sending/receiving data is successful
       
   245     TBool successful = !iCancelled;
       
   246     if (iProgress == EObjectInfoInProgress)
       
   247         {
       
   248         if (iOperationCode == EMTPOpCodeSendObjectInfo)
       
   249             {            
       
   250             successful = DoHandleSendObjectInfoCompleteL();
       
   251             }
       
   252         else
       
   253             {
       
   254             successful = DoHandleSendObjectPropListCompleteL();
       
   255             }
       
   256         iProgress = (successful ? EObjectInfoSucceed : EObjectInfoFail);
       
   257         }
       
   258     else if (iProgress == ESendObjectInProgress)
       
   259         {
       
   260         successful = DoHandleSendObjectCompleteL();
       
   261         iProgress = (successful ? ESendObjectSucceed : ESendObjectFail);
       
   262         }        
       
   263     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleResponsePhaseL"));    
       
   264     return EFalse;
       
   265     }
       
   266 
       
   267 /**
       
   268 Override to handle the completing phase of SendObjectInfo and SendObject requests
       
   269 @return ETrue if succesfully received the file, otherwise EFalse
       
   270 */    
       
   271 TBool CMTPPictBridgeDpSendObjectInfo::DoHandleCompletingPhaseL()
       
   272     {
       
   273     __FLOG_VA((_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleCompletingPhaseL iProgress==%d opCode==0x%x"),iProgress, iOperationCode));
       
   274     TBool result = ETrue;
       
   275     CMTPRequestProcessor::DoHandleCompletingPhaseL();
       
   276     if (iProgress == EObjectInfoSucceed)
       
   277         {
       
   278         if (( iOperationCode == EMTPOpCodeSendObjectInfo ) || ( iOperationCode == EMTPOpCodeSendObjectPropList ))
       
   279             {
       
   280             iPreviousTransactionID = Request().Uint32(TMTPTypeRequest::ERequestTransactionID);
       
   281             }
       
   282         result = EFalse;
       
   283         }
       
   284     else if (iProgress == ESendObjectSucceed)
       
   285         {
       
   286         iPictBridgeDP.PtpServer()->Printer()->DpsObjectReceived(iReceivedObjectP->Uint(CMTPObjectMetaData::EHandle));
       
   287         }
       
   288     else if (iProgress == ESendObjectFail)
       
   289         {
       
   290         if (iOperationCode == EMTPOpCodeSendObject)
       
   291             {
       
   292             iPreviousTransactionID++;
       
   293             }
       
   294         iProgress = EObjectInfoSucceed;
       
   295         result = EFalse;
       
   296         }
       
   297     
       
   298     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleCompletingPhaseL"));    
       
   299     return result;    
       
   300     }
       
   301 
       
   302 /**
       
   303 Verify if the SendObject request comes after SendObjectInfo request
       
   304 @return EMTPRespCodeOK if SendObject request comes after a valid SendObjectInfo request, otherwise
       
   305 EMTPRespCodeNoValidObjectInfo
       
   306 */
       
   307 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL()
       
   308     {
       
   309     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL"));    
       
   310     TMTPResponseCode result = EMTPRespCodeOK;
       
   311     iOperationCode = Request().Uint16(TMTPTypeRequest::ERequestOperationCode);
       
   312 
       
   313     if (iOperationCode == EMTPOpCodeSendObject)
       
   314         {
       
   315         //In ParseRouter everytime SendObject gets resolved then will be removed from Registry
       
   316         //Right away therefore we need reRegister it here again in case possible cancelRequest
       
   317         //Against this SendObject being raised.
       
   318         iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   319         iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   320         }
       
   321    
       
   322     if (iProgress == EObjectNone)
       
   323         {
       
   324         if (iOperationCode == EMTPOpCodeSendObject)
       
   325             {
       
   326             result = EMTPRespCodeNoValidObjectInfo;
       
   327             }        
       
   328         }
       
   329     else if (iProgress == EObjectInfoSucceed) 
       
   330         {
       
   331         if (iOperationCode == EMTPOpCodeSendObjectInfo || iOperationCode == EMTPOpCodeSendObjectPropList)
       
   332             {
       
   333             // Not finished SendObjectInfo/SendObject pair detected, need to remove the object reservation that was created, unless the object already existed
       
   334             if (!iNoRollback )
       
   335                 {
       
   336                 __FLOG(_L8("  CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL ... Rolling back!"));
       
   337                 Rollback();
       
   338                 }
       
   339 
       
   340             delete iObjectInfoP;
       
   341             iObjectInfoP = NULL;
       
   342             delete iObjectPropList;
       
   343             iObjectPropList = NULL;
       
   344             iProgress = EObjectNone;
       
   345             }
       
   346         }
       
   347     else 
       
   348         {
       
   349         Panic(EMTPPictBridgeDpSendObjectStateInvalid);
       
   350         }
       
   351     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL"));    
       
   352     return result;    
       
   353     }
       
   354 
       
   355 /**
       
   356 SendObjectInfo request handler
       
   357 */
       
   358 void CMTPPictBridgeDpSendObjectInfo::ServiceSendObjectInfoL()
       
   359     {
       
   360     delete iObjectInfoP;
       
   361     iObjectInfoP = NULL;
       
   362     iObjectInfoP = CMTPTypeObjectInfo::NewL();
       
   363     ReceiveDataL(*iObjectInfoP);
       
   364     iProgress = EObjectInfoInProgress;
       
   365     }
       
   366 
       
   367 /**
       
   368 ServiceSendObjectPropListL request handler
       
   369 */ 
       
   370 void CMTPPictBridgeDpSendObjectInfo::ServiceSendObjectPropListL()
       
   371     {
       
   372     delete iObjectPropList;
       
   373     iObjectPropList = NULL;
       
   374     iObjectPropList = CMTPTypeObjectPropList::NewL();
       
   375     ReceiveDataL( *iObjectPropList );
       
   376     iProgress = EObjectInfoInProgress;
       
   377     }
       
   378 
       
   379 /**
       
   380 SendObject request handler
       
   381 */    
       
   382 void CMTPPictBridgeDpSendObjectInfo::ServiceSendObjectL()
       
   383     {    
       
   384     ReceiveDataL(*iFileReceivedP);    
       
   385     iProgress = ESendObjectInProgress;
       
   386     }
       
   387 
       
   388 /**
       
   389 Get a default parent object, if the request does not specify a parent object.
       
   390 */
       
   391 void CMTPPictBridgeDpSendObjectInfo::GetDefaultParentObjectL()
       
   392     {    
       
   393     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::GetDefaultParentObjectL"));    
       
   394 
       
   395     if (iStorageId == KMTPStorageDefault)
       
   396         {
       
   397         iStorageId = iFramework.StorageMgr().DefaultStorageId();
       
   398         }
       
   399     TInt drive(static_cast<TDriveNumber>(iFramework.StorageMgr().DriveNumber(iStorageId)));
       
   400     User::LeaveIfError(drive);
       
   401 
       
   402     // Obtain the root of the drive.  Logical storages can sometimes have a filesystem root
       
   403     // other than <drive>:\ .  For example an MP3 DP might have a root of c:\media\music\
       
   404 
       
   405     delete iParentSuidP;
       
   406     iParentSuidP = NULL;
       
   407     iParentSuidP=(iFramework.StorageMgr().StorageL(iStorageId).DesC(CMTPStorageMetaData::EStorageSuid)).AllocL();
       
   408     iReceivedObjectP->SetUint(CMTPObjectMetaData::EParentHandle, KMTPHandleNoParent);
       
   409     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::GetDefaultParentObjectL"));            
       
   410     }
       
   411 
       
   412 /**
       
   413 Get parent object and storage id
       
   414 @return EMTPRespCodeOK if successful, otherwise, EMTPRespCodeInvalidParentObject
       
   415 */
       
   416 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::GetParentObjectAndStorageIdL()
       
   417     {
       
   418     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::GetParentObjectAndStorageIdL"));    
       
   419     __ASSERT_DEBUG(iRequestChecker, Panic(EMTPPictBridgeDpRequestCheckNull));
       
   420 
       
   421     iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   422     iParentHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter2);
       
   423     //does not take ownership
       
   424     CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo(iParentHandle);
       
   425 
       
   426     if (!parentObjectInfo)
       
   427         {
       
   428         GetDefaultParentObjectL();    
       
   429         }
       
   430     else
       
   431         {        
       
   432         delete iParentSuidP;
       
   433         iParentSuidP = NULL;
       
   434         iParentSuidP = parentObjectInfo->DesC(CMTPObjectMetaData::ESuid).AllocL();
       
   435         iReceivedObjectP->SetUint(CMTPObjectMetaData::EParentHandle, iParentHandle);
       
   436         }
       
   437 
       
   438     __FLOG_VA((_L16("<< CMTPPictBridgeDpSendObjectInfo::GetParentObjectAndStorageIdL %S"), iParentSuidP));    
       
   439     return EMTPRespCodeOK;
       
   440     }
       
   441 
       
   442 /**
       
   443 Handling the completing phase of SendObjectInfo request
       
   444 @return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
       
   445 */    
       
   446 TBool CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectInfoCompleteL()
       
   447     {
       
   448     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectInfoCompleteL"));    
       
   449     TBool result(ETrue);
       
   450     TUint16 format(iObjectInfoP->Uint16L(CMTPTypeObjectInfo::EObjectFormat));
       
   451     
       
   452     result = IsFormatValid(TMTPFormatCode(format));
       
   453     
       
   454     if (result)
       
   455         {
       
   456         delete iDateModP;
       
   457         iDateModP = NULL;
       
   458         iDateModP = iObjectInfoP->StringCharsL(CMTPTypeObjectInfo::EDateModified).AllocL();
       
   459     
       
   460         TMTPResponseCode responseCode(GetParentObjectAndStorageIdL());
       
   461         if (responseCode != EMTPRespCodeOK)
       
   462             {
       
   463             SendResponseL(responseCode);
       
   464             result = EFalse;
       
   465             }
       
   466         }
       
   467     else
       
   468         {
       
   469         SendResponseL(EMTPRespCodeInvalidObjectFormatCode);
       
   470         }
       
   471 
       
   472     if (result)
       
   473         {
       
   474         iObjectSize = iObjectInfoP->Uint32L(CMTPTypeObjectInfo::EObjectCompressedSize);
       
   475         if (IsTooLarge(iObjectSize))
       
   476             {
       
   477             SendResponseL(EMTPRespCodeObjectTooLarge);
       
   478             result = EFalse;            
       
   479             }
       
   480         if(result && !CanStoreFileL(iStorageId, iObjectSize))
       
   481             {
       
   482             SendResponseL(EMTPRespCodeStoreFull);
       
   483             result = EFalse;            
       
   484             }
       
   485         }
       
   486 
       
   487     if (result)
       
   488         {
       
   489         iProtectionStatus = iObjectInfoP->Uint16L(CMTPTypeObjectInfo::EProtectionStatus);
       
   490         if (iProtectionStatus !=  EMTPProtectionNoProtection &&
       
   491             iProtectionStatus != EMTPProtectionReadOnly)
       
   492             {
       
   493             SendResponseL(EMTPRespCodeParameterNotSupported);
       
   494             result = EFalse;
       
   495             }
       
   496         }
       
   497 
       
   498     if (result)
       
   499         {
       
   500         result = GetFullPathNameL(iObjectInfoP->StringCharsL(CMTPTypeObjectInfo::EFilename));
       
   501         if (!result)
       
   502             {        
       
   503             // File and/or parent pathname invalid.
       
   504             SendResponseL(EMTPRespCodeInvalidDataset);
       
   505             }
       
   506         }
       
   507 
       
   508     // pictbridge objects should be overwritten
       
   509 /*
       
   510     if (result)
       
   511         {    
       
   512         result &= !Exists(iFullPath);
       
   513         if (!result)
       
   514             {        
       
   515             // Object with the same name already exists.
       
   516             __FLOG(_L8("   no rollback"));
       
   517 			iNoRollback = ETrue;
       
   518             SendResponseL(EMTPRespCodeAccessDenied);
       
   519             }
       
   520         }
       
   521   */
       
   522     
       
   523     if (result)
       
   524         {
       
   525         iReceivedObjectP->SetUint(CMTPObjectMetaData::EFormatCode, format);
       
   526         iPictBridgeDP.PtpServer()->Printer()->DpsDiscovery(iFullPath, &iConnection);
       
   527         TRAPD(err, CreateFsObjectL()); 
       
   528         
       
   529         if (err != KErrNone)
       
   530             {
       
   531             SendResponseL(ErrorToMTPError(err));
       
   532             }
       
   533         else
       
   534             {
       
   535             ReserveObjectL();
       
   536             }
       
   537         }
       
   538     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectInfoCompleteL"));    
       
   539     return result;    
       
   540     }
       
   541 
       
   542 
       
   543 TBool CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectPropListCompleteL()
       
   544     {
       
   545     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectPropListCompleteL"));
       
   546     TBool result(ETrue);
       
   547     TMTPResponseCode responseCode( GetParentObjectAndStorageIdL() );
       
   548     if ( responseCode != EMTPRespCodeOK )
       
   549         {
       
   550         SendResponseL( responseCode );
       
   551         result = EFalse;
       
   552         }
       
   553     
       
   554     if ( result )
       
   555         {
       
   556         TInt invalidParameterIndex = KErrNotFound;
       
   557         responseCode = VerifyObjectPropListL( invalidParameterIndex );
       
   558         result = ( responseCode == EMTPRespCodeOK );
       
   559         if ( !result )
       
   560             {
       
   561             TUint32 parameters[4];
       
   562             parameters[0] = 0;
       
   563             parameters[1] = 0;
       
   564             parameters[2] = 0;
       
   565             parameters[3] = invalidParameterIndex;
       
   566             SendResponseL( responseCode, 4, parameters );
       
   567             }
       
   568         }
       
   569 
       
   570     if ( result )
       
   571         {
       
   572         iReceivedObjectP->SetUint(CMTPObjectMetaData::EFormatCode, iRequest->Uint32( TMTPTypeRequest::ERequestParameter3 ));
       
   573         iPictBridgeDP.PtpServer()->Printer()->DpsDiscovery(iFullPath, &iConnection);
       
   574         TRAPD(err, CreateFsObjectL());
       
   575         if ( err != KErrNone )
       
   576             {
       
   577             SendResponseL(ErrorToMTPError(err));
       
   578             }
       
   579         else
       
   580             {
       
   581             ReserveObjectL();
       
   582             }
       
   583         }
       
   584 
       
   585     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectPropListCompleteL"));
       
   586     return result;
       
   587     }
       
   588 
       
   589 /**
       
   590 */
       
   591 TBool CMTPPictBridgeDpSendObjectInfo::IsFormatValid(TMTPFormatCode aFormat) const
       
   592     {
       
   593     __FLOG_VA((_L8(">> CMTPPictGetObjectPropDesc::IsFormatValid %d"),aFormat));
       
   594     TInt count(sizeof(KMTPValidCodeExtensionMappings) / sizeof(KMTPValidCodeExtensionMappings[0]));        
       
   595     for(TInt i = 0; i < count; i++)
       
   596         {
       
   597         if (KMTPValidCodeExtensionMappings[i].iFormatCode == aFormat)
       
   598             {
       
   599             __FLOG(_L8("<< CMTPPictGetObjectPropDesc::IsFormatValid ETrue"));
       
   600             return ETrue;
       
   601             }
       
   602         }
       
   603     __FLOG(_L8("<< CMTPPictGetObjectPropDesc::IsFormatValid EFalse"));
       
   604     return EFalse;
       
   605     }
       
   606     
       
   607 /**
       
   608 Handling the completing phase of SendObject request
       
   609 @return ETrue if the object has been successfully saved on the device, otherwise, EFalse
       
   610 */    
       
   611 TBool CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectCompleteL()
       
   612     {
       
   613     __FLOG_VA((_L8(">> CMTPPictGetObjectPropDesc::DoHandleSendObjectCompleteL size=%d cancelled=%d"), iObjectSize, iCancelled));
       
   614     TBool result(ETrue);
       
   615                 
       
   616     delete iFileReceivedP;
       
   617     iFileReceivedP = NULL;
       
   618         
       
   619     TEntry fileEntry;
       
   620     User::LeaveIfError(iFramework.Fs().Entry(iFullPath, fileEntry));
       
   621 
       
   622     if (fileEntry.FileSize() != iObjectSize)
       
   623         {
       
   624         __FLOG_VA((_L8("   sizes differ %d!=%d"),fileEntry.iSize, iObjectSize));
       
   625         iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   626          
       
   627         iFramework.Fs().Delete(iFullPath);
       
   628         iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObjectP);
       
   629         TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge;
       
   630         if (fileEntry.FileSize() < iObjectSize)
       
   631             {
       
   632             responseCode = EMTPRespCodeInvalidDataset;
       
   633             }
       
   634         SendResponseL(responseCode);
       
   635         result = EFalse;
       
   636         }
       
   637 
       
   638     
       
   639     // Get the result of the SendObject operation. 
       
   640     RMTPFramework frameworkSingletons;   
       
   641     frameworkSingletons.OpenL();
       
   642     TUint connectionId = iConnection.ConnectionId();
       
   643     CMTPConnectionMgr& connectionMgr = frameworkSingletons.ConnectionMgr();
       
   644     CMTPConnection& connection = connectionMgr.ConnectionL(connectionId);
       
   645     TInt ret = connection.GetDataReceiveResult(); 
       
   646     frameworkSingletons.Close();
       
   647      // SendObject is cancelled or connection is dropped.
       
   648     if(result && (iCancelled || (ret == KErrAbort)))
       
   649         {
       
   650         iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   651         Rollback();
       
   652         SendResponseL(EMTPRespCodeTransactionCancelled);        
       
   653         }
       
   654     else if (result && !iCancelled)
       
   655         {
       
   656          iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   657         
       
   658         //The MTP spec states that it is not mandatory for SendObjectInfo
       
   659         //to be followed by a SendObject.  An object is reserved in the ObjectStore on 
       
   660         //receiving a SendObjectInfo request, but we only commit it 
       
   661         //on receiving the corresponding SendObject request.  With Associations however 
       
   662         //we commit the object straight away as the SendObject phase is often absent 
       
   663         //with folder creation.
       
   664 
       
   665 
       
   666         iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObjectP);
       
   667         SendResponseL(EMTPRespCodeOK);
       
   668         }
       
   669     __FLOG(_L8("<< CMTPPictGetObjectPropDesc::DoHandleSendObjectCompleteL"));
       
   670     return result;
       
   671     }
       
   672 
       
   673 /**
       
   674 Get the full path name of the object to be saved
       
   675 @param aFileName, on entry, contains the file name of the object,
       
   676 on return, contains the full path name of the object to be saved
       
   677 @return ETrue if the name is valid, EFalse otherwise
       
   678 */
       
   679 TBool CMTPPictBridgeDpSendObjectInfo::GetFullPathNameL(const TDesC& aFileName)
       
   680     {
       
   681     __FLOG_VA((_L16(">> CMTPPictBridgeDpSendObjectInfo::GetFullPathNameL file %S"), &aFileName));
       
   682     TBool result(EFalse);
       
   683     if (aFileName.Length() > 0)
       
   684         {
       
   685         iFullPath = *iParentSuidP;
       
   686         if (iFullPath.Length() + aFileName.Length() < iFullPath.MaxLength())
       
   687             {
       
   688             iFullPath.Append(aFileName);
       
   689             result = iFramework.Fs().IsValidName(iFullPath);
       
   690             }
       
   691         }
       
   692 
       
   693     __FLOG_VA((_L16("<< CMTPPictBridgeDpSendObjectInfo::GetFullPathNameL full path %S"), &iFullPath));
       
   694     return result;
       
   695     }
       
   696 
       
   697 /**
       
   698 Check if we can store the file on the storage
       
   699 @return ETrue if yes, otherwise EFalse
       
   700 */
       
   701 TBool CMTPPictBridgeDpSendObjectInfo::CanStoreFileL(TUint32 aStorageId, TInt64 aObjectSize) const
       
   702     {
       
   703     TBool result(ETrue);
       
   704     if (aStorageId == KMTPStorageDefault)
       
   705         {
       
   706         aStorageId = iFramework.StorageMgr().DefaultStorageId();
       
   707         }
       
   708     TInt drive(iFramework.StorageMgr().DriveNumber(aStorageId));
       
   709     User::LeaveIfError(drive);
       
   710     TVolumeInfo volumeInfo;
       
   711     User::LeaveIfError(iFramework.Fs().Volume(volumeInfo, drive));
       
   712     if (volumeInfo.iFree < aObjectSize)
       
   713         {        
       
   714         result = EFalse;
       
   715         }
       
   716     return result;        
       
   717     }
       
   718 
       
   719 /**
       
   720 Check if the object is too large
       
   721 @return ETrue if yes, otherwise EFalse
       
   722 */
       
   723 TBool CMTPPictBridgeDpSendObjectInfo::IsTooLarge(TUint64 aObjectSize) const
       
   724     {
       
   725     TBool ret(aObjectSize > KMaxTInt64);
       
   726     return ret;
       
   727     }
       
   728     
       
   729 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::VerifyObjectPropListL( TInt& aInvalidParameterIndex )
       
   730     {
       
   731     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::VerifyObjectPropListL"));
       
   732     TMTPResponseCode responseCode( EMTPRespCodeOK );
       
   733     const TUint KCount( iObjectPropList->NumberOfElements() );
       
   734     iObjectPropList->ResetCursor();
       
   735     for ( TUint i(0); (i < KCount); i++ )
       
   736         {
       
   737         CMTPTypeObjectPropListElement& KElement=iObjectPropList->GetNextElementL();
       
   738         const TUint32 KHandle( KElement.Uint32L(CMTPTypeObjectPropListElement::EObjectHandle) );
       
   739         aInvalidParameterIndex = i;
       
   740         if ( KHandle != KMTPHandleNone )
       
   741             {
       
   742             responseCode = EMTPRespCodeInvalidObjectHandle;  
       
   743             break;
       
   744             }
       
   745         responseCode = CheckPropCodeL( KElement );
       
   746         if ( responseCode != EMTPRespCodeOK )
       
   747             {
       
   748             break;
       
   749             }
       
   750         responseCode = ExtractPropertyL(KElement);
       
   751         if ( responseCode != EMTPRespCodeOK )
       
   752             {
       
   753             break;
       
   754             }  
       
   755         }
       
   756 
       
   757     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::VerifyObjectPropListL"));
       
   758     return responseCode;
       
   759     }
       
   760 
       
   761 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::ExtractPropertyL( const CMTPTypeObjectPropListElement& aElement )
       
   762     {
       
   763     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ExtractPropertyL"));
       
   764     TMTPResponseCode responseCode(EMTPRespCodeOK);
       
   765     switch ( aElement.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode) )
       
   766         {
       
   767     case EMTPObjectPropCodeObjectFileName:
       
   768         {
       
   769         const TDesC& KFileName = aElement.StringL(CMTPTypeObjectPropListElement::EValue);
       
   770         if (!GetFullPathNameL(KFileName))
       
   771             {
       
   772             responseCode = EMTPRespCodeInvalidDataset;
       
   773             }
       
   774         }
       
   775         break;
       
   776 
       
   777     case EMTPObjectPropCodeProtectionStatus:
       
   778         {
       
   779         iProtectionStatus = aElement.Uint16L(CMTPTypeObjectPropListElement::EValue);
       
   780         if (iProtectionStatus !=  EMTPProtectionNoProtection &&
       
   781             iProtectionStatus != EMTPProtectionReadOnly)
       
   782             {
       
   783             responseCode = EMTPRespCodeParameterNotSupported;
       
   784             }
       
   785         }
       
   786         break;
       
   787 
       
   788     case EMTPObjectPropCodeDateModified:
       
   789         delete iDateModP;
       
   790         iDateModP = NULL;
       
   791         iDateModP = aElement.StringL(CMTPTypeObjectPropListElement::EValue).AllocL();
       
   792         break;
       
   793     case EMTPObjectPropCodeName:
       
   794     	iName = aElement.StringL(CMTPTypeObjectPropListElement::EValue);
       
   795     	break;
       
   796     default:
       
   797         break;
       
   798         }
       
   799 
       
   800     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ExtractPropertyL"));
       
   801     return responseCode;
       
   802     }
       
   803     
       
   804 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::CheckPropCodeL( const CMTPTypeObjectPropListElement& aElement ) const
       
   805     {
       
   806     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CheckPropCodeL"));
       
   807     TMTPResponseCode responseCode( EMTPRespCodeOK );
       
   808     switch( aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ))
       
   809         {
       
   810         case EMTPObjectPropCodeStorageID:
       
   811             {
       
   812             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32 )
       
   813                 {
       
   814                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   815                 }
       
   816             else if ( iStorageId != aElement.Uint32L(CMTPTypeObjectPropListElement::EValue) )
       
   817                 {
       
   818                 responseCode = EMTPRespCodeInvalidDataset;
       
   819                 }
       
   820             }
       
   821             break;
       
   822         case EMTPObjectPropCodeObjectFormat:
       
   823             {
       
   824             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16 )
       
   825                 {
       
   826                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   827                 }
       
   828         else if (Request().Uint32(TMTPTypeRequest::ERequestParameter3) != aElement.Uint16L(CMTPTypeObjectPropListElement::EValue))
       
   829                 {
       
   830                 responseCode = EMTPRespCodeInvalidDataset;
       
   831                 }
       
   832             }
       
   833             break;
       
   834         case EMTPObjectPropCodeObjectSize:
       
   835             {
       
   836             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT64 )
       
   837                 {
       
   838                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   839                 }
       
   840         else if (iObjectSize != aElement.Uint64L(CMTPTypeObjectPropListElement::EValue))
       
   841                 {
       
   842                 responseCode = EMTPRespCodeInvalidDataset;
       
   843                 }
       
   844             }
       
   845             break;
       
   846         case EMTPObjectPropCodeParentObject:
       
   847             {
       
   848             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32 )
       
   849                 {
       
   850                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   851                 }
       
   852             else if( Request().Uint32(TMTPTypeRequest::ERequestParameter2) != aElement.Uint32L(CMTPTypeObjectPropListElement::EValue) )
       
   853                 {
       
   854                 responseCode = EMTPRespCodeInvalidDataset;
       
   855                 }
       
   856             }
       
   857             break;
       
   858         case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
       
   859             {
       
   860             responseCode = EMTPRespCodeAccessDenied;
       
   861             }
       
   862             break;
       
   863         case EMTPObjectPropCodeProtectionStatus:
       
   864             {
       
   865             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16 )
       
   866                 {
       
   867                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   868                 }
       
   869             }
       
   870             break;
       
   871         case EMTPObjectPropCodeDateModified:
       
   872         case EMTPObjectPropCodeObjectFileName:
       
   873         case EMTPObjectPropCodeName:
       
   874             {
       
   875             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeString )
       
   876                 {
       
   877                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   878                 }
       
   879             }
       
   880             break;
       
   881         case EMTPObjectPropCodeNonConsumable:
       
   882             {
       
   883             if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT8 )
       
   884                 {
       
   885                 responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   886                 }
       
   887             }
       
   888             break;
       
   889         default:
       
   890             {
       
   891             responseCode = EMTPRespCodeInvalidObjectPropCode;
       
   892             }
       
   893             break;
       
   894         }
       
   895     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::CheckPropCodeL"));
       
   896     return responseCode; 
       
   897     }
       
   898 
       
   899 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::MatchStoreAndParentL() const
       
   900     {
       
   901     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::MatchStoreAndParentL"));
       
   902     TMTPResponseCode ret = EMTPRespCodeOK;
       
   903     const TUint32 storeId(Request().Uint32(TMTPTypeRequest::ERequestParameter1));
       
   904     const TUint32 parentHandle(Request().Uint32(TMTPTypeRequest::ERequestParameter2));
       
   905     if (parentHandle != KMTPHandleAll && parentHandle != KMTPHandleNone)
       
   906         {
       
   907         CMTPObjectMetaData* parentObjInfo = iRequestChecker->GetObjectInfo(parentHandle);
       
   908         __ASSERT_DEBUG(parentObjInfo, Panic(EMTPPictBridgeDpObjectNull));
       
   909 
       
   910         if (parentObjInfo->Uint(CMTPObjectMetaData::EStorageId) != storeId)   
       
   911             {
       
   912             ret = EMTPRespCodeInvalidObjectHandle;
       
   913             }
       
   914         }
       
   915     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::MatchStoreAndParentL"));
       
   916     return ret;
       
   917     }
       
   918 
       
   919 /**
       
   920 Reserves space for and assigns an object handle to the received object, then
       
   921 sends a success response.
       
   922 */
       
   923 void CMTPPictBridgeDpSendObjectInfo::ReserveObjectL()
       
   924     {
       
   925     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ReserveObjectL"));    
       
   926     iReceivedObjectP->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
       
   927     iReceivedObjectP->SetDesCL(CMTPObjectMetaData::ESuid, iFullPath);
       
   928     
       
   929     iFramework.ObjectMgr().ReserveObjectHandleL(*iReceivedObjectP, iObjectSize);    
       
   930     
       
   931     iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   932     iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   933     TUint32 parameters[3];
       
   934     parameters[0] = iStorageId;
       
   935     parameters[1] = iParentHandle;
       
   936     parameters[2] = iReceivedObjectP->Uint(CMTPObjectMetaData::EHandle);
       
   937     SendResponseL(EMTPRespCodeOK, (sizeof(parameters) / sizeof(parameters[0])), parameters);
       
   938     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ReserveObjectL"));    
       
   939     }
       
   940     
       
   941 void CMTPPictBridgeDpSendObjectInfo::CreateFsObjectL()
       
   942     {
       
   943     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CreateFsObjectL"));    
       
   944     delete iFileReceivedP;
       
   945     iFileReceivedP = NULL;
       
   946     iFileReceivedP = CMTPTypeFile::NewL(iFramework.Fs(), iFullPath, EFileWrite);
       
   947     iFileReceivedP->SetSizeL(iObjectSize);
       
   948     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::CreateFsObjectL"));    
       
   949     }
       
   950     
       
   951 void CMTPPictBridgeDpSendObjectInfo::Rollback()
       
   952     {
       
   953     __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::Rollback"));
       
   954     // Delete this object from file system.
       
   955     delete iFileReceivedP;
       
   956     iFileReceivedP=NULL;
       
   957     TInt err=iFramework.Fs().Delete(iFullPath);
       
   958     __FLOG_VA((_L16(">> CMTPPictBridgeDpSendObjectInfo::Rollback deleted %S with return code %d"), &iFullPath, err));
       
   959     TRAP_IGNORE(iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObjectP));
       
   960     __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::Rollback"));    
       
   961     }
       
   962     
       
   963 TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::ErrorToMTPError(TInt aError) const
       
   964     {
       
   965     TMTPResponseCode resp = EMTPRespCodeGeneralError;
       
   966     
       
   967     switch (aError)
       
   968         {
       
   969     case KErrAccessDenied:
       
   970         resp = EMTPRespCodeAccessDenied;
       
   971         break;
       
   972         
       
   973     case KErrDiskFull:
       
   974         resp = EMTPRespCodeStoreFull;
       
   975         break;
       
   976 
       
   977     default:
       
   978         resp = EMTPRespCodeGeneralError;
       
   979         break;
       
   980         }
       
   981         
       
   982     return resp;
       
   983     }
       
   984