mtpfws/mtpfw/dataproviders/proxydp/src/cmtpsendobjectproplist.cpp
changeset 0 d0791faffa3f
child 15 f85613f12947
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/dataproviders/proxydp/src/cmtpsendobjectproplist.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,251 @@
+// 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/cmtptypeobjectproplist.h>
+
+#include "cmtpdataprovider.h"
+#include "cmtpdataprovidercontroller.h"
+#include "cmtpparserrouter.h"
+#include "cmtpsendobjectproplist.h"
+#include "mtpproxydppanic.h"
+#include "rmtpframework.h"
+#include "cmtpstoragemgr.h"
+
+/**
+Verification data for the SendObjectPropList request
+*/
+const TMTPRequestElementInfo KMTPSendObjectPropListPolicy[] = 
+    {
+        {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeStorageId, EMTPElementAttrWrite, 1, 0, 0}, 
+        {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeObjectHandle, (EMTPElementAttrDir | EMTPElementAttrWrite), 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* CMTPSendObjectPropList::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection)
+    {
+    CMTPSendObjectPropList* self = new (ELeave) CMTPSendObjectPropList(aFramework, aConnection);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+Destructor
+*/    
+CMTPSendObjectPropList::~CMTPSendObjectPropList()
+    {
+    delete iObjectPropList;
+    iSingletons.Close();
+    }
+
+/**
+Standard c++ constructor
+*/    
+CMTPSendObjectPropList::CMTPSendObjectPropList(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) :
+    CMTPRequestProcessor(aFramework, aConnection, (sizeof(KMTPSendObjectPropListPolicy) / sizeof(TMTPRequestElementInfo)), KMTPSendObjectPropListPolicy)
+    {
+    
+    }
+    
+/**
+Second phase constructor.
+*/
+void CMTPSendObjectPropList::ConstructL()
+    {
+    iSingletons.OpenL();
+    }
+    
+void CMTPSendObjectPropList::ServiceL()
+    {
+    delete iObjectPropList;
+    iObjectPropList = NULL;
+    iObjectPropList = CMTPTypeObjectPropList::NewL();
+    ReceiveDataL(*iObjectPropList);
+    }
+
+TBool CMTPSendObjectPropList::HasDataphase() const
+    {
+    return ETrue;
+    }
+    
+TBool CMTPSendObjectPropList::DoHandleResponsePhaseL()
+    {
+    TMTPResponseCode rsp(EMTPRespCodeOK);
+    
+    TUint formatcode = Request().Uint32(TMTPTypeResponse::EResponseParameter3);
+    
+    if( EMTPFormatCodeAssociation != formatcode )
+        {
+        //Here, it must be that FormatCode is supported by multi DPs and the first Parameter (StorageID) should be used.
+        //Because if only one target DP, Parser&Router will directly dispatch the request to it
+        //if no target DP, the request will be dispatch to Device DP.
+        
+        RArray<TUint> targets;
+        CleanupClosePushL(targets);
+        CMTPParserRouter::TRoutingParameters params(*iRequest, iConnection);
+        iSingletons.Router().ParseOperationRequestL(params);
+        iSingletons.Router().RouteOperationRequestL(params, targets);
+        CMTPStorageMgr& storages(iSingletons.StorageMgr());
+        const TUint KStorageId = Request().Uint32(TMTPTypeResponse::EResponseParameter1);
+        if( KMTPNotSpecified32 == KStorageId)
+            {
+            rsp = EMTPRespCodeGeneralError;
+            }
+        else if( storages.ValidStorageId(KStorageId) )
+            {
+            TInt dpID(KErrNotFound);
+            if (storages.LogicalStorageId(KStorageId))
+                {
+                dpID = storages.LogicalStorageOwner(KStorageId);
+                }
+            else
+                {
+                dpID = storages.PhysicalStorageOwner(KStorageId);
+                }
+            
+            if( targets.Find( dpID ) == KErrNotFound )
+                {
+                rsp = EMTPRespCodeGeneralError;
+                }
+            else
+                {
+                iSingletons.DpController().DataProviderL(dpID).ExecuteProxyRequestL(Request(), Connection(), *this);
+                }
+            }
+        else
+            {
+            rsp = EMTPRespCodeInvalidStorageID;
+            }
+        
+        CleanupStack::PopAndDestroy(&targets);
+        
+        }
+    else
+        {
+        /* 
+        Only requests with an ObjectFormatCode of EMTPFormatCodeAssociation 
+        are routed to the proxy DP. Locate and extract the association type from 
+        the received ObjectPropList dataset.
+        */
+        TUint32 count(iObjectPropList->NumberOfElements());
+		iObjectPropList->ResetCursor();		
+        TInt    type(KErrNotFound);
+        TUint16 tmpAssocValue(EMTPAssociationTypeGenericFolder);
+        for (TUint i(0); ((rsp == EMTPRespCodeOK) && (type == KErrNotFound) && (i < count)); i++)
+            {
+			CMTPTypeObjectPropListElement& prop=iObjectPropList->GetNextElementL();			
+            if (prop.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode) == EMTPObjectPropCodeAssociationType)
+                {
+                if (prop.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16)
+                    {
+                    rsp = EMTPRespCodeInvalidObjectPropFormat;
+                    }
+                else
+                    {
+                    type = i;
+					tmpAssocValue = prop.Uint16L(CMTPTypeObjectPropListElement::EValue);
+                    }
+                }
+            }	        
+        TUint16 assocValue;
+        if ((type == KErrNotFound) &&
+            (rsp == EMTPRespCodeOK))
+            {
+            // If no property type is specified, create a generic folder
+            assocValue = EMTPAssociationTypeGenericFolder;
+            }
+        else
+            {
+            assocValue = tmpAssocValue;
+            }
+        
+        if (rsp == EMTPRespCodeOK)
+            {
+            CMTPParserRouter::TRoutingParameters params(*iRequest, iConnection);
+            iSingletons.Router().ParseOperationRequestL(params);
+            params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatCode, EMTPFormatCodeAssociation);
+            params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatSubCode, assocValue);
+            RArray<TUint> targets;
+            CleanupClosePushL(targets);
+            iSingletons.Router().RouteOperationRequestL(params, targets);
+            __ASSERT_DEBUG((targets.Count() == 1), User::Invariant());
+            iSingletons.DpController().DataProviderL(targets[0]).ExecuteProxyRequestL(Request(), Connection(), *this);
+            CleanupStack::PopAndDestroy(&targets);
+            }
+        }
+    if (rsp != EMTPRespCodeOK)
+        {
+        SendResponseL(rsp);
+        }
+    return EFalse;
+    }
+
+#ifdef _DEBUG
+void CMTPSendObjectPropList::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus)
+#else
+void CMTPSendObjectPropList::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus)
+#endif
+    {
+    __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy));
+
+	CMTPTypeObjectPropList* targetObjectPropList = static_cast<CMTPTypeObjectPropList*>(&aData); 
+	
+	targetObjectPropList->AppendObjectPropListL(*iObjectPropList);
+
+    TRequestStatus* status = &aStatus;
+    User::RequestComplete(status, KErrNone);
+    }
+    
+void CMTPSendObjectPropList::ProxySendDataL(const MMTPType& /*aData*/, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& /*aStatus*/)
+    {
+    Panic(EMTPWrongRequestPhase);
+    }
+    
+#ifdef _DEBUG    
+void CMTPSendObjectPropList::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus)
+#else
+void CMTPSendObjectPropList::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 CMTPSendObjectPropList::ProxyTransactionCompleteL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
+    {
+    __ASSERT_DEBUG(((iRequest == &aRequest) && (&iConnection == &aConnection)), Panic(EMTPNotSameRequestProxy));
+    iFramework.SendResponseL(iResponse, aRequest, aConnection);
+    }
+    
+void CMTPSendObjectPropList::SendResponseL(TUint16 aCode)
+    {
+    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());
+    }
+