mtpfws/mtpfw/dataproviders/proxydp/src/cmtpdeleteobjectproplist.cpp
author hgs
Tue, 28 Sep 2010 20:14:08 +0800
changeset 52 866b4af7ffbe
parent 49 c20dd21d1eb4
permissions -rw-r--r--
201039_01

// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//


#include <mtp/mtpprotocolconstants.h>
#include <mtp/cmtptypedeleteobjectproplist.h>
#include <mtp/tmtptypedatapair.h>
#include <mtp/mmtpdataproviderframework.h>

#include "cmtpdeleteobjectproplist.h"
#include "mtpproxydppanic.h"
#include "cmtpdataprovidercontroller.h"
#include "cmtpobjectmgr.h"
#include "cmtpdataprovider.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmtpdeleteobjectproplistTraces.h"
#endif



// Class constants.


/**
Verification data for the DeleteObjectPropList request
*/
const TMTPRequestElementInfo KMTPDeleteObjectPropListPolicy[] = 
    {
        { TMTPTypeRequest::ERequestParameter1, EMTPElementTypeObjectHandle, (EMTPElementAttrDir | EMTPElementAttrWrite), 1, KMTPHandleAll, 0 }
    };

/**
Two-phase construction method
@param aFramework    The data provider framework
@param aConnection    The connection from which the request comes
@return a pointer to the created request processor object
*/ 
MMTPRequestProcessor* CMTPDeleteObjectPropList::NewL( MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection )
    {
    CMTPDeleteObjectPropList* self = new (ELeave) CMTPDeleteObjectPropList( aFramework, aConnection );
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

/**
Destructor
*/ 
CMTPDeleteObjectPropList::~CMTPDeleteObjectPropList()
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_CMTPDELETEOBJECTPROPLIST_DES_ENTRY );
    
    delete iDeleteObjectPropList;
    iSingletons.Close();
    iTargetDps.Close();
    iSubDatasets.ResetAndDestroy();

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_CMTPDELETEOBJECTPROPLIST_DES_EXIT );
    }

CMTPDeleteObjectPropList::CMTPDeleteObjectPropList(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection):
CMTPRequestProcessor( aFramework, aConnection, (sizeof(KMTPDeleteObjectPropListPolicy) / sizeof(TMTPRequestElementInfo)), KMTPDeleteObjectPropListPolicy )
    {
    
    }

void CMTPDeleteObjectPropList::ConstructL()
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_CONSTRUCTL_ENTRY );
    
    iSingletons.OpenL();
    
    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_CONSTRUCTL_EXIT );
    }

void CMTPDeleteObjectPropList::ServiceL()
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_SERVICEL_ENTRY );
    
    delete iDeleteObjectPropList;
    iDeleteObjectPropList = NULL;
    iTargetDps.Reset();
    iSubDatasets.Reset();
    

    iDeleteObjectPropList = CMTPTypeDeleteObjectPropList::NewL();
    ReceiveDataL(*iDeleteObjectPropList);

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_SERVICEL_EXIT );
    }

TBool CMTPDeleteObjectPropList::DoHandleResponsePhaseL()
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_DOHANDLERESPONSEPHASEL_ENTRY );
      
    //if the ObjectHandle is 0x00000000, 
    //discard the received data and return Invalid_ObjectHandle error code
    if ( Request().Uint32(TMTPTypeRequest::ERequestParameter1) == KMTPHandleNone )
     {  
     TRAP_IGNORE(SendResponseL(EMTPRespCodeInvalidObjectHandle));
     }
    else
     {
     BuildSubRequestsL();
     
     if(iTargetDps.Count() == 0)
    	 {
    	 TRAP_IGNORE(SendResponseL(EMTPRespCodeInvalidDataset));
    	 }
     else
    	 {
	     iCurrentTarget = 0;
	     
	     Schedule(KErrNone);
    	 }
     }

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_DOHANDLERESPONSEPHASEL_EXIT );
    return EFalse;
    }

void CMTPDeleteObjectPropList::BuildSubRequestsL()
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_BUILDSUBREQUESTSL_ENTRY );

    TInt count(iDeleteObjectPropList->NumberOfElements());
    TInt dpid(0);
    TInt index(-1);
    TInt tmpDpid(-1);
    for( TUint i(0); i < count; i++)
        {
        TMTPTypeDataPair& temp(iDeleteObjectPropList->ElementL(i));
        TMTPTypeDataPair* element = new (ELeave) TMTPTypeDataPair();
        CleanupStack::PushL(element);
        MMTPType::CopyL( temp, *element );
        dpid = iSingletons.ObjectMgr().ObjectOwnerId( temp.Uint32(TMTPTypeDataPair::EOwnerHandle) );
        if ( tmpDpid != dpid )
            {
            iTargetDps.AppendL(dpid);
            CMTPTypeDeleteObjectPropList* dataset = CMTPTypeDeleteObjectPropList::NewLC();
            iSubDatasets.AppendL( dataset );
            dataset->AppendL( element);
            CleanupStack::Pop(dataset);
            
            tmpDpid = dpid;
            ++index;
            }
        else
            {          
            iSubDatasets[index]->AppendL( element );
            }
        
        CleanupStack::Pop(element);
        }

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_BUILDSUBREQUESTSL_EXIT );
    }

TBool CMTPDeleteObjectPropList::HasDataphase() const
    {
    return ETrue;
    }


#ifdef _DEBUG
void CMTPDeleteObjectPropList::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus)
#else
void CMTPDeleteObjectPropList::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus)
#endif
    {
    __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy));

    MMTPType::CopyL( *iSubDatasets[iCurrentTarget], aData);
    TRequestStatus* status = &aStatus;
    User::RequestComplete(status, KErrNone);
    }


void CMTPDeleteObjectPropList::ProxySendDataL(const MMTPType& /*aData*/, const TMTPTypeRequest&  /*aRequest*/, MMTPConnection& /* aConnection */, TRequestStatus& /*aStatus*/)
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_PROXYSENDDATAL_ENTRY );
        
    Panic(EMTPWrongRequestPhase);

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_PROXYSENDDATAL_EXIT );
    }

/**
  Send the corresponding response for the request is routed by Proxy DP
  ProxySendResponseL will complete the request of framework's AO, then switch the transaction phase to TranscationComplete
  so ProxyTransactionCompleteL will be called later.
  @param aResponse      The response which is sent by some DP
  @param aRequest       The corresponding request 
  @param aConnection    The corresponding connection
  @param aStatus        The status of framework AO 
 */
#ifdef _DEBUG    
void CMTPDeleteObjectPropList::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus)
#else
void CMTPDeleteObjectPropList::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus)
#endif
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_PROXYSENDRESPONSEL_ENTRY );
    
    __ASSERT_DEBUG(((iRequest == &aRequest) && (&iConnection == &aConnection)), Panic(EMTPNotSameRequestProxy));
    MMTPType::CopyL(aResponse, iResponse);
    TRequestStatus* status = &aStatus;
    User::RequestComplete(status, KErrNone);

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_PROXYSENDRESPONSEL_EXIT );
    }


/**
  Complete the transaction phase for the request is routed by Proxy DP
  Drive its AO to route other requests or send the response.
  @param aRequest       The corresponding request 
  @param aConnection    The corresponding connection
 */
#ifdef _DEBUG
void CMTPDeleteObjectPropList::ProxyTransactionCompleteL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
#else
void CMTPDeleteObjectPropList::ProxyTransactionCompleteL(const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/)
#endif
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_PROXYTRANSACTIONCOMPLETEL_ENTRY );
        
    __ASSERT_DEBUG(((iRequest == &aRequest) && (&iConnection == &aConnection)), Panic(EMTPNotSameRequestProxy));
    const TUint16 KResponseCode(iResponse.Uint16(TMTPTypeResponse::EResponseCode)); 
    TInt err((KResponseCode == EMTPRespCodeOK) ? KErrNone : KErrGeneral);    
    if (err == KErrNone)
       {
       ++iCurrentTarget;
       }
    else
        {
        //when error, calculate the zero-based index of the first failed property
        TUint index = iResponse.Uint32(TMTPTypeResponse::EResponseParameter1);
        for(TInt i = 0 ; i < iCurrentTarget; i++ )
            {
            index  += iSubDatasets[i]->NumberOfElements();
            }
        iResponse.SetUint32(TMTPTypeResponse::EResponseParameter1, index );
        
        if(KResponseCode == EMTPRespCodeOperationNotSupported)
            {
            iResponse.SetUint16(TMTPTypeResponse::EResponseCode, EMTPRespCodeInvalidObjectHandle );
            }
        }

    Schedule(err);

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_PROXYTRANSACTIONCOMPLETEL_EXIT );
    }


    
void CMTPDeleteObjectPropList::SendResponseL(TUint16 aCode)
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_SENDRESPONSEL_ENTRY );
        
    const TMTPTypeRequest& req(Request());
    iResponse.SetUint16(TMTPTypeResponse::EResponseCode, aCode);
    iResponse.SetUint32(TMTPTypeResponse::EResponseSessionID, req.Uint32(TMTPTypeRequest::ERequestSessionID));
    iResponse.SetUint32(TMTPTypeResponse::EResponseTransactionID, req.Uint32(TMTPTypeRequest::ERequestTransactionID));
    iFramework.SendResponseL(iResponse, req, Connection());

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_SENDRESPONSEL_EXIT );
    }

void CMTPDeleteObjectPropList::RunL()
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_RUNL_ENTRY );
    
    if ( (iStatus == KErrNone) && (iCurrentTarget < iTargetDps.Count()) )    
        {
        TUint id(iTargetDps[iCurrentTarget]);
        
        if(iSingletons.DpController().IsDataProviderLoaded(id))
        	{
        	iSingletons.DpController().DataProviderL(id).ExecuteProxyRequestL( *iRequest, Connection(), *this );
        	}
        else
        	{
        	 TUint index(0);
	         for(TInt i = 0 ; i < iCurrentTarget; i++ )
	            {
	            index  += iSubDatasets[i]->NumberOfElements();
	            }
	         iResponse.SetUint32(TMTPTypeResponse::EResponseParameter1, index );
        	 TRAP_IGNORE(SendResponseL(EMTPRespCodeInvalidObjectHandle));
        	}
        }
    else        
        {
        //Any error will stop the process, and send the corresponding response.
        SendResponseL(iResponse.Uint16(TMTPTypeResponse::EResponseCode));
        }  

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_RUNL_EXIT );
    }
        
TInt CMTPDeleteObjectPropList::RunError(TInt /*aError*/)
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_RUNERROR_ENTRY );

    TRAP_IGNORE(SendResponseL(EMTPRespCodeGeneralError));

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_RUNERROR_EXIT );
    return KErrNone;
    }
            
/**
Completes the current asynchronous request with the specified 
completion code.
@param aError The asynchronous request completion request.
*/
void CMTPDeleteObjectPropList::Schedule(TInt aError)
    {
    OstTraceFunctionEntry0( CMTPDELETEOBJECTPROPLIST_SCHEDULE_ENTRY );

    TRequestStatus* status = &iStatus;
    User::RequestComplete(status, aError);
    SetActive();

    OstTraceFunctionExit0( CMTPDELETEOBJECTPROPLIST_SCHEDULE_EXIT );
    }