First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\testusbcldd\src\dlddtestusbcchannel.cpp
19 #include "dtestusblogdev.h"
22 extern TDynamicDfcQue* gDfcQ;
24 const TUsbcEndpointData DLddTestUsbcChannel::iEndpointData[] =
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}
34 // The EKA1 base class needs a DLogicalDevice* for its constructor
35 DLddTestUsbcChannel::DLddTestUsbcChannel(RPointerArray<DTestUsbcEndpoint>& aEndpoints) :
38 iEndpoints(aEndpoints),
39 iDeviceState(EUsbcDeviceStateConfigured)
41 iClient = &Kern::CurrentThread();
45 DLddTestUsbcChannel::~DLddTestUsbcChannel()
49 TInt DLddTestUsbcChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
52 // Setup LDD for receiving client messages
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)
70 void DLddTestUsbcChannel::HandleMsg(TMessageBase* aMsg)
72 TThreadMessage& m = *(TThreadMessage*)aMsg;
74 if (id == (TInt)ECloseMsg)
76 m.Complete(KErrNone, EFalse);
79 else if (id == KMaxTInt)
83 DTestUsbcEndpoint* pEndpoint = NULL;
86 case RDevUsbcClient::ERequestEp0Cancel:
87 pEndpoint = iEndpoints[0];
88 pEndpoint->DoCancel();
90 case RDevUsbcClient::ERequestEp1Cancel:
91 pEndpoint = iEndpoints[FindRealEndpoint(1)];
92 pEndpoint->DoCancel();
94 case RDevUsbcClient::ERequestEp2Cancel:
95 pEndpoint = iEndpoints[FindRealEndpoint(2)];
96 pEndpoint->DoCancel();
98 case RDevUsbcClient::ERequestEp3Cancel:
99 pEndpoint = iEndpoints[FindRealEndpoint(3)];
100 pEndpoint->DoCancel();
102 case RDevUsbcClient::ERequestEp4Cancel:
103 pEndpoint = iEndpoints[FindRealEndpoint(4)];
104 pEndpoint->DoCancel();
106 case RDevUsbcClient::ERequestEp5Cancel:
107 pEndpoint = iEndpoints[FindRealEndpoint(5)];
108 pEndpoint->DoCancel();
110 case RDevUsbcClient::ERequestAlternateDeviceStatusNotifyCancel:
111 CancelAlternateDeviceStatusNotify();
114 m.Complete(KErrNotSupported, ETrue);
117 m.Complete(KErrNone, ETrue);
124 TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
125 DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
126 m.Complete(KErrNone, ETrue);
131 TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
132 m.Complete(r, ETrue);
136 TInt DLddTestUsbcChannel::DoCancel(TInt /*aReqNo*/)
141 void DLddTestUsbcChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
143 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest 0x%08x"),aReqNo));
145 //If request is ep number then do a transfer request.
146 if(aReqNo > KUsbcMaxEpNumber)
148 if (aReqNo == RDevTestUsbcClient::ETestRequestNotifyEndpointStatus)
150 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestRequestNotifyEndpointStatus")));
151 r = HostEndpointStatusNotify((TInt)a1, aStatus);
153 else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
155 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ERequestAlternateDeviceStatusNotify")));
156 r = SetAlternateDeviceStatusNotify(aStatus, (TUint*)a1);
158 else if (aReqNo == RDevUsbcClient::ERequestReEnumerate)
160 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ERequestReEnumerate")));
161 r = ReEnumerate((TRequestStatus*)a1);
165 Kern::RequestComplete(iClient, aStatus, KErrNotSupported);
170 r = DoTransferAsyncReq(aReqNo, a1, a2, *aStatus);
175 Kern::RequestComplete(iClient, aStatus, r);
179 TInt DLddTestUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
182 TDes8& a1Buf = *((TDes8*)a1);
183 TDes8& a2Buf = *((TDes8*)a2);
184 TPtrC8 pZeroDesc(NULL,0);
189 case RDevUsbcClient::EControlEndpointZeroRequestError:
191 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlEndpointZeroRequestError")));
196 case RDevUsbcClient::EControlEndpointCaps:
198 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlEndpointCaps")));
199 r = __THREADWRITE(iClient, a1, pZeroDesc);
202 TBuf8<KMaxTUint8> aBuf;
203 memclr(&aBuf, sizeof(aBuf));
204 TPtr8 endpointCfg((TUint8*)&aBuf,0,sizeof(aBuf));
206 r = Kern::ThreadDesRead(iClient,a1,endpointCfg,0,0);
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);
218 __THREADPANIC(iClient, r);
224 case RDevUsbcClient::EControlDeviceCaps:
226 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlDeviceCaps")));
227 r = __THREADWRITE(iClient, a1, pZeroDesc);
230 __THREADPANIC(iClient, r);
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);
246 case RDevUsbcClient::EControlDeviceStatus:
248 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlDeviceStatus")));
249 r = __THREADRAWWRITE(iClient, a1, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState));
252 __THREADPANIC(iClient, r);
257 case RDevUsbcClient::EControlHaltEndpoint:
259 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlHaltEndpoint")));
260 r = HaltClearEndpoint(ETrue, (TInt)a1);
264 case RDevUsbcClient::EControlGetDeviceDescriptor:
266 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetDeviceDescriptor")));
267 r = __THREADWRITE(iClient, a1, pZeroDesc);
270 __THREADPANIC(iClient, r);
272 r = iDescriptors.GetDeviceDescriptorTC(iClient, a1Buf);
276 case RDevUsbcClient::EControlSetDeviceDescriptor:
278 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetDeviceDescriptor")));
279 r = iDescriptors.SetDeviceDescriptorTC(iClient, a1Buf);
283 case RDevUsbcClient::EControlGetDeviceDescriptorSize:
285 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetDeviceDescriptorSize")));
288 const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Device), sizeof(KUsbDescSize_Device));
289 r = __THREADWRITE(iClient, a1, size);
298 case RDevUsbcClient::EControlGetConfigurationDescriptor:
300 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetConfigurationDescriptor")));
301 r = __THREADWRITE(iClient, a1, pZeroDesc); // set client descriptor length to zero
304 __THREADPANIC(iClient, r);
306 r = iDescriptors.GetConfigurationDescriptorTC(iClient, a1Buf);
310 case RDevUsbcClient::EControlSetConfigurationDescriptor:
312 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetConfigurationDescriptor")));
313 r = iDescriptors.SetConfigurationDescriptorTC(iClient, a1Buf);
317 case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
319 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetConfigurationDescriptorSize")));
322 const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Config), sizeof(KUsbDescSize_Config));
323 r = __THREADWRITE(iClient, a1, size);
332 case RDevUsbcClient::EControlGetInterfaceDescriptor:
334 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetInterfaceDescriptor")));
335 r = iDescriptors.GetInterfaceDescriptorTC(iClient, a2Buf, 0, (TInt)a1);
339 case RDevUsbcClient::EControlSetInterfaceDescriptor:
341 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetInterfaceDescriptor")));
342 TBuf8<KUsbDescSize_Interface> new_ifc;
343 r = __THREADWRITE(iClient, a2, new_ifc);
348 r = iDescriptors.SetInterfaceDescriptor(new_ifc, 0, (TInt)a1);
352 case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
354 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetInterfaceDescriptorSize")));
357 const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Interface), sizeof(KUsbDescSize_Interface));
358 r = __THREADWRITE(iClient, a2, size);
367 case RDevUsbcClient::EControlGetEndpointDescriptor:
369 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetEndpointDescriptor")));
370 TEndpointDescriptorInfo info;
371 r = __THREADRAWREAD(iClient, a1,(TUint8*)&info, (TInt)sizeof(info));
374 __THREADPANIC(iClient, r);
376 r = iDescriptors.GetEndpointDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, (TUint8)info.iEndpoint);
379 case RDevUsbcClient::EControlSetEndpointDescriptor:
381 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetEndpointDescriptor")));
382 TEndpointDescriptorInfo info;
383 r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TEndpointDescriptorInfo));
385 __THREADPANIC(iClient, r);
386 r = iDescriptors.SetEndpointDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, (TUint8)info.iEndpoint);
390 case RDevUsbcClient::EControlGetEndpointDescriptorSize:
392 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetEndpointDescriptorSize")));
393 TEndpointDescriptorInfo info;
394 r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TEndpointDescriptorInfo));
396 __THREADPANIC(iClient, r);
398 TInt r = iDescriptors.GetEndpointDescriptorSize(0, info.iSetting, (TUint8)info.iEndpoint, s);
401 TPtrC8 size(reinterpret_cast<const TUint8*>(&s), sizeof(s));
402 r = __THREADWRITE(iClient, &(info.iArg), size);
407 case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
409 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetCSInterfaceDescriptor")));
410 TCSDescriptorInfo info;
411 r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TCSDescriptorInfo));
413 __THREADPANIC(iClient, r);
414 r = iDescriptors.SetCSInterfaceDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, info.iSize);
418 case RDevUsbcClient::EControlDeviceDisconnectFromHost:
424 case RDevUsbcClient::EControlDeviceConnectToHost:
430 case RDevUsbcClient::EControlDevicePowerUpUdc:
436 case RDevUsbcClient::EControlSetInterface:
438 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetInterface")));
440 r = __THREADRAWREAD(iClient, a2, (TUint8*)&info, (TInt)sizeof(TUsbcIfcInfo));
442 __THREADPANIC(iClient, r);
444 TUsbcInterfaceInfoBuf* interfaceData = info.iInterfaceData;
445 TPtr8* ifcString = info.iString;
446 r = SetInterface((TInt)a1, interfaceData, ifcString);
450 case RDevUsbcClient::EControlReleaseInterface:
452 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlReleaseInterface")));
453 r = ReleaseInterface((TInt)a1);
457 case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
459 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
460 r = iDescriptors.GetManufacturerStringDescriptorTC(iClient, a1Buf);
464 case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
466 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetManufacturerStringDescriptor")));
467 r = iDescriptors.SetManufacturerStringDescriptorTC(iClient, a1Buf);
471 case RDevUsbcClient::EControlGetProductStringDescriptor:
473 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
474 r = iDescriptors.GetProductStringDescriptorTC(iClient, a1Buf);
478 case RDevUsbcClient::EControlSetProductStringDescriptor:
480 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetProductStringDescriptor")));
481 r = iDescriptors.SetProductStringDescriptorTC(iClient, a1Buf);
485 case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
487 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
488 r = iDescriptors.GetSerialNumberStringDescriptorTC(iClient, a1Buf);
492 case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
494 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetSerialNumberStringDescriptor")));
495 r = iDescriptors.SetSerialNumberStringDescriptorTC(iClient, a1Buf);
499 case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
501 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
502 r = iDescriptors.GetConfigurationStringDescriptorTC(iClient, a1Buf);
506 case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
508 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetConfigurationStringDescriptor")));
509 r = iDescriptors.SetConfigurationStringDescriptorTC(iClient, a1Buf);
512 case RDevUsbcClient::EControlEndpointStatus:
515 DTestUsbcEndpoint* pEndpoint = iEndpoints[FindRealEndpoint(ep)];
516 TEndpointState state = EEndpointStateUnknown;
517 if (pEndpoint->IsHalted())
519 state = EEndpointStateStalled;
523 state = EEndpointStateNotStalled;
525 __THREADRAWWRITE(iClient, a2, (TUint8*)&state, (TInt)sizeof(state));
529 case RDevTestUsbcClient::ETestControlReqEndpointStatusNotify:
531 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestControlReqEndpointStatusNotify")));
532 r = HostEndpointStatusNotify((TInt)a2, (TRequestStatus*)a1);
536 case RDevTestUsbcClient::ETestControlClearEndpoint:
538 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestControlClearEndpoint")));
539 r = ClearEndpoint((TInt)a1);
544 r = KErrNotSupported;
550 TInt DLddTestUsbcChannel::SetInterface(TInt aInterfaceNumber,
551 TUsbcInterfaceInfoBuf *aUserInterfaceInfoBuf,
552 TPtr8* aInterfaceString)
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));
558 TUsbcEndpointInfo* pEndpointData=NULL;
559 TInt numberOfEndpoints=0;
560 TUsbcInterfaceInfoBuf interfaceBuff;
561 TInt bufLen=interfaceBuff.Length();
562 TInt srcLen=__THREADDESLEN(iClient,aUserInterfaceInfoBuf);
565 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface can't copy")));
566 __THREADPANIC(iClient,EDesOverflow);
568 r = __THREADREAD(iClient, aUserInterfaceInfoBuf, interfaceBuff);
571 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Copy failed reason=%d"),r));
572 __THREADPANIC(iClient,r);
574 pEndpointData=interfaceBuff().iEndpointData;
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));
582 for(TInt i=1;i<=numberOfEndpoints;i++,pEndpointData++)
584 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface for ep=%d"),i));
585 if(!ValidateEndpoint(pEndpointData))
587 r=KErrUsbBadEndpoint;
592 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Calling controller")));
593 r=SetInterface(aInterfaceNumber,
594 interfaceBuff().iClass,
596 interfaceBuff().iTotalEndpointsUsed,
597 interfaceBuff().iEndpointData);
599 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface controller returned %d"),r));
602 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface failed reason=%d"),r));
605 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface ready to exit")));
613 TInt DLddTestUsbcChannel::SetInterface(TInt aInterfaceNumber, TUsbcClassInfo& aClass,
614 TDesC8* aString, TInt aTotalEndpointsUsed,
615 const TUsbcEndpointInfo aEndpointData[])
617 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::SetInterface()")));
618 for (TInt i = 0; i < aTotalEndpointsUsed; ++i)
620 if (aEndpointData[i].iType == KUsbEpTypeControl)
622 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" control endpoints not supported")));
623 return KErrNotSupported;
626 // create & setup new interface
627 TUsbcInterface* ifc = CreateInterface(aInterfaceNumber);
630 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error (ifc == NULL)")));
633 // Create logical endpoints
634 if (CreateEndpoints(ifc, aTotalEndpointsUsed, aEndpointData) != KErrNone)
636 DeleteInterface(aInterfaceNumber);
637 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error (CreateEndpoints() != KErrNone)")));
640 // create & setup interface, string, and endpoint descriptors
641 const TInt r = SetupIfcDescriptor(ifc, aClass, aString, aEndpointData);
649 TUsbcInterface* DLddTestUsbcChannel::CreateInterface(TInt aIfc)
651 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::CreateInterface(x, aIfc=%d)"), aIfc));
652 if (aIfc != iIfcSet.iInterfaces.Count())
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));
659 TUsbcInterface* const ifc_ptr = new TUsbcInterface(&iIfcSet, (TUint8)aIfc);
662 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: new TUsbcInterface(ifcset, aIfc) failed")));
665 iIfcSet.iInterfaces.Append(ifc_ptr);
669 void DLddTestUsbcChannel::DeleteInterface(TInt aIfc)
671 if (iIfcSet.iInterfaces.Count() <= aIfc)
673 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: invalid interface setting: %d"), aIfc));
676 TUsbcInterface* const ifc_ptr = iIfcSet.iInterfaces[aIfc];
677 iIfcSet.iInterfaces.Remove(aIfc);
679 if (aIfc == iIfcSet.iCurrentInterface)
681 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" > Warning: deleting current interface setting")));
682 iIfcSet.iCurrentInterface = 0;
686 TInt DLddTestUsbcChannel::CreateEndpoints(TUsbcInterface* aIfc, TInt aEndpointsUsed,
687 const TUsbcEndpointInfo aEndpointData[])
689 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::CreateEndpoints()")));
691 for (TInt i = 0; i < aEndpointsUsed; ++i)
693 for (TInt j = 1; j <= KMaxEndpointsPerClient; ++j)
695 if (iEndpoints[j]->EndpointSuitable(aEndpointData[i]))
697 TUsbcLogicalEndpoint* const ep = new TUsbcLogicalEndpoint(j, aEndpointData[i], aIfc);
700 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: new TUsbcLogicalEndpoint() failed")));
701 aIfc->iEndpoints.ResetAndDestroy();
702 for (TInt k = 1; k <= KMaxEndpointsPerClient; ++k)
704 iEndpoints[k]->iReserve = EFalse;
708 iEndpoints[j]->iReserve = ETrue;
709 iEndpoints[j]->SetClearCallback(this);
710 aIfc->iEndpoints.Append(ep);
718 TBool DLddTestUsbcChannel::ValidateEndpoint(TUsbcEndpointInfo* aEndpointInfo)
719 { // Quick sanity check on endpoint properties
720 TUint dir=aEndpointInfo->iDir;
721 TInt size=aEndpointInfo->iSize;
724 switch (aEndpointInfo->iType)
726 case KUsbEpTypeControl:
727 if(dir != KUsbEpDirBidirect || size > 64)
730 case KUsbEpTypeIsochronous:
731 if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1023)
735 if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 64)
738 case KUsbEpTypeInterrupt:
739 if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 64)
748 TInt DLddTestUsbcChannel::SetupIfcDescriptor(TUsbcInterface* aIfc, TUsbcClassInfo& aClass,
749 TDesC8* aString, const TUsbcEndpointInfo aEndpointData[])
751 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::SetupIfcDescriptor()")));
753 // interface descriptor
754 TUsbcDescriptorBase* d = TUsbcInterfaceDescriptor::New(aIfc->iInterfaceSet->iInterfaceNumber,
756 aIfc->iEndpoints.Count(),
760 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc desc failed.")));
763 iDescriptors.InsertDescriptor(d);
765 // interface string descriptor
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)
772 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: $ descriptor too long - string will be truncated")));
773 strlen = KUsbStringDescStringMaxSize;
776 HBuf8Plat* stringbuf = NULL;
777 __NEWPLATBUF(stringbuf, strlen);
780 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc $ desc string failed.")));
781 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
786 __THREADREADPLATBUF(iClient, aString, stringbuf, r);
789 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Thread read error!")));
790 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
795 TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*stringbuf);
798 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc $ desc failed.")));
799 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
803 iDescriptors.SetIfcStringDescriptor(sd, aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
804 delete stringbuf; // the (EPOC) descriptor was copied by New()
807 // endpoint descriptors
808 for (TInt i = 0; i < aIfc->iEndpoints.Count(); ++i)
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)
815 // if non-standard endpoint descriptor requested...
816 if (aEndpointData[i].iExtra != 2)
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,
824 d = TUsbcAudioEndpointDescriptor::New((TUint8)i, aEndpointData[i]);
828 d = TUsbcEndpointDescriptor::New((TUint8)i, aEndpointData[i]);
832 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Memory allocation for ep desc #%d failed."), i));
833 iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
837 iDescriptors.InsertDescriptor(d);
846 Releases an existing USB interface (one setting), complete with endpoints, descriptors, etc.,
847 and removes it from the internal device configuration tree.
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.
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.
857 TInt DLddTestUsbcChannel::ReleaseInterface(TInt aInterfaceNumber)
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))
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));
868 // Reset reserved status of the endpoints
869 for (TInt i = 0; i < KMaxEndpointsPerClient+1; i++)
871 iEndpoints[i]->iReserve = EFalse;
873 if (aInterfaceNumber == 0)
875 TInt m = iIfcSet.iInterfaces.Count();
879 // Delete the setting itself + its ifc & ep descriptors
881 iDescriptors.DeleteIfcDescriptor(0, m);
886 // Delete the setting itself + its ifc & ep descriptors
887 DeleteInterface(aInterfaceNumber);
888 iDescriptors.DeleteIfcDescriptor(0, aInterfaceNumber);
890 // Delete the whole interface if all settings are gone
891 if (iIfcSet.iInterfaces.Count() == 0)
893 DeleteInterfaceSet();
898 void DLddTestUsbcChannel::DeleteInterfaceSet()
900 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::DeleteInterfaceSet")));
901 iIfcSet.iInterfaceNumber = 0;
902 iIfcSet.iCurrentInterface = 0;
903 iIfcSet.iInterfaces.ResetAndDestroy();
906 TInt DLddTestUsbcChannel::DoTransferAsyncReq(TInt aEndpointNumber, TAny* a1, TAny* a2, TRequestStatus& aStatus)
909 DTestUsbcEndpoint* pEndpoint = NULL;
910 TEndpointTransferInfo *pTfr = NULL;
913 if(!ValidEndpoint(aEndpointNumber))
915 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete")));
916 return KErrUsbEpNotInInterface;
924 TBool hostTransfer = EFalse;
927 hostTransfer = ETrue;
930 TEndpointTransferInfo transferInfo;
931 pTfr = (TEndpointTransferInfo*)&transferInfo;
932 r = __THREADRAWREAD(iClient, a1, (TUint8*)&transferInfo, sizeof(TEndpointTransferInfo));
935 __THREADPANIC(iClient, r);
937 if (aEndpointNumber != 0)
941 pEndpoint = iEndpoints[aEndpointNumber];
945 pEndpoint = iEndpoints[FindRealEndpoint(aEndpointNumber)];
950 pEndpoint = iEndpoints[0];
954 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete")));
955 return KErrUsbEpNotInInterface;
958 switch(pTfr->iTransferType)
960 case ETransferTypeReadUntilShort:
961 case ETransferTypeReadData:
963 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest Read")));
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;
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
976 __THREADPANIC(iClient, r);
978 r = pEndpoint->NewHostRequest(iClient, &aStatus, *pTfr, pTfr->iTransferType);
980 r = pEndpoint->NewRequest(iClient, &aStatus, *pTfr, pTfr->iTransferType);
984 case ETransferTypeWrite:
986 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest Write 1")));
987 if(!hostTransfer && !pEndpoint->SupportsDir(KUsbEpDirIn) && !pEndpoint->SupportsDir(KUsbEpDirBidirect))
989 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Write: wrong direction complete")));
990 r = KErrUsbEpBadDirection;
994 r = pEndpoint->NewHostRequest(iClient, &aStatus, *pTfr, ETransferTypeWrite);
996 r = pEndpoint->NewRequest(iClient, &aStatus, *pTfr, ETransferTypeWrite);
1000 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Not supported complete")));
1001 r = KErrNotSupported;
1007 TInt DLddTestUsbcChannel::HaltClearEndpoint(TBool aHalt, TInt aEndpointNumber)
1009 DTestUsbcEndpoint* pEndpoint = NULL;
1010 if (aEndpointNumber != 0)
1012 pEndpoint = iEndpoints[FindRealEndpoint(aEndpointNumber)];
1016 pEndpoint = iEndpoints[0];
1021 err = pEndpoint->Halt();
1025 err = pEndpoint->Clear();
1030 TInt DLddTestUsbcChannel::HostEndpointStatusNotify(TInt aEndpointNumber, TRequestStatus* aStatus)
1032 DTestUsbcEndpoint* pEndpoint = iEndpoints[aEndpointNumber];
1033 return pEndpoint->HostStatusNotify(iClient, aStatus);
1036 TInt DLddTestUsbcChannel::ClearEndpoint(TInt aEndpointNumber)
1038 DTestUsbcEndpoint* pEndpoint = iEndpoints[aEndpointNumber];
1039 return pEndpoint->Clear();
1042 TInt DLddTestUsbcChannel::EndpointStatusNotify(TUint* aEndpointMask, TRequestStatus* aStatus)
1044 iEndpointStatusMask = aEndpointMask;
1045 iEndpointStatusNotifyRequest = aStatus;
1049 void DLddTestUsbcChannel::EndpointStatusNotifyCallback()
1051 if (iEndpointStatusNotifyRequest == NULL || iEndpointStatusMask == NULL)
1056 //Get status for interface's endpoints.
1057 //NOTE: currently we only support one interface.
1058 TUsbcInterface* interface = iIfcSet.iInterfaces[0];
1060 for (TInt i = interface->iEndpoints.Count() - 1; i >= 0; i--)
1062 TUsbcLogicalEndpoint* logep = interface->iEndpoints[i];
1063 DTestUsbcEndpoint* pEndpoint = iEndpoints[FindRealEndpoint(logep->iLEndpointNum)];
1064 if (pEndpoint->IsHalted())
1067 bitmask = bitmask << 1;
1071 //Write bitmask back to client space.
1072 TInt r = __THREADRAWWRITE(iClient, (void*)iEndpointStatusMask, (TUint8*)&bitmask, (TInt)sizeof(bitmask));
1074 //Complete client request.
1075 Kern::RequestComplete(iClient, iEndpointStatusNotifyRequest, r);
1077 iEndpointStatusMask = NULL;
1078 iEndpointStatusNotifyRequest = NULL;
1081 TBool DLddTestUsbcChannel::ValidEndpoint(TInt aEndpointNumber)
1083 return (aEndpointNumber <= 5 && aEndpointNumber >= 0);
1086 TInt DLddTestUsbcChannel::FindRealEndpoint(TInt aEndpointNumber)
1088 TUsbcInterface* pIfc = iIfcSet.CurrentInterface();
1089 return pIfc->iEndpoints[aEndpointNumber - 1]->iLEndpointNum;
1092 void DLddTestUsbcChannel::AlternateDeviceStatusNotify()
1094 if (iAlternateDeviceStatusNotifyRequest != NULL)
1096 TInt r = __THREADRAWWRITE(iClient, (void*)iAlternateDeviceStatusNotifyValue, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState));
1097 Kern::RequestComplete(iClient, iAlternateDeviceStatusNotifyRequest, r);
1098 iAlternateDeviceStatusNotifyRequest = NULL;
1102 TInt DLddTestUsbcChannel::SetAlternateDeviceStatusNotify(TRequestStatus* aStatus, TUint* aValue)
1104 if (iAlternateDeviceStatusNotifyRequest != NULL)
1110 s = KRequestPending;
1112 __THREADRAWWRITE(iClient, (void*)aStatus, (TUint8*)&s, (TInt)sizeof(s));
1113 iAlternateDeviceStatusNotifyRequest = aStatus;
1114 iAlternateDeviceStatusNotifyValue = aValue;
1118 void DLddTestUsbcChannel::CancelAlternateDeviceStatusNotify()
1120 if (iAlternateDeviceStatusNotifyRequest != NULL)
1122 __THREADRAWWRITE(iClient, (void*)iAlternateDeviceStatusNotifyValue, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState));
1123 Kern::RequestComplete(iClient, iAlternateDeviceStatusNotifyRequest, KErrCancel);
1124 iAlternateDeviceStatusNotifyRequest = NULL;
1128 TInt DLddTestUsbcChannel::ReEnumerate(TRequestStatus* aStatus)
1130 SetDeviceState(EUsbcDeviceStateConfigured);
1131 Kern::RequestComplete(iClient, aStatus, KErrNone);
1135 void DLddTestUsbcChannel::SetDeviceState(TUsbcDeviceState aState)
1137 iDeviceState = aState;
1138 AlternateDeviceStatusNotify();