|
1 // Copyright (c) 2004-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 the License "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 // f32test\testusbcldd\src\dlddtestusbcchannel.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "usbcdesc.h" |
|
19 #include "dtestusblogdev.h" |
|
20 #include "testusbc.h" |
|
21 |
|
22 extern TDynamicDfcQue* gDfcQ; |
|
23 |
|
24 const TUsbcEndpointData DLddTestUsbcChannel::iEndpointData[] = |
|
25 { |
|
26 {{KUsbEpSize64, (KUsbEpTypeControl | KUsbEpDirBidirect)}, EFalse}, |
|
27 {{KUsbEpSize64, (KUsbEpTypeBulk | KUsbEpDirOut)}, EFalse}, |
|
28 {{KUsbEpSize64, (KUsbEpTypeBulk | KUsbEpDirIn )}, EFalse}, |
|
29 {{KUsbEpSize64, (KUsbEpTypeBulk | KUsbEpDirOut)}, EFalse}, |
|
30 {{KUsbEpSize64, (KUsbEpTypeBulk | KUsbEpDirIn )}, EFalse}, |
|
31 {{KUsbEpNotAvailable, KUsbEpNotAvailable}, EFalse} |
|
32 }; |
|
33 |
|
34 // The EKA1 base class needs a DLogicalDevice* for its constructor |
|
35 DLddTestUsbcChannel::DLddTestUsbcChannel(RPointerArray<DTestUsbcEndpoint>& aEndpoints) : |
|
36 iDescriptors(NULL), |
|
37 iIfcSet(this, 0), |
|
38 iEndpoints(aEndpoints), |
|
39 iDeviceState(EUsbcDeviceStateConfigured) |
|
40 { |
|
41 iClient = &Kern::CurrentThread(); |
|
42 iClient->Open(); |
|
43 } |
|
44 |
|
45 DLddTestUsbcChannel::~DLddTestUsbcChannel() |
|
46 { |
|
47 } |
|
48 |
|
49 TInt DLddTestUsbcChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) |
|
50 { |
|
51 TInt err = KErrNone; |
|
52 // Setup LDD for receiving client messages |
|
53 SetDfcQ(gDfcQ); |
|
54 iMsgQ.Receive(); |
|
55 |
|
56 _LIT(KEmptyString, ""); |
|
57 err = iDescriptors.Init( |
|
58 TUsbcDeviceDescriptor::New(0, 0, 0, 0, 0, 0, 0, 0), |
|
59 TUsbcConfigDescriptor::New(0, ETrue, ETrue, 0), |
|
60 TUsbcLangIdDescriptor::New(0), |
|
61 TUsbcStringDescriptor::New(KEmptyString), |
|
62 TUsbcStringDescriptor::New(KEmptyString), |
|
63 TUsbcStringDescriptor::New(KEmptyString), |
|
64 TUsbcStringDescriptor::New(KEmptyString) |
|
65 ); |
|
66 |
|
67 return err; |
|
68 } |
|
69 |
|
70 void DLddTestUsbcChannel::HandleMsg(TMessageBase* aMsg) |
|
71 { |
|
72 TThreadMessage& m = *(TThreadMessage*)aMsg; |
|
73 TInt id = m.iValue; |
|
74 if (id == (TInt)ECloseMsg) |
|
75 { |
|
76 m.Complete(KErrNone, EFalse); |
|
77 return; |
|
78 } |
|
79 else if (id == KMaxTInt) |
|
80 { |
|
81 // Cancel request. |
|
82 TInt mask = m.Int0(); |
|
83 DTestUsbcEndpoint* pEndpoint = NULL; |
|
84 switch (mask) |
|
85 { |
|
86 case RDevUsbcClient::ERequestEp0Cancel: |
|
87 pEndpoint = iEndpoints[0]; |
|
88 pEndpoint->DoCancel(); |
|
89 break; |
|
90 case RDevUsbcClient::ERequestEp1Cancel: |
|
91 pEndpoint = iEndpoints[FindRealEndpoint(1)]; |
|
92 pEndpoint->DoCancel(); |
|
93 break; |
|
94 case RDevUsbcClient::ERequestEp2Cancel: |
|
95 pEndpoint = iEndpoints[FindRealEndpoint(2)]; |
|
96 pEndpoint->DoCancel(); |
|
97 break; |
|
98 case RDevUsbcClient::ERequestEp3Cancel: |
|
99 pEndpoint = iEndpoints[FindRealEndpoint(3)]; |
|
100 pEndpoint->DoCancel(); |
|
101 break; |
|
102 case RDevUsbcClient::ERequestEp4Cancel: |
|
103 pEndpoint = iEndpoints[FindRealEndpoint(4)]; |
|
104 pEndpoint->DoCancel(); |
|
105 break; |
|
106 case RDevUsbcClient::ERequestEp5Cancel: |
|
107 pEndpoint = iEndpoints[FindRealEndpoint(5)]; |
|
108 pEndpoint->DoCancel(); |
|
109 break; |
|
110 case RDevUsbcClient::ERequestAlternateDeviceStatusNotifyCancel: |
|
111 CancelAlternateDeviceStatusNotify(); |
|
112 break; |
|
113 default: |
|
114 m.Complete(KErrNotSupported, ETrue); |
|
115 return; |
|
116 } |
|
117 m.Complete(KErrNone, ETrue); |
|
118 return; |
|
119 } |
|
120 |
|
121 if (id < 0) |
|
122 { |
|
123 // DoRequest |
|
124 TRequestStatus* pS = (TRequestStatus*)m.Ptr0(); |
|
125 DoRequest(~id, pS, m.Ptr1(), m.Ptr2()); |
|
126 m.Complete(KErrNone, ETrue); |
|
127 } |
|
128 else |
|
129 { |
|
130 // DoControl |
|
131 TInt r = DoControl(id, m.Ptr0(), m.Ptr1()); |
|
132 m.Complete(r, ETrue); |
|
133 } |
|
134 } |
|
135 |
|
136 TInt DLddTestUsbcChannel::DoCancel(TInt /*aReqNo*/) |
|
137 { |
|
138 return KErrNone; |
|
139 } |
|
140 |
|
141 void DLddTestUsbcChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2) |
|
142 { |
|
143 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest 0x%08x"),aReqNo)); |
|
144 TInt r = KErrNone; |
|
145 //If request is ep number then do a transfer request. |
|
146 if(aReqNo > KUsbcMaxEpNumber) |
|
147 { |
|
148 if (aReqNo == RDevTestUsbcClient::ETestRequestNotifyEndpointStatus) |
|
149 { |
|
150 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestRequestNotifyEndpointStatus"))); |
|
151 r = HostEndpointStatusNotify((TInt)a1, aStatus); |
|
152 } |
|
153 else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify) |
|
154 { |
|
155 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ERequestAlternateDeviceStatusNotify"))); |
|
156 r = SetAlternateDeviceStatusNotify(aStatus, (TUint*)a1); |
|
157 } |
|
158 else if (aReqNo == RDevUsbcClient::ERequestReEnumerate) |
|
159 { |
|
160 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ERequestReEnumerate"))); |
|
161 r = ReEnumerate((TRequestStatus*)a1); |
|
162 } |
|
163 else |
|
164 { |
|
165 Kern::RequestComplete(iClient, aStatus, KErrNotSupported); |
|
166 } |
|
167 } |
|
168 else |
|
169 { |
|
170 r = DoTransferAsyncReq(aReqNo, a1, a2, *aStatus); |
|
171 } |
|
172 |
|
173 if (r != KErrNone) |
|
174 { |
|
175 Kern::RequestComplete(iClient, aStatus, r); |
|
176 } |
|
177 } |
|
178 |
|
179 TInt DLddTestUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2) |
|
180 { |
|
181 TInt r=KErrNone; |
|
182 TDes8& a1Buf = *((TDes8*)a1); |
|
183 TDes8& a2Buf = *((TDes8*)a2); |
|
184 TPtrC8 pZeroDesc(NULL,0); |
|
185 |
|
186 |
|
187 switch (aFunction) |
|
188 { |
|
189 case RDevUsbcClient::EControlEndpointZeroRequestError: |
|
190 { |
|
191 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlEndpointZeroRequestError"))); |
|
192 r = KErrNone; |
|
193 break; |
|
194 } |
|
195 |
|
196 case RDevUsbcClient::EControlEndpointCaps: |
|
197 { |
|
198 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlEndpointCaps"))); |
|
199 r = __THREADWRITE(iClient, a1, pZeroDesc); |
|
200 if(r == KErrNone) |
|
201 { |
|
202 TBuf8<KMaxTUint8> aBuf; |
|
203 memclr(&aBuf, sizeof(aBuf)); |
|
204 TPtr8 endpointCfg((TUint8*)&aBuf,0,sizeof(aBuf)); |
|
205 |
|
206 r = Kern::ThreadDesRead(iClient,a1,endpointCfg,0,0); |
|
207 if(r == KErrNone) |
|
208 { |
|
209 endpointCfg.Copy(reinterpret_cast<const TUint8*>(iEndpointData), |
|
210 Min(endpointCfg.MaxLength(), |
|
211 sizeof(TUsbcEndpointData[5]))); |
|
212 r = Kern::ThreadDesWrite(iClient,a1,endpointCfg,0,KTruncateToMaxLength,iClient); |
|
213 } |
|
214 } |
|
215 |
|
216 if(r != KErrNone) |
|
217 { |
|
218 __THREADPANIC(iClient, r); |
|
219 } |
|
220 |
|
221 break; |
|
222 } |
|
223 |
|
224 case RDevUsbcClient::EControlDeviceCaps: |
|
225 { |
|
226 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlDeviceCaps"))); |
|
227 r = __THREADWRITE(iClient, a1, pZeroDesc); |
|
228 if(r!=KErrNone) |
|
229 { |
|
230 __THREADPANIC(iClient, r); |
|
231 } |
|
232 TUsbDeviceCaps caps; |
|
233 caps().iTotalEndpoints = KMaxEndpointsPerClient; |
|
234 caps().iConnect = ETrue; |
|
235 caps().iSelfPowered = ETrue; |
|
236 caps().iRemoteWakeup = ETrue; |
|
237 TBuf8<KMaxTUint8> aBuf; |
|
238 memclr(&aBuf, sizeof(aBuf)); |
|
239 TPtr8 cfg((TUint8*)&aBuf,0,sizeof(aBuf)); |
|
240 r=Kern::ThreadDesRead(iClient,a1,cfg,0,0); |
|
241 cfg = caps.Left(Min(caps.Length(), cfg.MaxLength())); |
|
242 r=Kern::ThreadDesWrite(iClient,a1,cfg,0,KTruncateToMaxLength,iClient); |
|
243 break; |
|
244 } |
|
245 |
|
246 case RDevUsbcClient::EControlDeviceStatus: |
|
247 { |
|
248 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlDeviceStatus"))); |
|
249 r = __THREADRAWWRITE(iClient, a1, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState)); |
|
250 if(r != KErrNone) |
|
251 { |
|
252 __THREADPANIC(iClient, r); |
|
253 } |
|
254 break; |
|
255 } |
|
256 |
|
257 case RDevUsbcClient::EControlHaltEndpoint: |
|
258 { |
|
259 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlHaltEndpoint"))); |
|
260 r = HaltClearEndpoint(ETrue, (TInt)a1); |
|
261 break; |
|
262 } |
|
263 |
|
264 case RDevUsbcClient::EControlGetDeviceDescriptor: |
|
265 { |
|
266 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetDeviceDescriptor"))); |
|
267 r = __THREADWRITE(iClient, a1, pZeroDesc); |
|
268 if(r != KErrNone) |
|
269 { |
|
270 __THREADPANIC(iClient, r); |
|
271 } |
|
272 r = iDescriptors.GetDeviceDescriptorTC(iClient, a1Buf); |
|
273 break; |
|
274 } |
|
275 |
|
276 case RDevUsbcClient::EControlSetDeviceDescriptor: |
|
277 { |
|
278 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetDeviceDescriptor"))); |
|
279 r = iDescriptors.SetDeviceDescriptorTC(iClient, a1Buf); |
|
280 break; |
|
281 } |
|
282 |
|
283 case RDevUsbcClient::EControlGetDeviceDescriptorSize: |
|
284 { |
|
285 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetDeviceDescriptorSize"))); |
|
286 if(a1 != NULL) |
|
287 { |
|
288 const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Device), sizeof(KUsbDescSize_Device)); |
|
289 r = __THREADWRITE(iClient, a1, size); |
|
290 } |
|
291 else |
|
292 { |
|
293 r = KErrArgument; |
|
294 } |
|
295 break; |
|
296 } |
|
297 |
|
298 case RDevUsbcClient::EControlGetConfigurationDescriptor: |
|
299 { |
|
300 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetConfigurationDescriptor"))); |
|
301 r = __THREADWRITE(iClient, a1, pZeroDesc); // set client descriptor length to zero |
|
302 if(r != KErrNone) |
|
303 { |
|
304 __THREADPANIC(iClient, r); |
|
305 } |
|
306 r = iDescriptors.GetConfigurationDescriptorTC(iClient, a1Buf); |
|
307 break; |
|
308 } |
|
309 |
|
310 case RDevUsbcClient::EControlSetConfigurationDescriptor: |
|
311 { |
|
312 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetConfigurationDescriptor"))); |
|
313 r = iDescriptors.SetConfigurationDescriptorTC(iClient, a1Buf); |
|
314 break; |
|
315 } |
|
316 |
|
317 case RDevUsbcClient::EControlGetConfigurationDescriptorSize: |
|
318 { |
|
319 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetConfigurationDescriptorSize"))); |
|
320 if(a1 != NULL) |
|
321 { |
|
322 const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Config), sizeof(KUsbDescSize_Config)); |
|
323 r = __THREADWRITE(iClient, a1, size); |
|
324 } |
|
325 else |
|
326 { |
|
327 r=KErrArgument; |
|
328 } |
|
329 break; |
|
330 } |
|
331 |
|
332 case RDevUsbcClient::EControlGetInterfaceDescriptor: |
|
333 { |
|
334 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetInterfaceDescriptor"))); |
|
335 r = iDescriptors.GetInterfaceDescriptorTC(iClient, a2Buf, 0, (TInt)a1); |
|
336 break; |
|
337 } |
|
338 |
|
339 case RDevUsbcClient::EControlSetInterfaceDescriptor: |
|
340 { |
|
341 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetInterfaceDescriptor"))); |
|
342 TBuf8<KUsbDescSize_Interface> new_ifc; |
|
343 r = __THREADWRITE(iClient, a2, new_ifc); |
|
344 if (r != KErrNone) |
|
345 { |
|
346 break; |
|
347 } |
|
348 r = iDescriptors.SetInterfaceDescriptor(new_ifc, 0, (TInt)a1); |
|
349 break; |
|
350 } |
|
351 |
|
352 case RDevUsbcClient::EControlGetInterfaceDescriptorSize: |
|
353 { |
|
354 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetInterfaceDescriptorSize"))); |
|
355 if (a2 != NULL) |
|
356 { |
|
357 const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Interface), sizeof(KUsbDescSize_Interface)); |
|
358 r = __THREADWRITE(iClient, a2, size); |
|
359 } |
|
360 else |
|
361 { |
|
362 r = KErrArgument; |
|
363 } |
|
364 break; |
|
365 } |
|
366 |
|
367 case RDevUsbcClient::EControlGetEndpointDescriptor: |
|
368 { |
|
369 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetEndpointDescriptor"))); |
|
370 TEndpointDescriptorInfo info; |
|
371 r = __THREADRAWREAD(iClient, a1,(TUint8*)&info, (TInt)sizeof(info)); |
|
372 if(r != KErrNone) |
|
373 { |
|
374 __THREADPANIC(iClient, r); |
|
375 } |
|
376 r = iDescriptors.GetEndpointDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, (TUint8)info.iEndpoint); |
|
377 } |
|
378 |
|
379 case RDevUsbcClient::EControlSetEndpointDescriptor: |
|
380 { |
|
381 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetEndpointDescriptor"))); |
|
382 TEndpointDescriptorInfo info; |
|
383 r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TEndpointDescriptorInfo)); |
|
384 if(r != KErrNone) |
|
385 __THREADPANIC(iClient, r); |
|
386 r = iDescriptors.SetEndpointDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, (TUint8)info.iEndpoint); |
|
387 break; |
|
388 } |
|
389 |
|
390 case RDevUsbcClient::EControlGetEndpointDescriptorSize: |
|
391 { |
|
392 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetEndpointDescriptorSize"))); |
|
393 TEndpointDescriptorInfo info; |
|
394 r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TEndpointDescriptorInfo)); |
|
395 if(r != KErrNone) |
|
396 __THREADPANIC(iClient, r); |
|
397 TInt s; |
|
398 TInt r = iDescriptors.GetEndpointDescriptorSize(0, info.iSetting, (TUint8)info.iEndpoint, s); |
|
399 if (r == KErrNone) |
|
400 { |
|
401 TPtrC8 size(reinterpret_cast<const TUint8*>(&s), sizeof(s)); |
|
402 r = __THREADWRITE(iClient, &(info.iArg), size); |
|
403 } |
|
404 break; |
|
405 } |
|
406 |
|
407 case RDevUsbcClient::EControlSetCSInterfaceDescriptor: |
|
408 { |
|
409 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetCSInterfaceDescriptor"))); |
|
410 TCSDescriptorInfo info; |
|
411 r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TCSDescriptorInfo)); |
|
412 if(r != KErrNone) |
|
413 __THREADPANIC(iClient, r); |
|
414 r = iDescriptors.SetCSInterfaceDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, info.iSize); |
|
415 } |
|
416 break; |
|
417 |
|
418 case RDevUsbcClient::EControlDeviceDisconnectFromHost: |
|
419 { |
|
420 r = KErrNone; |
|
421 break; |
|
422 } |
|
423 |
|
424 case RDevUsbcClient::EControlDeviceConnectToHost: |
|
425 { |
|
426 r = KErrNone; |
|
427 break; |
|
428 } |
|
429 |
|
430 case RDevUsbcClient::EControlDevicePowerUpUdc: |
|
431 { |
|
432 r = KErrNone; |
|
433 break; |
|
434 } |
|
435 |
|
436 case RDevUsbcClient::EControlSetInterface: |
|
437 { |
|
438 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetInterface"))); |
|
439 TUsbcIfcInfo info; |
|
440 r = __THREADRAWREAD(iClient, a2, (TUint8*)&info, (TInt)sizeof(TUsbcIfcInfo)); |
|
441 if(r != KErrNone) |
|
442 __THREADPANIC(iClient, r); |
|
443 |
|
444 TUsbcInterfaceInfoBuf* interfaceData = info.iInterfaceData; |
|
445 TPtr8* ifcString = info.iString; |
|
446 r = SetInterface((TInt)a1, interfaceData, ifcString); |
|
447 } |
|
448 break; |
|
449 |
|
450 case RDevUsbcClient::EControlReleaseInterface: |
|
451 { |
|
452 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlReleaseInterface"))); |
|
453 r = ReleaseInterface((TInt)a1); |
|
454 break; |
|
455 } |
|
456 |
|
457 case RDevUsbcClient::EControlGetManufacturerStringDescriptor: |
|
458 { |
|
459 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor"))); |
|
460 r = iDescriptors.GetManufacturerStringDescriptorTC(iClient, a1Buf); |
|
461 break; |
|
462 } |
|
463 |
|
464 case RDevUsbcClient::EControlSetManufacturerStringDescriptor: |
|
465 { |
|
466 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetManufacturerStringDescriptor"))); |
|
467 r = iDescriptors.SetManufacturerStringDescriptorTC(iClient, a1Buf); |
|
468 break; |
|
469 } |
|
470 |
|
471 case RDevUsbcClient::EControlGetProductStringDescriptor: |
|
472 { |
|
473 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor"))); |
|
474 r = iDescriptors.GetProductStringDescriptorTC(iClient, a1Buf); |
|
475 break; |
|
476 } |
|
477 |
|
478 case RDevUsbcClient::EControlSetProductStringDescriptor: |
|
479 { |
|
480 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetProductStringDescriptor"))); |
|
481 r = iDescriptors.SetProductStringDescriptorTC(iClient, a1Buf); |
|
482 break; |
|
483 } |
|
484 |
|
485 case RDevUsbcClient::EControlGetSerialNumberStringDescriptor: |
|
486 { |
|
487 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor"))); |
|
488 r = iDescriptors.GetSerialNumberStringDescriptorTC(iClient, a1Buf); |
|
489 break; |
|
490 } |
|
491 |
|
492 case RDevUsbcClient::EControlSetSerialNumberStringDescriptor: |
|
493 { |
|
494 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetSerialNumberStringDescriptor"))); |
|
495 r = iDescriptors.SetSerialNumberStringDescriptorTC(iClient, a1Buf); |
|
496 break; |
|
497 } |
|
498 |
|
499 case RDevUsbcClient::EControlGetConfigurationStringDescriptor: |
|
500 { |
|
501 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor"))); |
|
502 r = iDescriptors.GetConfigurationStringDescriptorTC(iClient, a1Buf); |
|
503 break; |
|
504 } |
|
505 |
|
506 case RDevUsbcClient::EControlSetConfigurationStringDescriptor: |
|
507 { |
|
508 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetConfigurationStringDescriptor"))); |
|
509 r = iDescriptors.SetConfigurationStringDescriptorTC(iClient, a1Buf); |
|
510 break; |
|
511 } |
|
512 case RDevUsbcClient::EControlEndpointStatus: |
|
513 { |
|
514 TInt ep = (TInt)a1; |
|
515 DTestUsbcEndpoint* pEndpoint = iEndpoints[FindRealEndpoint(ep)]; |
|
516 TEndpointState state = EEndpointStateUnknown; |
|
517 if (pEndpoint->IsHalted()) |
|
518 { |
|
519 state = EEndpointStateStalled; |
|
520 } |
|
521 else |
|
522 { |
|
523 state = EEndpointStateNotStalled; |
|
524 } |
|
525 __THREADRAWWRITE(iClient, a2, (TUint8*)&state, (TInt)sizeof(state)); |
|
526 break; |
|
527 } |
|
528 |
|
529 case RDevTestUsbcClient::ETestControlReqEndpointStatusNotify: |
|
530 { |
|
531 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestControlReqEndpointStatusNotify"))); |
|
532 r = HostEndpointStatusNotify((TInt)a2, (TRequestStatus*)a1); |
|
533 break; |
|
534 } |
|
535 |
|
536 case RDevTestUsbcClient::ETestControlClearEndpoint: |
|
537 { |
|
538 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestControlClearEndpoint"))); |
|
539 r = ClearEndpoint((TInt)a1); |
|
540 break; |
|
541 } |
|
542 |
|
543 default: |
|
544 r = KErrNotSupported; |
|
545 } |
|
546 |
|
547 return r; |
|
548 } |
|
549 |
|
550 TInt DLddTestUsbcChannel::SetInterface(TInt aInterfaceNumber, |
|
551 TUsbcInterfaceInfoBuf *aUserInterfaceInfoBuf, |
|
552 TPtr8* aInterfaceString) |
|
553 { |
|
554 // The Interface Descriptor string is no interest to us |
|
555 // so leave that as is, the controller will have to take a local copy |
|
556 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Entry Interface#=%d Endpoints =%d"),aInterfaceNumber,(*aUserInterfaceInfoBuf)().iTotalEndpointsUsed)); |
|
557 TInt r = KErrNone; |
|
558 TUsbcEndpointInfo* pEndpointData=NULL; |
|
559 TInt numberOfEndpoints=0; |
|
560 TUsbcInterfaceInfoBuf interfaceBuff; |
|
561 TInt bufLen=interfaceBuff.Length(); |
|
562 TInt srcLen=__THREADDESLEN(iClient,aUserInterfaceInfoBuf); |
|
563 if(srcLen<bufLen) |
|
564 { |
|
565 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface can't copy"))); |
|
566 __THREADPANIC(iClient,EDesOverflow); |
|
567 } |
|
568 r = __THREADREAD(iClient, aUserInterfaceInfoBuf, interfaceBuff); |
|
569 if(r!=KErrNone) |
|
570 { |
|
571 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Copy failed reason=%d"),r)); |
|
572 __THREADPANIC(iClient,r); |
|
573 } |
|
574 pEndpointData=interfaceBuff().iEndpointData; |
|
575 |
|
576 // If an alternate interface is being asked for then do nothing |
|
577 // just pass it down to the Controller |
|
578 numberOfEndpoints=interfaceBuff().iTotalEndpointsUsed; |
|
579 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface 10 numberOfEndpoints=%d"),numberOfEndpoints)); |
|
580 |
|
581 // other endpoints |
|
582 for(TInt i=1;i<=numberOfEndpoints;i++,pEndpointData++) |
|
583 { |
|
584 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface for ep=%d"),i)); |
|
585 if(!ValidateEndpoint(pEndpointData)) |
|
586 { |
|
587 r=KErrUsbBadEndpoint; |
|
588 goto KillAll; |
|
589 } |
|
590 } |
|
591 |
|
592 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Calling controller"))); |
|
593 r=SetInterface(aInterfaceNumber, |
|
594 interfaceBuff().iClass, |
|
595 aInterfaceString, |
|
596 interfaceBuff().iTotalEndpointsUsed, |
|
597 interfaceBuff().iEndpointData); |
|
598 |
|
599 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface controller returned %d"),r)); |
|
600 if(r!=KErrNone) |
|
601 { |
|
602 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface failed reason=%d"),r)); |
|
603 goto KillAll; |
|
604 } |
|
605 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface ready to exit"))); |
|
606 |
|
607 return KErrNone; |
|
608 |
|
609 KillAll: |
|
610 return r; |
|
611 } |
|
612 |
|
613 TInt DLddTestUsbcChannel::SetInterface(TInt aInterfaceNumber, TUsbcClassInfo& aClass, |
|
614 TDesC8* aString, TInt aTotalEndpointsUsed, |
|
615 const TUsbcEndpointInfo aEndpointData[]) |
|
616 { |
|
617 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::SetInterface()"))); |
|
618 for (TInt i = 0; i < aTotalEndpointsUsed; ++i) |
|
619 { |
|
620 if (aEndpointData[i].iType == KUsbEpTypeControl) |
|
621 { |
|
622 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" control endpoints not supported"))); |
|
623 return KErrNotSupported; |
|
624 } |
|
625 } |
|
626 // create & setup new interface |
|
627 TUsbcInterface* ifc = CreateInterface(aInterfaceNumber); |
|
628 if (ifc == NULL) |
|
629 { |
|
630 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error (ifc == NULL)"))); |
|
631 return KErrGeneral; |
|
632 } |
|
633 // Create logical endpoints |
|
634 if (CreateEndpoints(ifc, aTotalEndpointsUsed, aEndpointData) != KErrNone) |
|
635 { |
|
636 DeleteInterface(aInterfaceNumber); |
|
637 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error (CreateEndpoints() != KErrNone)"))); |
|
638 return KErrGeneral; |
|
639 } |
|
640 // create & setup interface, string, and endpoint descriptors |
|
641 const TInt r = SetupIfcDescriptor(ifc, aClass, aString, aEndpointData); |
|
642 if (r != KErrNone) |
|
643 { |
|
644 return r; |
|
645 } |
|
646 return KErrNone; |
|
647 } |
|
648 |
|
649 TUsbcInterface* DLddTestUsbcChannel::CreateInterface(TInt aIfc) |
|
650 { |
|
651 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::CreateInterface(x, aIfc=%d)"), aIfc)); |
|
652 if (aIfc != iIfcSet.iInterfaces.Count()) |
|
653 { |
|
654 // 9.2.3: "Alternate settings range from zero to one less than the number of alternate |
|
655 // settings for a specific interface." (Thus we can here only append a setting.) |
|
656 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" invalid interface setting number (2): %d"), aIfc)); |
|
657 return NULL; |
|
658 } |
|
659 TUsbcInterface* const ifc_ptr = new TUsbcInterface(&iIfcSet, (TUint8)aIfc); |
|
660 if (!ifc_ptr) |
|
661 { |
|
662 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: new TUsbcInterface(ifcset, aIfc) failed"))); |
|
663 return NULL; |
|
664 } |
|
665 iIfcSet.iInterfaces.Append(ifc_ptr); |
|
666 return ifc_ptr; |
|
667 } |
|
668 |
|
669 void DLddTestUsbcChannel::DeleteInterface(TInt aIfc) |
|
670 { |
|
671 if (iIfcSet.iInterfaces.Count() <= aIfc) |
|
672 { |
|
673 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: invalid interface setting: %d"), aIfc)); |
|
674 return; |
|
675 } |
|
676 TUsbcInterface* const ifc_ptr = iIfcSet.iInterfaces[aIfc]; |
|
677 iIfcSet.iInterfaces.Remove(aIfc); |
|
678 delete ifc_ptr; |
|
679 if (aIfc == iIfcSet.iCurrentInterface) |
|
680 { |
|
681 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" > Warning: deleting current interface setting"))); |
|
682 iIfcSet.iCurrentInterface = 0; |
|
683 } |
|
684 } |
|
685 |
|
686 TInt DLddTestUsbcChannel::CreateEndpoints(TUsbcInterface* aIfc, TInt aEndpointsUsed, |
|
687 const TUsbcEndpointInfo aEndpointData[]) |
|
688 { |
|
689 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::CreateEndpoints()"))); |
|
690 |
|
691 for (TInt i = 0; i < aEndpointsUsed; ++i) |
|
692 { |
|
693 for (TInt j = 1; j <= KMaxEndpointsPerClient; ++j) |
|
694 { |
|
695 if (iEndpoints[j]->EndpointSuitable(aEndpointData[i])) |
|
696 { |
|
697 TUsbcLogicalEndpoint* const ep = new TUsbcLogicalEndpoint(j, aEndpointData[i], aIfc); |
|
698 if (!ep) |
|
699 { |
|
700 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: new TUsbcLogicalEndpoint() failed"))); |
|
701 aIfc->iEndpoints.ResetAndDestroy(); |
|
702 for (TInt k = 1; k <= KMaxEndpointsPerClient; ++k) |
|
703 { |
|
704 iEndpoints[k]->iReserve = EFalse; |
|
705 } |
|
706 return KErrNoMemory; |
|
707 } |
|
708 iEndpoints[j]->iReserve = ETrue; |
|
709 iEndpoints[j]->SetClearCallback(this); |
|
710 aIfc->iEndpoints.Append(ep); |
|
711 break; |
|
712 } |
|
713 } |
|
714 } |
|
715 return KErrNone; |
|
716 } |
|
717 |
|
718 TBool DLddTestUsbcChannel::ValidateEndpoint(TUsbcEndpointInfo* aEndpointInfo) |
|
719 { // Quick sanity check on endpoint properties |
|
720 TUint dir=aEndpointInfo->iDir; |
|
721 TInt size=aEndpointInfo->iSize; |
|
722 if(size <=0) |
|
723 return EFalse; |
|
724 switch (aEndpointInfo->iType) |
|
725 { |
|
726 case KUsbEpTypeControl: |
|
727 if(dir != KUsbEpDirBidirect || size > 64) |
|
728 return EFalse; |
|
729 break; |
|
730 case KUsbEpTypeIsochronous: |
|
731 if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1023) |
|
732 return EFalse; |
|
733 break; |
|
734 case KUsbEpTypeBulk: |
|
735 if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 64) |
|
736 return EFalse; |
|
737 break; |
|
738 case KUsbEpTypeInterrupt: |
|
739 if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 64) |
|
740 return EFalse; |
|
741 break; |
|
742 default: |
|
743 return EFalse; |
|
744 } |
|
745 return ETrue; |
|
746 } |
|
747 |
|
748 TInt DLddTestUsbcChannel::SetupIfcDescriptor(TUsbcInterface* aIfc, TUsbcClassInfo& aClass, |
|
749 TDesC8* aString, const TUsbcEndpointInfo aEndpointData[]) |
|
750 { |
|
751 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::SetupIfcDescriptor()"))); |
|
752 |
|
753 // interface descriptor |
|
754 TUsbcDescriptorBase* d = TUsbcInterfaceDescriptor::New(aIfc->iInterfaceSet->iInterfaceNumber, |
|
755 aIfc->iSettingCode, |
|
756 aIfc->iEndpoints.Count(), |
|
757 aClass); |
|
758 if (!d) |
|
759 { |
|
760 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc desc failed."))); |
|
761 return KErrNoMemory; |
|
762 } |
|
763 iDescriptors.InsertDescriptor(d); |
|
764 |
|
765 // interface string descriptor |
|
766 if (aString) |
|
767 { |
|
768 // we don't know the length of the string, so we have to allocate memory dynamically |
|
769 TUint strlen = __THREADDESLEN(iClient, aString); |
|
770 if (strlen > KUsbStringDescStringMaxSize) |
|
771 { |
|
772 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: $ descriptor too long - string will be truncated"))); |
|
773 strlen = KUsbStringDescStringMaxSize; |
|
774 } |
|
775 |
|
776 HBuf8Plat* stringbuf = NULL; |
|
777 __NEWPLATBUF(stringbuf, strlen); |
|
778 if (!stringbuf) |
|
779 { |
|
780 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc $ desc string failed."))); |
|
781 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode); |
|
782 return KErrNoMemory; |
|
783 } |
|
784 |
|
785 TInt r; |
|
786 __THREADREADPLATBUF(iClient, aString, stringbuf, r); |
|
787 if (r != KErrNone) |
|
788 { |
|
789 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Thread read error!"))); |
|
790 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, |
|
791 aIfc->iSettingCode); |
|
792 delete stringbuf; |
|
793 return r; |
|
794 } |
|
795 TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*stringbuf); |
|
796 if (!sd) |
|
797 { |
|
798 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc $ desc failed."))); |
|
799 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode); |
|
800 delete stringbuf; |
|
801 return KErrNoMemory; |
|
802 } |
|
803 iDescriptors.SetIfcStringDescriptor(sd, aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode); |
|
804 delete stringbuf; // the (EPOC) descriptor was copied by New() |
|
805 } |
|
806 |
|
807 // endpoint descriptors |
|
808 for (TInt i = 0; i < aIfc->iEndpoints.Count(); ++i) |
|
809 { |
|
810 // The reason for using another function argument for Endpoint Info - and not possibly (similar to the |
|
811 // Endpoint Address) "aIfc->iEndpoints[i]->iPEndpoint->iLEndpoint->iInfo" - is that at this time |
|
812 // there are no logical endpoints associated with our real endpoints, i.e. iLEndpoint is NULL! |
|
813 if (aEndpointData[i].iExtra) |
|
814 { |
|
815 // if non-standard endpoint descriptor requested... |
|
816 if (aEndpointData[i].iExtra != 2) |
|
817 { |
|
818 // ...then it must be a Audio Class endpoint descriptor. Else... |
|
819 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > We only support EP desc extension of 2 bytes (not %d)"), aEndpointData[i].iExtra)); |
|
820 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, |
|
821 aIfc->iSettingCode); |
|
822 return KErrArgument; |
|
823 } |
|
824 d = TUsbcAudioEndpointDescriptor::New((TUint8)i, aEndpointData[i]); |
|
825 } |
|
826 else |
|
827 { |
|
828 d = TUsbcEndpointDescriptor::New((TUint8)i, aEndpointData[i]); |
|
829 } |
|
830 if (!d) |
|
831 { |
|
832 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Memory allocation for ep desc #%d failed."), i)); |
|
833 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, |
|
834 aIfc->iSettingCode); |
|
835 return KErrNoMemory; |
|
836 } |
|
837 iDescriptors.InsertDescriptor(d); |
|
838 } |
|
839 |
|
840 return KErrNone; |
|
841 } |
|
842 |
|
843 /** |
|
844 @internalTechnology |
|
845 |
|
846 Releases an existing USB interface (one setting), complete with endpoints, descriptors, etc., |
|
847 and removes it from the internal device configuration tree. |
|
848 |
|
849 @param aClientId A pointer to the LDD owning the interface. |
|
850 @param aInterfaceNumber The setting number of the interface setting to be deleted. This must be |
|
851 the highest numbered (or 'last') setting for this interface. |
|
852 |
|
853 @return KErrNotFound if interface (not setting) for some reason cannot be found, KErrArgument if an |
|
854 invalid interface setting number is specified (not existing or existing but too small), KErrNone if |
|
855 interface successfully released or if this client doesn't own any interface. |
|
856 */ |
|
857 TInt DLddTestUsbcChannel::ReleaseInterface(TInt aInterfaceNumber) |
|
858 { |
|
859 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::ReleaseInterface(..., %d)"), aInterfaceNumber)); |
|
860 const TInt setting_count = iIfcSet.iInterfaces.Count(); |
|
861 if ((aInterfaceNumber != 0) && ((setting_count - 1) != aInterfaceNumber)) |
|
862 { |
|
863 __KTRACE_OPT(KUSB, |
|
864 Kern::Printf(__KSTRING(" > Error: interface settings must be released in descending order:\n\r%d settings exist, #%d was requested to be released: release %d first)"), |
|
865 setting_count, aInterfaceNumber, setting_count - 1)); |
|
866 return KErrArgument; |
|
867 } |
|
868 // Reset reserved status of the endpoints |
|
869 for (TInt i = 0; i < KMaxEndpointsPerClient+1; i++) |
|
870 { |
|
871 iEndpoints[i]->iReserve = EFalse; |
|
872 } |
|
873 if (aInterfaceNumber == 0) |
|
874 { |
|
875 TInt m = iIfcSet.iInterfaces.Count(); |
|
876 while (m > 0) |
|
877 { |
|
878 m--; |
|
879 // Delete the setting itself + its ifc & ep descriptors |
|
880 DeleteInterface(m); |
|
881 iDescriptors.DeleteIfcDescriptor(0, m); |
|
882 } |
|
883 } |
|
884 else |
|
885 { |
|
886 // Delete the setting itself + its ifc & ep descriptors |
|
887 DeleteInterface(aInterfaceNumber); |
|
888 iDescriptors.DeleteIfcDescriptor(0, aInterfaceNumber); |
|
889 } |
|
890 // Delete the whole interface if all settings are gone |
|
891 if (iIfcSet.iInterfaces.Count() == 0) |
|
892 { |
|
893 DeleteInterfaceSet(); |
|
894 } |
|
895 return KErrNone; |
|
896 } |
|
897 |
|
898 void DLddTestUsbcChannel::DeleteInterfaceSet() |
|
899 { |
|
900 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::DeleteInterfaceSet"))); |
|
901 iIfcSet.iInterfaceNumber = 0; |
|
902 iIfcSet.iCurrentInterface = 0; |
|
903 iIfcSet.iInterfaces.ResetAndDestroy(); |
|
904 } |
|
905 |
|
906 TInt DLddTestUsbcChannel::DoTransferAsyncReq(TInt aEndpointNumber, TAny* a1, TAny* a2, TRequestStatus& aStatus) |
|
907 { |
|
908 TInt r = KErrNone; |
|
909 DTestUsbcEndpoint* pEndpoint = NULL; |
|
910 TEndpointTransferInfo *pTfr = NULL; |
|
911 |
|
912 |
|
913 if(!ValidEndpoint(aEndpointNumber)) |
|
914 { |
|
915 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete"))); |
|
916 return KErrUsbEpNotInInterface; |
|
917 } |
|
918 |
|
919 if(a1 == NULL) |
|
920 { |
|
921 return KErrArgument; |
|
922 } |
|
923 |
|
924 TBool hostTransfer = EFalse; |
|
925 if(a2 != NULL) |
|
926 { |
|
927 hostTransfer = ETrue; |
|
928 } |
|
929 |
|
930 TEndpointTransferInfo transferInfo; |
|
931 pTfr = (TEndpointTransferInfo*)&transferInfo; |
|
932 r = __THREADRAWREAD(iClient, a1, (TUint8*)&transferInfo, sizeof(TEndpointTransferInfo)); |
|
933 if(r != KErrNone) |
|
934 { |
|
935 __THREADPANIC(iClient, r); |
|
936 } |
|
937 if (aEndpointNumber != 0) |
|
938 { |
|
939 if (hostTransfer) |
|
940 { |
|
941 pEndpoint = iEndpoints[aEndpointNumber]; |
|
942 } |
|
943 else |
|
944 { |
|
945 pEndpoint = iEndpoints[FindRealEndpoint(aEndpointNumber)]; |
|
946 } |
|
947 } |
|
948 else |
|
949 { |
|
950 pEndpoint = iEndpoints[0]; |
|
951 } |
|
952 if(!pEndpoint) |
|
953 { |
|
954 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete"))); |
|
955 return KErrUsbEpNotInInterface; |
|
956 } |
|
957 |
|
958 switch(pTfr->iTransferType) |
|
959 { |
|
960 case ETransferTypeReadUntilShort: |
|
961 case ETransferTypeReadData: |
|
962 { |
|
963 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest Read"))); |
|
964 |
|
965 if(!hostTransfer && !pEndpoint->SupportsDir(KUsbEpDirOut) && !pEndpoint->SupportsDir(KUsbEpDirBidirect)) |
|
966 { // Trying to make the wrong thing |
|
967 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete"))); |
|
968 r = KErrUsbEpBadDirection; |
|
969 break; |
|
970 } |
|
971 |
|
972 // Set the length of data to zero now to catch all cases |
|
973 TPtrC8 pZeroDesc(NULL, 0); |
|
974 r = __THREADWRITE(iClient, pTfr->iDes, pZeroDesc); // set client descriptor length to zero |
|
975 if(r != KErrNone) |
|
976 __THREADPANIC(iClient, r); |
|
977 if (hostTransfer) |
|
978 r = pEndpoint->NewHostRequest(iClient, &aStatus, *pTfr, pTfr->iTransferType); |
|
979 else |
|
980 r = pEndpoint->NewRequest(iClient, &aStatus, *pTfr, pTfr->iTransferType); |
|
981 break; |
|
982 } |
|
983 |
|
984 case ETransferTypeWrite: |
|
985 { |
|
986 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest Write 1"))); |
|
987 if(!hostTransfer && !pEndpoint->SupportsDir(KUsbEpDirIn) && !pEndpoint->SupportsDir(KUsbEpDirBidirect)) |
|
988 { |
|
989 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Write: wrong direction complete"))); |
|
990 r = KErrUsbEpBadDirection; |
|
991 break; |
|
992 } |
|
993 if (hostTransfer) |
|
994 r = pEndpoint->NewHostRequest(iClient, &aStatus, *pTfr, ETransferTypeWrite); |
|
995 else |
|
996 r = pEndpoint->NewRequest(iClient, &aStatus, *pTfr, ETransferTypeWrite); |
|
997 break; |
|
998 } |
|
999 default: |
|
1000 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Not supported complete"))); |
|
1001 r = KErrNotSupported; |
|
1002 break; |
|
1003 } |
|
1004 return r; |
|
1005 } |
|
1006 |
|
1007 TInt DLddTestUsbcChannel::HaltClearEndpoint(TBool aHalt, TInt aEndpointNumber) |
|
1008 { |
|
1009 DTestUsbcEndpoint* pEndpoint = NULL; |
|
1010 if (aEndpointNumber != 0) |
|
1011 { |
|
1012 pEndpoint = iEndpoints[FindRealEndpoint(aEndpointNumber)]; |
|
1013 } |
|
1014 else |
|
1015 { |
|
1016 pEndpoint = iEndpoints[0]; |
|
1017 } |
|
1018 TInt err; |
|
1019 if (aHalt) |
|
1020 { |
|
1021 err = pEndpoint->Halt(); |
|
1022 } |
|
1023 else |
|
1024 { |
|
1025 err = pEndpoint->Clear(); |
|
1026 } |
|
1027 return err; |
|
1028 } |
|
1029 |
|
1030 TInt DLddTestUsbcChannel::HostEndpointStatusNotify(TInt aEndpointNumber, TRequestStatus* aStatus) |
|
1031 { |
|
1032 DTestUsbcEndpoint* pEndpoint = iEndpoints[aEndpointNumber]; |
|
1033 return pEndpoint->HostStatusNotify(iClient, aStatus); |
|
1034 } |
|
1035 |
|
1036 TInt DLddTestUsbcChannel::ClearEndpoint(TInt aEndpointNumber) |
|
1037 { |
|
1038 DTestUsbcEndpoint* pEndpoint = iEndpoints[aEndpointNumber]; |
|
1039 return pEndpoint->Clear(); |
|
1040 } |
|
1041 |
|
1042 TInt DLddTestUsbcChannel::EndpointStatusNotify(TUint* aEndpointMask, TRequestStatus* aStatus) |
|
1043 { |
|
1044 iEndpointStatusMask = aEndpointMask; |
|
1045 iEndpointStatusNotifyRequest = aStatus; |
|
1046 return KErrNone; |
|
1047 } |
|
1048 |
|
1049 void DLddTestUsbcChannel::EndpointStatusNotifyCallback() |
|
1050 { |
|
1051 if (iEndpointStatusNotifyRequest == NULL || iEndpointStatusMask == NULL) |
|
1052 { |
|
1053 return; |
|
1054 } |
|
1055 |
|
1056 //Get status for interface's endpoints. |
|
1057 //NOTE: currently we only support one interface. |
|
1058 TUsbcInterface* interface = iIfcSet.iInterfaces[0]; |
|
1059 TUint bitmask = 0; |
|
1060 for (TInt i = interface->iEndpoints.Count() - 1; i >= 0; i--) |
|
1061 { |
|
1062 TUsbcLogicalEndpoint* logep = interface->iEndpoints[i]; |
|
1063 DTestUsbcEndpoint* pEndpoint = iEndpoints[FindRealEndpoint(logep->iLEndpointNum)]; |
|
1064 if (pEndpoint->IsHalted()) |
|
1065 { |
|
1066 bitmask |= 1; |
|
1067 bitmask = bitmask << 1; |
|
1068 } |
|
1069 } |
|
1070 |
|
1071 //Write bitmask back to client space. |
|
1072 TInt r = __THREADRAWWRITE(iClient, (void*)iEndpointStatusMask, (TUint8*)&bitmask, (TInt)sizeof(bitmask)); |
|
1073 |
|
1074 //Complete client request. |
|
1075 Kern::RequestComplete(iClient, iEndpointStatusNotifyRequest, r); |
|
1076 |
|
1077 iEndpointStatusMask = NULL; |
|
1078 iEndpointStatusNotifyRequest = NULL; |
|
1079 } |
|
1080 |
|
1081 TBool DLddTestUsbcChannel::ValidEndpoint(TInt aEndpointNumber) |
|
1082 { |
|
1083 return (aEndpointNumber <= 5 && aEndpointNumber >= 0); |
|
1084 } |
|
1085 |
|
1086 TInt DLddTestUsbcChannel::FindRealEndpoint(TInt aEndpointNumber) |
|
1087 { |
|
1088 TUsbcInterface* pIfc = iIfcSet.CurrentInterface(); |
|
1089 return pIfc->iEndpoints[aEndpointNumber - 1]->iLEndpointNum; |
|
1090 } |
|
1091 |
|
1092 void DLddTestUsbcChannel::AlternateDeviceStatusNotify() |
|
1093 { |
|
1094 if (iAlternateDeviceStatusNotifyRequest != NULL) |
|
1095 { |
|
1096 TInt r = __THREADRAWWRITE(iClient, (void*)iAlternateDeviceStatusNotifyValue, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState)); |
|
1097 Kern::RequestComplete(iClient, iAlternateDeviceStatusNotifyRequest, r); |
|
1098 iAlternateDeviceStatusNotifyRequest = NULL; |
|
1099 } |
|
1100 } |
|
1101 |
|
1102 TInt DLddTestUsbcChannel::SetAlternateDeviceStatusNotify(TRequestStatus* aStatus, TUint* aValue) |
|
1103 { |
|
1104 if (iAlternateDeviceStatusNotifyRequest != NULL) |
|
1105 { |
|
1106 return KErrInUse; |
|
1107 } |
|
1108 |
|
1109 TRequestStatus s; |
|
1110 s = KRequestPending; |
|
1111 |
|
1112 __THREADRAWWRITE(iClient, (void*)aStatus, (TUint8*)&s, (TInt)sizeof(s)); |
|
1113 iAlternateDeviceStatusNotifyRequest = aStatus; |
|
1114 iAlternateDeviceStatusNotifyValue = aValue; |
|
1115 return KErrNone; |
|
1116 } |
|
1117 |
|
1118 void DLddTestUsbcChannel::CancelAlternateDeviceStatusNotify() |
|
1119 { |
|
1120 if (iAlternateDeviceStatusNotifyRequest != NULL) |
|
1121 { |
|
1122 __THREADRAWWRITE(iClient, (void*)iAlternateDeviceStatusNotifyValue, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState)); |
|
1123 Kern::RequestComplete(iClient, iAlternateDeviceStatusNotifyRequest, KErrCancel); |
|
1124 iAlternateDeviceStatusNotifyRequest = NULL; |
|
1125 } |
|
1126 } |
|
1127 |
|
1128 TInt DLddTestUsbcChannel::ReEnumerate(TRequestStatus* aStatus) |
|
1129 { |
|
1130 SetDeviceState(EUsbcDeviceStateConfigured); |
|
1131 Kern::RequestComplete(iClient, aStatus, KErrNone); |
|
1132 return KErrNone; |
|
1133 } |
|
1134 |
|
1135 void DLddTestUsbcChannel::SetDeviceState(TUsbcDeviceState aState) |
|
1136 { |
|
1137 iDeviceState = aState; |
|
1138 AlternateDeviceStatusNotify(); |
|
1139 } |
|
1140 |