mtpfws/mtpfw/dataproviders/proxydp/src/cmtpsendobjectinfo.cpp
author hgs
Fri, 03 Sep 2010 18:38:04 +0800
changeset 49 c20dd21d1eb4
parent 29 3ae5cb0b4c02
permissions -rw-r--r--
201035_05

// 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/tmtptyperequest.h>
#include <mtp/mmtpdataproviderframework.h>
#include <mtp/mtpprotocolconstants.h>
#include <mtp/cmtptypeobjectinfo.h>

#include "rmtpframework.h"
#include "cmtpdataprovidercontroller.h"
#include "cmtpparserrouter.h"
#include "cmtpdataprovider.h"
#include "cmtpsendobjectinfo.h"
#include "mtpproxydppanic.h"
#include "cmtpproxydpconfigmgr.h"
#include "cmtpstoragemgr.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmtpsendobjectinfoTraces.h"
#endif


/**
Verification data for the SendObjectInfo request
*/
const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] =
    {
        {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeStorageId, EMTPElementAttrWrite, 1, 0, 0},
        {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeObjectHandle, EMTPElementAttrDir, 2, KMTPHandleAll, KMTPHandleNone}
    };

/**
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* CMTPSendObjectInfo::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection)
    {
    CMTPSendObjectInfo* self = new (ELeave) CMTPSendObjectInfo(aFramework, aConnection);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

/**
Destructor
*/
CMTPSendObjectInfo::~CMTPSendObjectInfo()
    {
    OstTraceFunctionEntry0( CMTPSENDOBJECTINFO_CMTPSENDOBJECTINFO_DES_ENTRY );

    delete iObjectInfo;
    iSingletons.Close();
    iProxyDpSingletons.Close();
    
    OstTraceFunctionExit0( CMTPSENDOBJECTINFO_CMTPSENDOBJECTINFO_DES_EXIT );
    }

/**
Standard c++ constructor
*/
CMTPSendObjectInfo::CMTPSendObjectInfo(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) :
    CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPSendObjectInfoPolicy)/sizeof(TMTPRequestElementInfo), KMTPSendObjectInfoPolicy)
    {

    }

/**
Second phase constructor.
*/
void CMTPSendObjectInfo::ConstructL()
    {
    OstTraceFunctionEntry0( CMTPSENDOBJECTINFO_CONSTRUCTL_ENTRY );
    
    iSingletons.OpenL();

    OstTraceFunctionExit0( CMTPSENDOBJECTINFO_CONSTRUCTL_EXIT );
    }

/**
SendObjectInfo/SendObject request handler
NOTE: SendObjectInfo has to be comes before SendObject requests.  To maintain the state information
between the two requests, the two requests are combined together in one signal processor.
*/
void CMTPSendObjectInfo::ServiceL()
    {
    delete iObjectInfo;
    iObjectInfo = NULL;
    iObjectInfo = CMTPTypeObjectInfo::NewL();
    ReceiveDataL(*iObjectInfo);
    }

/**
Override to handle the response phase of SendObjectInfo requests
@return EFalse
*/
TBool CMTPSendObjectInfo::DoHandleResponsePhaseL()
    {
    DoHandleSendObjectInfoCompleteL();
    return EFalse;
    }

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

/**
Handling the completing phase of SendObjectInfo request
@return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
*/
void CMTPSendObjectInfo::DoHandleSendObjectInfoCompleteL()
    {
    OstTraceFunctionEntry0( CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL_ENTRY );

    CMTPParserRouter::TRoutingParameters params(*iRequest, iConnection);
    iSingletons.Router().ParseOperationRequestL(params);
    TBool fileFlag=EFalse;
    RArray<TUint> targets;
    CleanupClosePushL(targets);
    params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatCode, iObjectInfo->Uint16L(CMTPTypeObjectInfo::EObjectFormat));
    
    iProxyDpSingletons.OpenL(iFramework);
    TInt index(KErrNotFound);
	const TUint16 formatCode=iObjectInfo->Uint16L(CMTPTypeObjectInfo::EObjectFormat);
	OstTrace1(TRACE_NORMAL, CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, "formatCode = %d", formatCode);
	switch(formatCode)
		{
	case EMTPFormatCodeAssociation:
        params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatSubCode, iObjectInfo->Uint16L(CMTPTypeObjectInfo::EAssociationType));
        break;

    case EMTPFormatCodeScript:
    	{
    	const TDesC& filename = iObjectInfo->StringCharsL(CMTPTypeObjectInfo::EFilename);
    	HBufC* lowFileName = HBufC::NewLC(filename.Length());
    	TPtr16 prt(lowFileName->Des());
    	prt.Append(filename);
    	prt.LowerCase();   	
    	OstTraceExt1(TRACE_NORMAL, DUP1_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, 
    	        "lowFileName = %S", prt);
    	if (iProxyDpSingletons.FrameworkConfig().GetFileName(prt,index) )
    		{
    		fileFlag=ETrue;
    		}
    	CleanupStack::PopAndDestroy(lowFileName);
    	
    	params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatSubCode, EMTPAssociationTypeUndefined);	
        break;
    	}
    default:
    	params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatSubCode, EMTPAssociationTypeUndefined);
        break;
		}
	
    OstTrace1( TRACE_NORMAL, DUP2_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, "fileFlag = %d", fileFlag);
    
    if(fileFlag)
    	{
    	TInt  syncdpid =  iSingletons.DpController().DpId(iProxyDpSingletons.FrameworkConfig().GetDPId(index));
       	iSingletons.DpController().DataProviderL(syncdpid).ExecuteProxyRequestL(Request(), Connection(), *this);
    	}
    else
    	{
    	iSingletons.Router().RouteOperationRequestL(params, targets);
        CMTPStorageMgr& storages(iSingletons.StorageMgr());
    	const TUint KStorageId = Request().Uint32(TMTPTypeResponse::EResponseParameter1);
        OstTrace1(TRACE_NORMAL, DUP3_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, 
                "KStorageId = %d", KStorageId);
        OstTrace1(TRACE_NORMAL, DUP4_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, 
                "targets.Count() = %d", targets.Count());
        if( KMTPNotSpecified32 == KStorageId)
            {
            iSingletons.DpController().DataProviderL(targets[0]).ExecuteProxyRequestL(Request(), Connection(), *this);
            }
        else if( storages.ValidStorageId(KStorageId) )
            {
        	if(targets.Count() == 1)
        		{
                OstTrace1(TRACE_NORMAL, DUP5_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, 
                        "targets[0] = %d", targets[0]);
        		iSingletons.DpController().DataProviderL(targets[0]).ExecuteProxyRequestL(Request(), Connection(), *this);
        		}
        	else
        		{
	            TInt dpID(KErrNotFound);
	            if (storages.LogicalStorageId(KStorageId))
	                {
	                dpID = storages.LogicalStorageOwner(KStorageId);
	                }
	            else
	                {
	                dpID = storages.PhysicalStorageOwner(KStorageId);
	                }
                OstTrace1(TRACE_NORMAL, DUP6_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, 
                        "dpID = %d", dpID);
	            if( targets.Find( dpID ) == KErrNotFound )
	                {
	                OstTrace0( TRACE_NORMAL, DUP7_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL, 
	                        "No target dp is found, so send one GeneralError response." );	                
	                SendResponseL( EMTPRespCodeGeneralError );
	                }
	            else
	                {
	                iSingletons.DpController().DataProviderL(dpID).ExecuteProxyRequestL(Request(), Connection(), *this);
	                }
        		}
            }
        else
            {
            OstTrace0( TRACE_NORMAL, DUP8_CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL,"StorageID is invalid." );
            SendResponseL( EMTPRespCodeInvalidStorageID );
            }
    	}	
    CleanupStack::PopAndDestroy(&targets);

    OstTraceFunctionExit0( CMTPSENDOBJECTINFO_DOHANDLESENDOBJECTINFOCOMPLETEL_EXIT );
    }

#ifdef _DEBUG
void CMTPSendObjectInfo::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus)
#else
void CMTPSendObjectInfo::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus)
#endif
    {
    __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy));
    MMTPType::CopyL(*iObjectInfo, aData);
    TRequestStatus* status = &aStatus;
    User::RequestComplete(status, KErrNone);
    }

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

#ifdef _DEBUG
void CMTPSendObjectInfo::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus)
#else
void CMTPSendObjectInfo::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus)
#endif
    {
    __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy));
    MMTPType::CopyL(aResponse, iResponse);
    TRequestStatus* status = &aStatus;
    User::RequestComplete(status, KErrNone);
    }

void CMTPSendObjectInfo::ProxyTransactionCompleteL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
    {
    __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy));
    iFramework.SendResponseL(iResponse, aRequest, aConnection);
    }