|
1 // Copyright (c) 2006-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 #include <mtp/tmtptyperequest.h> |
|
17 #include <mtp/mmtpdataproviderframework.h> |
|
18 #include <mtp/mtpprotocolconstants.h> |
|
19 #include <mtp/cmtptypeobjectproplist.h> |
|
20 |
|
21 #include "cmtpdataprovider.h" |
|
22 #include "cmtpdataprovidercontroller.h" |
|
23 #include "cmtpparserrouter.h" |
|
24 #include "cmtpsendobjectproplist.h" |
|
25 #include "mtpproxydppanic.h" |
|
26 #include "rmtpframework.h" |
|
27 #include "cmtpstoragemgr.h" |
|
28 |
|
29 /** |
|
30 Verification data for the SendObjectPropList request |
|
31 */ |
|
32 const TMTPRequestElementInfo KMTPSendObjectPropListPolicy[] = |
|
33 { |
|
34 {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeStorageId, EMTPElementAttrWrite, 1, 0, 0}, |
|
35 {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeObjectHandle, (EMTPElementAttrDir | EMTPElementAttrWrite), 2, KMTPHandleAll, KMTPHandleNone} |
|
36 }; |
|
37 |
|
38 /** |
|
39 Two-phase construction method |
|
40 @param aFramework The data provider framework |
|
41 @param aConnection The connection from which the request comes |
|
42 @return a pointer to the created request processor object |
|
43 */ |
|
44 MMTPRequestProcessor* CMTPSendObjectPropList::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) |
|
45 { |
|
46 CMTPSendObjectPropList* self = new (ELeave) CMTPSendObjectPropList(aFramework, aConnection); |
|
47 CleanupStack::PushL(self); |
|
48 self->ConstructL(); |
|
49 CleanupStack::Pop(self); |
|
50 return self; |
|
51 } |
|
52 |
|
53 /** |
|
54 Destructor |
|
55 */ |
|
56 CMTPSendObjectPropList::~CMTPSendObjectPropList() |
|
57 { |
|
58 delete iObjectPropList; |
|
59 iSingletons.Close(); |
|
60 } |
|
61 |
|
62 /** |
|
63 Standard c++ constructor |
|
64 */ |
|
65 CMTPSendObjectPropList::CMTPSendObjectPropList(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) : |
|
66 CMTPRequestProcessor(aFramework, aConnection, (sizeof(KMTPSendObjectPropListPolicy) / sizeof(TMTPRequestElementInfo)), KMTPSendObjectPropListPolicy) |
|
67 { |
|
68 |
|
69 } |
|
70 |
|
71 /** |
|
72 Second phase constructor. |
|
73 */ |
|
74 void CMTPSendObjectPropList::ConstructL() |
|
75 { |
|
76 iSingletons.OpenL(); |
|
77 } |
|
78 |
|
79 void CMTPSendObjectPropList::ServiceL() |
|
80 { |
|
81 delete iObjectPropList; |
|
82 iObjectPropList = NULL; |
|
83 iObjectPropList = CMTPTypeObjectPropList::NewL(); |
|
84 ReceiveDataL(*iObjectPropList); |
|
85 } |
|
86 |
|
87 TBool CMTPSendObjectPropList::HasDataphase() const |
|
88 { |
|
89 return ETrue; |
|
90 } |
|
91 |
|
92 TBool CMTPSendObjectPropList::DoHandleResponsePhaseL() |
|
93 { |
|
94 TMTPResponseCode rsp(EMTPRespCodeOK); |
|
95 |
|
96 TUint formatcode = Request().Uint32(TMTPTypeResponse::EResponseParameter3); |
|
97 |
|
98 if( EMTPFormatCodeAssociation != formatcode ) |
|
99 { |
|
100 //Here, it must be that FormatCode is supported by multi DPs and the first Parameter (StorageID) should be used. |
|
101 //Because if only one target DP, Parser&Router will directly dispatch the request to it |
|
102 //if no target DP, the request will be dispatch to Device DP. |
|
103 |
|
104 RArray<TUint> targets; |
|
105 CleanupClosePushL(targets); |
|
106 CMTPParserRouter::TRoutingParameters params(*iRequest, iConnection); |
|
107 iSingletons.Router().ParseOperationRequestL(params); |
|
108 iSingletons.Router().RouteOperationRequestL(params, targets); |
|
109 CMTPStorageMgr& storages(iSingletons.StorageMgr()); |
|
110 const TUint KStorageId = Request().Uint32(TMTPTypeResponse::EResponseParameter1); |
|
111 if( KMTPNotSpecified32 == KStorageId) |
|
112 { |
|
113 rsp = EMTPRespCodeGeneralError; |
|
114 } |
|
115 else if( storages.ValidStorageId(KStorageId) ) |
|
116 { |
|
117 TInt dpID(KErrNotFound); |
|
118 if (storages.LogicalStorageId(KStorageId)) |
|
119 { |
|
120 dpID = storages.LogicalStorageOwner(KStorageId); |
|
121 } |
|
122 else |
|
123 { |
|
124 dpID = storages.PhysicalStorageOwner(KStorageId); |
|
125 } |
|
126 |
|
127 if( targets.Find( dpID ) == KErrNotFound ) |
|
128 { |
|
129 rsp = EMTPRespCodeGeneralError; |
|
130 } |
|
131 else |
|
132 { |
|
133 iSingletons.DpController().DataProviderL(dpID).ExecuteProxyRequestL(Request(), Connection(), *this); |
|
134 } |
|
135 } |
|
136 else |
|
137 { |
|
138 rsp = EMTPRespCodeInvalidStorageID; |
|
139 } |
|
140 |
|
141 CleanupStack::PopAndDestroy(&targets); |
|
142 |
|
143 } |
|
144 else |
|
145 { |
|
146 /* |
|
147 Only requests with an ObjectFormatCode of EMTPFormatCodeAssociation |
|
148 are routed to the proxy DP. Locate and extract the association type from |
|
149 the received ObjectPropList dataset. |
|
150 */ |
|
151 TUint32 count(iObjectPropList->NumberOfElements()); |
|
152 iObjectPropList->ResetCursor(); |
|
153 TInt type(KErrNotFound); |
|
154 TUint16 tmpAssocValue(EMTPAssociationTypeGenericFolder); |
|
155 for (TUint i(0); ((rsp == EMTPRespCodeOK) && (type == KErrNotFound) && (i < count)); i++) |
|
156 { |
|
157 CMTPTypeObjectPropListElement& prop=iObjectPropList->GetNextElementL(); |
|
158 if (prop.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode) == EMTPObjectPropCodeAssociationType) |
|
159 { |
|
160 if (prop.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16) |
|
161 { |
|
162 rsp = EMTPRespCodeInvalidObjectPropFormat; |
|
163 } |
|
164 else |
|
165 { |
|
166 type = i; |
|
167 tmpAssocValue = prop.Uint16L(CMTPTypeObjectPropListElement::EValue); |
|
168 } |
|
169 } |
|
170 } |
|
171 TUint16 assocValue; |
|
172 if ((type == KErrNotFound) && |
|
173 (rsp == EMTPRespCodeOK)) |
|
174 { |
|
175 // If no property type is specified, create a generic folder |
|
176 assocValue = EMTPAssociationTypeGenericFolder; |
|
177 } |
|
178 else |
|
179 { |
|
180 assocValue = tmpAssocValue; |
|
181 } |
|
182 |
|
183 if (rsp == EMTPRespCodeOK) |
|
184 { |
|
185 CMTPParserRouter::TRoutingParameters params(*iRequest, iConnection); |
|
186 iSingletons.Router().ParseOperationRequestL(params); |
|
187 params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatCode, EMTPFormatCodeAssociation); |
|
188 params.SetParam(CMTPParserRouter::TRoutingParameters::EParamFormatSubCode, assocValue); |
|
189 RArray<TUint> targets; |
|
190 CleanupClosePushL(targets); |
|
191 iSingletons.Router().RouteOperationRequestL(params, targets); |
|
192 __ASSERT_DEBUG((targets.Count() == 1), User::Invariant()); |
|
193 iSingletons.DpController().DataProviderL(targets[0]).ExecuteProxyRequestL(Request(), Connection(), *this); |
|
194 CleanupStack::PopAndDestroy(&targets); |
|
195 } |
|
196 } |
|
197 if (rsp != EMTPRespCodeOK) |
|
198 { |
|
199 SendResponseL(rsp); |
|
200 } |
|
201 return EFalse; |
|
202 } |
|
203 |
|
204 #ifdef _DEBUG |
|
205 void CMTPSendObjectPropList::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus) |
|
206 #else |
|
207 void CMTPSendObjectPropList::ProxyReceiveDataL(MMTPType& aData, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus) |
|
208 #endif |
|
209 { |
|
210 __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy)); |
|
211 |
|
212 CMTPTypeObjectPropList* targetObjectPropList = static_cast<CMTPTypeObjectPropList*>(&aData); |
|
213 |
|
214 targetObjectPropList->AppendObjectPropListL(*iObjectPropList); |
|
215 |
|
216 TRequestStatus* status = &aStatus; |
|
217 User::RequestComplete(status, KErrNone); |
|
218 } |
|
219 |
|
220 void CMTPSendObjectPropList::ProxySendDataL(const MMTPType& /*aData*/, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& /*aStatus*/) |
|
221 { |
|
222 Panic(EMTPWrongRequestPhase); |
|
223 } |
|
224 |
|
225 #ifdef _DEBUG |
|
226 void CMTPSendObjectPropList::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, TRequestStatus& aStatus) |
|
227 #else |
|
228 void CMTPSendObjectPropList::ProxySendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& /*aRequest*/, MMTPConnection& /*aConnection*/, TRequestStatus& aStatus) |
|
229 #endif |
|
230 { |
|
231 __ASSERT_DEBUG(iRequest == &aRequest && &iConnection == &aConnection, Panic(EMTPNotSameRequestProxy)); |
|
232 MMTPType::CopyL(aResponse, iResponse); |
|
233 TRequestStatus* status = &aStatus; |
|
234 User::RequestComplete(status, KErrNone); |
|
235 } |
|
236 |
|
237 void CMTPSendObjectPropList::ProxyTransactionCompleteL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
238 { |
|
239 __ASSERT_DEBUG(((iRequest == &aRequest) && (&iConnection == &aConnection)), Panic(EMTPNotSameRequestProxy)); |
|
240 iFramework.SendResponseL(iResponse, aRequest, aConnection); |
|
241 } |
|
242 |
|
243 void CMTPSendObjectPropList::SendResponseL(TUint16 aCode) |
|
244 { |
|
245 const TMTPTypeRequest& req(Request()); |
|
246 iResponse.SetUint16(TMTPTypeResponse::EResponseCode, aCode); |
|
247 iResponse.SetUint32(TMTPTypeResponse::EResponseSessionID, req.Uint32(TMTPTypeRequest::ERequestSessionID)); |
|
248 iResponse.SetUint32(TMTPTypeResponse::EResponseTransactionID, req.Uint32(TMTPTypeRequest::ERequestTransactionID)); |
|
249 iFramework.SendResponseL(iResponse, req, Connection()); |
|
250 } |
|
251 |