kerneltest/e32utils/testusbcldd/src/dlddtestusbcchannel.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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