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