|
1 // Copyright (c) 2007-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 // e32test\device\t_usbcsc.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #define __E32TEST_EXTENSION__ |
|
19 #include <e32test.h> |
|
20 #include <e32def.h> |
|
21 #include <e32def_private.h> |
|
22 #include <d32usbcsc.h> |
|
23 #include <hal.h> |
|
24 #include "t_usblib.h" |
|
25 #include <e32svr.h> |
|
26 #include "u32std.h" |
|
27 |
|
28 //#define DEBUGVERSION |
|
29 |
|
30 #ifdef DEBUGVERSION |
|
31 #define DEBUGPRINT(a) {a;} |
|
32 #else |
|
33 #define DEBUGPRINT(a) {} |
|
34 #endif |
|
35 |
|
36 LOCAL_D RTest test(_L("T_USBCSC")); |
|
37 |
|
38 _LIT(KLddName, "eusbcsc"); |
|
39 _LIT(KUsbDeviceName, "Usbcsc"); |
|
40 |
|
41 static char sym[9]="`*+@$#%!"; |
|
42 |
|
43 // Constants to be used in Descriptor Tests |
|
44 |
|
45 static const TInt KUsbDesc_SizeOffset = 0; //for SetCS EndpointDescriptor |
|
46 static const TInt KUsbDesc_TypeOffset = 1; //for SetCS EndpointDescriptor |
|
47 |
|
48 static const TInt KDevDesc_SpecOffset = 2; |
|
49 static const TInt KDevDesc_DevClassOffset = 4; |
|
50 static const TInt KDevDesc_DevSubClassOffset = 5; |
|
51 static const TInt KDevDesc_DevProtocolOffset = 6; |
|
52 static const TInt KDevDesc_Ep0SizeOffset = 7; |
|
53 static const TInt KDevDesc_VendorIdOffset = 8; |
|
54 static const TInt KDevDesc_ProductIdOffset = 10; |
|
55 static const TInt KDevDesc_DevReleaseOffset = 12; |
|
56 |
|
57 static const TInt KConfDesc_AttribOffset = 7; |
|
58 static const TInt KConfDesc_MaxPowerOffset = 8; |
|
59 |
|
60 static const TInt KIfcDesc_SettingOffset = 2; |
|
61 static const TInt KIfcDesc_ProtocolOffset = 7; |
|
62 |
|
63 static const TInt KEpDesc_PacketSizeOffset = 4; |
|
64 static const TInt KEpDesc_IntervalOffset = 6; |
|
65 static const TInt KEpDesc_SynchAddressOffset = 8; |
|
66 |
|
67 // |
|
68 const TInt KUsbcMaxBuffers = 32; // Maximum buffers per device (15 In + 15 Out + 2 for Ep0) |
|
69 const TInt KUsbcMaxAltSetting = 5; // Maximum alternate setting an interface can have |
|
70 |
|
71 static RDevUsbcScClient gPort; |
|
72 |
|
73 // Values to be found from device capabilities |
|
74 static TBool gSupportsHighSpeed; |
|
75 TInt gInterruptInEpFound = 0; |
|
76 |
|
77 //Command Line parameters |
|
78 TBool gRealHardware = EFalse; |
|
79 TInt gVerbose = 0; |
|
80 enum TSpecTestType {EAll=0,EBufRead,EBufWrite,EEp0, EAltSet, EInterface, ECancel, EInvalidApi, EDescriptor, /*insert new non-bil here*/ EBilRw=100, EBilEp0, EBilAlt}; |
|
81 TSpecTestType gSpecTest = EAll; |
|
82 |
|
83 RChunk gChunk; |
|
84 static const TInt gBytesReceived = 128; |
|
85 static const TInt KMaxBufSize = 1024 * 1024; // max data buffer size: 1MB |
|
86 |
|
87 // Masks for EP0Setup type. (Used By BIL tests and LDD tests) |
|
88 const TUint KDeviceToHost = 0x80; |
|
89 //const TUint KDirMask = 0x80; |
|
90 const TUint KDirBit = 0x7; |
|
91 |
|
92 //const TUint KReqTypeMask = 0x60; |
|
93 const TUint KReqTypeBit = 0x5; |
|
94 |
|
95 const TUint KRecepientMask = 0x1F; |
|
96 const TUint KRecepientReservedMask = 0x1C; |
|
97 |
|
98 |
|
99 //Forward Declaration |
|
100 class TAlternateSetting; |
|
101 class CActiveRW; |
|
102 class TBuffer; |
|
103 class TEndpointWrapper; |
|
104 |
|
105 // Stucture which holds how many in and out endpoints an alternate setting in the chunk should contain |
|
106 struct TEndpointDescription |
|
107 { |
|
108 TInt iNumOfEp; |
|
109 TInt iNumOfOutEp; |
|
110 TInt iNumOfInEp; |
|
111 }; |
|
112 // This class is used for checking against the contents of the chunk after its construction |
|
113 class TAltSetConfig |
|
114 { |
|
115 public: |
|
116 TInt iNumOfAltSet; |
|
117 TEndpointDescription iEpsDesc[KMaxEndpointsPerClient]; |
|
118 }; |
|
119 |
|
120 enum Tep0phase {EReady, EDataIn}; |
|
121 |
|
122 struct Sep0SetupPacket |
|
123 { |
|
124 TUint8 iRequestType; |
|
125 TUint8 iRequest; |
|
126 TUint16 iwValue; |
|
127 TUint16 iwIndex; |
|
128 TUint16 iWlength; |
|
129 }; |
|
130 |
|
131 // CActive class to monitor KeyStrokes from User (Only EKeyEscape in this test) |
|
132 class CActiveConsole : public CActive |
|
133 { |
|
134 public: |
|
135 CActiveConsole(); |
|
136 ~CActiveConsole(); |
|
137 void GetCharacter(); |
|
138 |
|
139 private: |
|
140 // Defined as pure virtual by CActive; |
|
141 // implementation provided by this class. |
|
142 virtual void DoCancel(); |
|
143 // Defined as pure virtual by CActive; |
|
144 // implementation provided by this class, |
|
145 virtual void RunL(); |
|
146 }; |
|
147 |
|
148 //CActive class to monitor Device/AlternateSetting changes |
|
149 class CActiveDeviceStateNotifier : public CActive |
|
150 { |
|
151 public: |
|
152 CActiveDeviceStateNotifier(); |
|
153 ~CActiveDeviceStateNotifier(); |
|
154 void Activate(); |
|
155 |
|
156 private: |
|
157 virtual void DoCancel(); |
|
158 virtual void RunL(); |
|
159 |
|
160 private: |
|
161 TUint iDeviceState; |
|
162 }; |
|
163 |
|
164 class CActiveStallNotifier : public CActive |
|
165 { |
|
166 public: |
|
167 CActiveStallNotifier(); |
|
168 ~CActiveStallNotifier(); |
|
169 void Activate(); |
|
170 |
|
171 private: |
|
172 virtual void DoCancel(); |
|
173 virtual void RunL(); |
|
174 |
|
175 private: |
|
176 TUint iEndpointState; |
|
177 }; |
|
178 |
|
179 //Class containing all alternate settings |
|
180 class TInterface |
|
181 { |
|
182 public: |
|
183 TInterface(); |
|
184 ~TInterface(); |
|
185 void AddAlternateSetting(TAlternateSetting &aAlternateSetting); |
|
186 void SetActiveAlternateSetting(TInt aSettingNum, TBool aStartNextInAltSet = EFalse); |
|
187 TInt GetAltSettingChangeSequenceNum(); |
|
188 private: |
|
189 void IncrementAltSettingChangeSequenceNum(); |
|
190 private: |
|
191 TInt iAltSettingChangeSequenceNum; // To keep track of alternate setting changes, Always is one more than previous after an alternat setting change. |
|
192 RArray <TAlternateSetting> iAlternateSetting; |
|
193 }; |
|
194 |
|
195 //Class containing all endpoints of an alternate setting |
|
196 class TAlternateSetting |
|
197 { |
|
198 public: |
|
199 TAlternateSetting(TInt aAltSetNum); |
|
200 ~TAlternateSetting(); |
|
201 void AddEndpoint(CActiveRW &aEp); |
|
202 void SetInterfaceHandle(TInterface *aInterface); |
|
203 TInt GetAlternateSetting(); |
|
204 TInt GetInterfaceAltSettingChangeSequenceNum(); |
|
205 void Activate(TBool aStartNextInAltSet = EFalse); |
|
206 void SetChangeRequestFlag(CActiveRW *aEp); |
|
207 TBool CheckFlagForAllOutEndpoints(); |
|
208 void ChangeAlternateSetting(TInt aAltsetting); |
|
209 private: |
|
210 TInt iAltSetNum; |
|
211 TInterface *iInterface; |
|
212 RArray <TEndpointWrapper> iEndpoints; |
|
213 }; |
|
214 |
|
215 // CActive class represents an endpoint for reading or writing |
|
216 class CActiveRW : public CActive |
|
217 { |
|
218 public: |
|
219 CActiveRW(TInt aEndpointNum, TInt aDirection, TBuffer* aBuffer); |
|
220 ~CActiveRW(); |
|
221 void SetAlternateSettingHandle(TAlternateSetting *aAlternateSetting); |
|
222 TInt GetAlternateSettingOfEndpoint(); |
|
223 TBool CheckFlagForAllOutEndpoints(); |
|
224 TInt GetInterfaceAltSettingChangeSequenceNum(); |
|
225 void CallChangeAlternateSetting(TInt aAltsetting); |
|
226 |
|
227 TInt GetEndpointNumber(); |
|
228 TInt GetDirection(); |
|
229 |
|
230 void QueueRequests(); |
|
231 TInt StartRead(); |
|
232 void StartWrite(); |
|
233 void SetChangeRequestFlag(TBuffer *aBuffer); |
|
234 |
|
235 private: |
|
236 virtual void RunL(); |
|
237 virtual void DoCancel(); |
|
238 |
|
239 private: |
|
240 TInt iLogicalEndpointNum; |
|
241 TInt iDirection; |
|
242 TAlternateSetting* iAltSetting; |
|
243 |
|
244 public: |
|
245 TBuffer* iBuffer; |
|
246 }; |
|
247 |
|
248 class TBuffer |
|
249 { |
|
250 public: |
|
251 TBuffer(TInt aBufNum); |
|
252 ~TBuffer(); |
|
253 void SetEndpointHandle(CActiveRW* aEndpoint); |
|
254 void SetUpHeader(); |
|
255 void ProcessData(); |
|
256 void SendEP0Packet(TInt aLength); |
|
257 |
|
258 public: |
|
259 CActiveRW* iEndpoint; // To know which endpoint of an alternate setting it belongs to |
|
260 |
|
261 TInt iBufNum; |
|
262 TBool iIsHeaderSetUp; // If already setUp |
|
263 |
|
264 //For Ep0 |
|
265 Sep0SetupPacket* iSetup; |
|
266 Tep0phase iEp0Phase; |
|
267 |
|
268 //For Reading |
|
269 TUsbcScTransferHeader* iTransfer; |
|
270 SUsbcScBufferHeader* iHeader; |
|
271 TUint iMaxBufferSize; |
|
272 TUint iMaxPacketSize; |
|
273 TUint iBase; |
|
274 TInt iOldTail; |
|
275 |
|
276 #if _DEBUG |
|
277 TUint iPrevSequence; |
|
278 TUint iLoop; |
|
279 #endif |
|
280 TInt iBytesReceived; |
|
281 TInt iTickCount; |
|
282 TUint iPrevAltSeq; |
|
283 |
|
284 |
|
285 //For Writing |
|
286 TUint iBufferOffset; |
|
287 TUint iLength; |
|
288 }; |
|
289 |
|
290 class TEndpointWrapper |
|
291 { |
|
292 public: |
|
293 CActiveRW* iEp; |
|
294 TBool iSettingChangeReceived; // Flag to check if "empty packet" containing alternate setting change is received |
|
295 }; |
|
296 |
|
297 |
|
298 /* Open drivers, with a few endpoints. Check each endpoint has headers that |
|
299 make sense. Getting the test program to this stage will be an |
|
300 achievement in itself! */ |
|
301 |
|
302 void TestBufferConstruction(TAltSetConfig* aAltSetConfig) |
|
303 { |
|
304 TInt r; |
|
305 test.Next(_L("Buffer Construction")); |
|
306 r = gPort.RealizeInterface(gChunk); |
|
307 test_KErrNone(r); |
|
308 |
|
309 TUsbcScChunkHeader chunkHeader(gChunk); |
|
310 |
|
311 DEBUGPRINT(test.Printf(_L("iBuffers at 0x%x, iAltSettings at 0x%x\n"),chunkHeader.iBuffers, chunkHeader.iAltSettings)); |
|
312 |
|
313 test_Equal(gChunk.Base()+ sizeof(TUint)*2, chunkHeader.iBuffers); |
|
314 |
|
315 DEBUGPRINT(test.Printf(_L("iBuffers: EP0Out: 0x%x EP0In: 0x%x\n"), chunkHeader.iBuffers->Ep0Out()->Offset(), |
|
316 chunkHeader.iBuffers->Ep0In()->Offset())); |
|
317 |
|
318 DEBUGPRINT(test.Printf(_L("iAltSettings: Number of: %d First offset: 0x%x \n"), chunkHeader.iAltSettings->iNumOfAltSettings, |
|
319 chunkHeader.iAltSettings->iAltTableOffset[0])); |
|
320 |
|
321 test_Compare(aAltSetConfig->iNumOfAltSet, ==, chunkHeader.iAltSettings->iNumOfAltSettings); |
|
322 |
|
323 TInt maxInEps = 0, maxOutEps = 0; |
|
324 for (int i = 0; i < chunkHeader.iAltSettings->iNumOfAltSettings; i++) |
|
325 { |
|
326 TInt inEps = 0, outEps = 0; |
|
327 DEBUGPRINT(test.Printf(_L("Alternate Setting %d offset: 0x%x \n"), i, chunkHeader.iAltSettings->iAltTableOffset[i])); |
|
328 |
|
329 TInt8* endpoint = (TInt8*) (chunkHeader.iAltSettings->iAltTableOffset[i] + (TInt) gChunk.Base()); |
|
330 for (int j = 1; j <= chunkHeader.GetNumberOfEndpoints(i); j++) |
|
331 { |
|
332 TUsbcScHdrEndpointRecord* endpointInf = (TUsbcScHdrEndpointRecord*) &(endpoint[j * chunkHeader.iAltSettings->iEpRecordSize]); |
|
333 DEBUGPRINT(test.Printf(_L("Endpoint %d owns buffer %d BufferOffset 0x%x Dir %d Type %d\n"), j, endpointInf->iBufferNo, chunkHeader.iBuffers->Buffers(endpointInf->iBufferNo)->Offset(), |
|
334 endpointInf->Direction(), endpointInf->Type())); |
|
335 if (endpointInf->Direction() == KUsbScHdrEpDirectionOut) |
|
336 { |
|
337 outEps++; |
|
338 } |
|
339 else |
|
340 { |
|
341 inEps++; |
|
342 } |
|
343 } |
|
344 |
|
345 DEBUGPRINT(test.Printf(_L("Test if Alternate Setting %d has %d endpoints (%d Out Endpoint(s) and %d In Endpoint(s)) \n"), i, aAltSetConfig->iEpsDesc[i].iNumOfEp, |
|
346 aAltSetConfig->iEpsDesc[i].iNumOfOutEp, aAltSetConfig->iEpsDesc[i].iNumOfInEp)); |
|
347 |
|
348 test_Compare(chunkHeader.GetNumberOfEndpoints(i), ==, aAltSetConfig->iEpsDesc[i].iNumOfEp); |
|
349 test_Compare(outEps, ==, aAltSetConfig->iEpsDesc[i].iNumOfOutEp); |
|
350 test_Compare(inEps, ==, aAltSetConfig->iEpsDesc[i].iNumOfInEp); |
|
351 if (outEps > maxOutEps) |
|
352 maxOutEps = outEps; |
|
353 if (inEps > maxInEps) |
|
354 maxInEps = inEps; |
|
355 } |
|
356 test_Compare(chunkHeader.iBuffers->NumberOfBuffers(), ==, (maxOutEps + maxInEps)); |
|
357 } |
|
358 |
|
359 // Function Definitions ***** |
|
360 |
|
361 TInt WaitUntilTimeout(TInt aTimout, TRequestStatus& aStatus) |
|
362 { |
|
363 TRequestStatus timerStatus; |
|
364 RTimer timer; |
|
365 test_KErrNone(timer.CreateLocal()); |
|
366 timer.After(timerStatus,aTimout*1000); |
|
367 User::WaitForRequest(timerStatus, aStatus); |
|
368 return (timerStatus.Int()!=KRequestPending)?KErrTimedOut:KErrNone; |
|
369 } |
|
370 |
|
371 // Class CActiveConsole |
|
372 |
|
373 CActiveConsole::CActiveConsole() |
|
374 : CActive(EPriorityHigh) |
|
375 { |
|
376 CActiveScheduler::Add(this); |
|
377 } |
|
378 |
|
379 CActiveConsole::~CActiveConsole() |
|
380 { |
|
381 Cancel(); |
|
382 } |
|
383 |
|
384 void CActiveConsole::GetCharacter() |
|
385 { |
|
386 test.Printf(_L("\n \n ***** Press Escape to exit ***** \n \n")); |
|
387 |
|
388 test.Console()->Read(iStatus); |
|
389 SetActive(); |
|
390 } |
|
391 |
|
392 void CActiveConsole::DoCancel() |
|
393 { |
|
394 DEBUGPRINT(test.Printf(_L("CActiveConsole::DoCancel\n"))); |
|
395 test.Console()->ReadCancel(); |
|
396 } |
|
397 |
|
398 void CActiveConsole::RunL() |
|
399 { |
|
400 DEBUGPRINT(test.Printf(_L("\n CActiveConsole::RunL\n"))); |
|
401 if (test.Console()->KeyCode() == EKeyEscape) |
|
402 { |
|
403 test.Printf(_L("CActiveConsole: ESC key pressed -> stopping active scheduler...\n")); |
|
404 CActiveScheduler::Stop(); |
|
405 return; |
|
406 } |
|
407 GetCharacter(); |
|
408 } |
|
409 |
|
410 // Class CActiveDeviceStateNotifier |
|
411 CActiveDeviceStateNotifier::CActiveDeviceStateNotifier() |
|
412 : CActive(EPriorityHigh) |
|
413 { |
|
414 DEBUGPRINT(test.Printf(_L("CActiveDeviceStateNotifier::CActiveDeviceStateNotifier() \n"))); |
|
415 CActiveScheduler::Add(this); |
|
416 } |
|
417 |
|
418 CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier() |
|
419 { |
|
420 DEBUGPRINT(test.Printf(_L("CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier() \n"))); |
|
421 Cancel(); |
|
422 } |
|
423 |
|
424 void CActiveDeviceStateNotifier::DoCancel() |
|
425 { |
|
426 DEBUGPRINT(test.Printf(_L("CActiveDeviceStateNotifier::DoCancel\n"))); |
|
427 gPort.AlternateDeviceStatusNotifyCancel(); |
|
428 } |
|
429 |
|
430 void CActiveDeviceStateNotifier::Activate() |
|
431 { |
|
432 gPort.AlternateDeviceStatusNotify(iStatus, iDeviceState); |
|
433 SetActive(); |
|
434 } |
|
435 |
|
436 void CActiveDeviceStateNotifier::RunL() |
|
437 { |
|
438 DEBUGPRINT(test.Printf(_L("CActiveDeviceStateNotifier::RunL() \n"))); |
|
439 if (!(iDeviceState & KUsbAlternateSetting)) |
|
440 { |
|
441 switch (iDeviceState) |
|
442 { |
|
443 case EUsbcDeviceStateUndefined: |
|
444 DEBUGPRINT(test.Printf(_L("Device State notifier: Undefined \n"))); |
|
445 break; |
|
446 case EUsbcDeviceStateAttached: |
|
447 DEBUGPRINT(test.Printf(_L("Device State notifier: Attached \n"))); |
|
448 break; |
|
449 case EUsbcDeviceStatePowered: |
|
450 DEBUGPRINT(test.Printf(_L("Device State notifier: Powered \n"))); |
|
451 break; |
|
452 case EUsbcDeviceStateDefault: |
|
453 DEBUGPRINT(test.Printf(_L("Device State notifier: Default \n"))); |
|
454 break; |
|
455 case EUsbcDeviceStateAddress: |
|
456 DEBUGPRINT(test.Printf(_L("Device State notifier: Address \n"))); |
|
457 break; |
|
458 case EUsbcDeviceStateConfigured: |
|
459 DEBUGPRINT(test.Printf(_L("Device State notifier: Configured \n"))); |
|
460 break; |
|
461 case EUsbcDeviceStateSuspended: |
|
462 DEBUGPRINT(test.Printf(_L("Device State notifier: Suspended \n"))); |
|
463 break; |
|
464 default: |
|
465 DEBUGPRINT(test.Printf(_L("Device State notifier: !!!! NOT RECOGNISED !!!! \n"))); |
|
466 } |
|
467 } |
|
468 else if (iDeviceState & KUsbAlternateSetting) |
|
469 { |
|
470 test.Printf(_L("Device State notifier: Alternate interface setting has changed: now %d \n"), |
|
471 iDeviceState & ~KUsbAlternateSetting); |
|
472 } |
|
473 Activate(); |
|
474 } |
|
475 |
|
476 |
|
477 |
|
478 CActiveStallNotifier::CActiveStallNotifier() |
|
479 : CActive(EPriorityNormal), |
|
480 iEndpointState(0) |
|
481 { |
|
482 DEBUGPRINT(test.Printf(_L("CActiveStallNotifier::CActiveStallNotifier() \n"))); |
|
483 CActiveScheduler::Add(this); |
|
484 } |
|
485 |
|
486 CActiveStallNotifier::~CActiveStallNotifier() |
|
487 { |
|
488 DEBUGPRINT(test.Printf(_L("CActiveStallNotifier::~CActiveStallNotifier() \n"))); |
|
489 Cancel(); |
|
490 } |
|
491 |
|
492 void CActiveStallNotifier::DoCancel() |
|
493 { |
|
494 DEBUGPRINT(test.Printf(_L("CActiveStallNotifier::DoCancel() \n"))); |
|
495 gPort.EndpointStatusNotifyCancel(); |
|
496 } |
|
497 |
|
498 void CActiveStallNotifier::RunL() |
|
499 { |
|
500 DEBUGPRINT(test.Printf(_L("CActiveStallNotifier::RunL() \n"))); |
|
501 test.Printf(_L("StallNotifier Endpointstate 0x%x\n"), iEndpointState); |
|
502 Activate(); |
|
503 } |
|
504 |
|
505 void CActiveStallNotifier::Activate() |
|
506 { |
|
507 gPort.EndpointStatusNotify(iStatus, iEndpointState); |
|
508 SetActive(); |
|
509 } |
|
510 |
|
511 |
|
512 |
|
513 |
|
514 |
|
515 |
|
516 |
|
517 //Function definitions for Class TInterface |
|
518 |
|
519 TInterface::TInterface() |
|
520 :iAltSettingChangeSequenceNum(0) |
|
521 { } |
|
522 |
|
523 TInterface::~TInterface() |
|
524 { |
|
525 DEBUGPRINT(test.Printf(_L("TInterface::~TInterface()\n"))); |
|
526 iAlternateSetting.Reset(); |
|
527 } |
|
528 |
|
529 void TInterface::AddAlternateSetting(TAlternateSetting &aAlternateSetting) |
|
530 { |
|
531 aAlternateSetting.SetInterfaceHandle(this); |
|
532 iAlternateSetting.Append(aAlternateSetting); |
|
533 } |
|
534 |
|
535 void TInterface::SetActiveAlternateSetting(TInt aSettingNum, TBool aStartNextInAltSet) |
|
536 { |
|
537 if (aStartNextInAltSet) |
|
538 { |
|
539 IncrementAltSettingChangeSequenceNum(); |
|
540 test.Printf(_L("ALTERNATE SETTING CHANGE! Calling StartNextInAlternateSetting() \n")); |
|
541 TInt r = gPort.StartNextInAlternateSetting(); |
|
542 test_Compare((r&0xFFFF), ==, aSettingNum); |
|
543 } |
|
544 |
|
545 iAlternateSetting[aSettingNum].Activate(aStartNextInAltSet); |
|
546 } |
|
547 |
|
548 void TInterface::IncrementAltSettingChangeSequenceNum() |
|
549 { |
|
550 iAltSettingChangeSequenceNum++; |
|
551 } |
|
552 TInt TInterface::GetAltSettingChangeSequenceNum() |
|
553 { |
|
554 return iAltSettingChangeSequenceNum; |
|
555 } |
|
556 |
|
557 TAlternateSetting::TAlternateSetting(TInt aAltSetNum) |
|
558 :iAltSetNum(aAltSetNum) |
|
559 { } |
|
560 |
|
561 //Function definitions for Class TAlternateSetting |
|
562 |
|
563 TAlternateSetting::~TAlternateSetting() |
|
564 { |
|
565 DEBUGPRINT(test.Printf(_L("TAlternateSetting::~TAlternateSetting() \n"))); |
|
566 iEndpoints.Reset(); |
|
567 } |
|
568 |
|
569 void TAlternateSetting::AddEndpoint(CActiveRW &aEndpoint) |
|
570 { |
|
571 TEndpointWrapper* wrapper = new TEndpointWrapper(); |
|
572 test_NotNull(wrapper); |
|
573 |
|
574 aEndpoint.SetAlternateSettingHandle(this); |
|
575 |
|
576 wrapper->iEp = &aEndpoint; |
|
577 wrapper->iSettingChangeReceived = EFalse; |
|
578 |
|
579 iEndpoints.Append(*wrapper); |
|
580 delete wrapper; |
|
581 } |
|
582 |
|
583 void TAlternateSetting::SetInterfaceHandle(TInterface *aInterface) |
|
584 { |
|
585 iInterface = aInterface; |
|
586 } |
|
587 |
|
588 TInt TAlternateSetting::GetAlternateSetting() |
|
589 { |
|
590 return iAltSetNum; |
|
591 } |
|
592 |
|
593 TInt TAlternateSetting::GetInterfaceAltSettingChangeSequenceNum() |
|
594 { |
|
595 return iInterface->GetAltSettingChangeSequenceNum(); |
|
596 } |
|
597 |
|
598 |
|
599 void TAlternateSetting::Activate(TBool aStartNextInAltSet) |
|
600 { |
|
601 // set handle for Ep0 |
|
602 for(TInt count = 0; count < iEndpoints.Count(); count++) |
|
603 { |
|
604 if(iEndpoints[count].iEp->GetEndpointNumber() == 0) |
|
605 { |
|
606 iEndpoints[count].iEp->SetAlternateSettingHandle(this); |
|
607 break; |
|
608 } |
|
609 } |
|
610 |
|
611 if (gSpecTest == EAltSet) |
|
612 test.Printf(_L("On host side, on the Interface Tab, Change to a differnt Alternate Setting and read or write from an endpoint in the new alternate setting \n\n")); |
|
613 |
|
614 if (aStartNextInAltSet) |
|
615 { |
|
616 iEndpoints[0].iSettingChangeReceived = EFalse; |
|
617 iEndpoints[0].iEp->QueueRequests(); |
|
618 |
|
619 |
|
620 for (TInt i = 1; i < iEndpoints.Count() ; i++) // Not including EP0 |
|
621 { |
|
622 iEndpoints[i].iEp->iBuffer->SetEndpointHandle(iEndpoints[i].iEp); |
|
623 iEndpoints[i].iSettingChangeReceived = EFalse; |
|
624 |
|
625 if (iEndpoints[i].iEp->iBuffer->iIsHeaderSetUp) |
|
626 { |
|
627 iEndpoints[i].iEp->QueueRequests(); |
|
628 } |
|
629 else |
|
630 { |
|
631 //Set up Header as before |
|
632 iEndpoints[i].iEp->iBuffer->iIsHeaderSetUp = ETrue; |
|
633 iEndpoints[i].iEp->iBuffer->SetUpHeader(); |
|
634 } |
|
635 } |
|
636 } |
|
637 else |
|
638 { |
|
639 for (TInt i = 0; i < iEndpoints.Count() ; i++) |
|
640 { |
|
641 iEndpoints[i].iEp->iBuffer->SetEndpointHandle(iEndpoints[i].iEp); |
|
642 iEndpoints[i].iEp->iBuffer->iIsHeaderSetUp = ETrue; |
|
643 |
|
644 iEndpoints[i].iSettingChangeReceived = EFalse; |
|
645 iEndpoints[i].iEp->iBuffer->SetUpHeader(); |
|
646 } |
|
647 } |
|
648 } |
|
649 |
|
650 void CActiveRW::QueueRequests() |
|
651 { |
|
652 DEBUGPRINT(test.Printf(_L("CActiveRW::QueueRequests() for Buffer number iBufNum %d AlternateSetting %d iDirection %d\n"), |
|
653 iBuffer->iBufNum, iAltSetting->GetAlternateSetting(), iDirection)); |
|
654 if (!IsActive()) |
|
655 { |
|
656 if (iDirection != KUsbScHdrEpDirectionIn) |
|
657 { |
|
658 TInt r = StartRead(); |
|
659 if (r == KErrCompletion) |
|
660 RunL(); |
|
661 else if (r == KErrNone) |
|
662 SetActive(); |
|
663 } |
|
664 else |
|
665 StartWrite(); |
|
666 } |
|
667 } |
|
668 |
|
669 void TAlternateSetting::SetChangeRequestFlag(CActiveRW *aEp) |
|
670 { |
|
671 DEBUGPRINT(test.Printf(_L("Set ChangeRequestFlag to True for Buffer Number = %d \n"), aEp->iBuffer->iBufNum)); |
|
672 |
|
673 TInt countOfEndpoints = iEndpoints.Count(); |
|
674 |
|
675 for(TInt count = 0; count < countOfEndpoints; count++) |
|
676 { |
|
677 if(iEndpoints[count].iEp->iBuffer->iBufNum == aEp->iBuffer->iBufNum) |
|
678 { |
|
679 iEndpoints[count].iSettingChangeReceived = ETrue; |
|
680 break; |
|
681 } |
|
682 } |
|
683 } |
|
684 |
|
685 TBool TAlternateSetting::CheckFlagForAllOutEndpoints() |
|
686 { |
|
687 // now check if we have received Alternate Setting requests for all out EPs |
|
688 TInt countOfEndpoints = iEndpoints.Count(); |
|
689 TBool settingRequestReceivedForAllEps = ETrue; |
|
690 for(TInt count = 0; count < countOfEndpoints; count++) |
|
691 { |
|
692 if((iEndpoints[count].iEp->GetDirection() != KUsbScHdrEpDirectionIn) && !iEndpoints[count].iSettingChangeReceived) |
|
693 { |
|
694 settingRequestReceivedForAllEps = EFalse; |
|
695 break; |
|
696 } |
|
697 } |
|
698 |
|
699 return settingRequestReceivedForAllEps; |
|
700 } |
|
701 |
|
702 void TAlternateSetting::ChangeAlternateSetting(TInt aAltSetting) |
|
703 { |
|
704 iInterface->SetActiveAlternateSetting(aAltSetting, ETrue); |
|
705 } |
|
706 |
|
707 //Function definitions for Class CActiveRW |
|
708 CActiveRW::CActiveRW(TInt aEndpointNum, TInt aDirection, TBuffer* aBuffer) |
|
709 : CActive(EPriorityNormal), |
|
710 iLogicalEndpointNum(aEndpointNum), |
|
711 iDirection(aDirection) |
|
712 { |
|
713 CActiveScheduler::Add(this); |
|
714 iBuffer = aBuffer; |
|
715 } |
|
716 |
|
717 CActiveRW::~CActiveRW() |
|
718 { |
|
719 DEBUGPRINT(test.Printf(_L("CActiveRW::~CActiveRW\n"))); |
|
720 Cancel(); |
|
721 } |
|
722 |
|
723 void CActiveRW::DoCancel() |
|
724 { |
|
725 DEBUGPRINT(test.Printf(_L("CActiveRW::DoCancel for Buffer number iBufNum %d AlternateSetting %d\n"), |
|
726 iBuffer->iBufNum, iAltSetting->GetAlternateSetting())); |
|
727 if (IsActive()) |
|
728 { |
|
729 if (iDirection == KUsbScHdrEpDirectionOut) |
|
730 gPort.ReadCancel(iBuffer->iBufNum); |
|
731 else if (iDirection == KUsbScHdrEpDirectionIn) |
|
732 gPort.WriteCancel(iBuffer->iBufNum); |
|
733 else |
|
734 { |
|
735 gPort.WriteCancel(iBuffer->iBufNum); |
|
736 gPort.ReadCancel(iBuffer->iBufNum); |
|
737 } |
|
738 } |
|
739 } |
|
740 |
|
741 void CActiveRW::SetAlternateSettingHandle(TAlternateSetting *aAlternateSetting) |
|
742 { |
|
743 iAltSetting = aAlternateSetting; |
|
744 } |
|
745 |
|
746 TInt CActiveRW::GetAlternateSettingOfEndpoint() |
|
747 { |
|
748 return iAltSetting->GetAlternateSetting(); |
|
749 } |
|
750 |
|
751 TBool CActiveRW::CheckFlagForAllOutEndpoints() |
|
752 { |
|
753 return iAltSetting->CheckFlagForAllOutEndpoints(); |
|
754 } |
|
755 |
|
756 TInt CActiveRW::GetInterfaceAltSettingChangeSequenceNum() |
|
757 { |
|
758 return iAltSetting->GetInterfaceAltSettingChangeSequenceNum(); |
|
759 } |
|
760 |
|
761 void CActiveRW::CallChangeAlternateSetting(TInt aAltsetting) |
|
762 { |
|
763 iAltSetting->ChangeAlternateSetting(aAltsetting); |
|
764 } |
|
765 |
|
766 void CActiveRW::SetChangeRequestFlag(TBuffer *aBuffer) |
|
767 { |
|
768 iAltSetting->SetChangeRequestFlag(this); |
|
769 } |
|
770 |
|
771 TInt CActiveRW::GetEndpointNumber() |
|
772 { |
|
773 return iLogicalEndpointNum; |
|
774 } |
|
775 |
|
776 TInt CActiveRW::GetDirection() |
|
777 { |
|
778 return iDirection; |
|
779 } |
|
780 |
|
781 //Prototypes |
|
782 void LoadDriver(); |
|
783 void OpenChannel(); |
|
784 void CloseChannel(); |
|
785 void UnloadDriver(); |
|
786 void TestMultipleChannels(); |
|
787 void CheckDeviceCapabilities(); |
|
788 TInt SettingOne(TInt aAltSetNo); |
|
789 TInt SettingTwo(TInt aAltSetNo); |
|
790 TInt SettingThreeIn(TInt aAltSetNo); |
|
791 TInt SettingFourOut(TInt aAltSetNo); |
|
792 TInt SettingFive(TInt aAltSetNo); |
|
793 TInt InvalidSettingOne(TInt aAltSetNo); |
|
794 TInt InvalidSettingTwo(TInt aAltSetNo); |
|
795 TInt InvalidSettingThree(TInt aAltSetNo); |
|
796 |
|
797 void TestBufferHandling() |
|
798 { |
|
799 LoadDriver(); |
|
800 OpenChannel(); |
|
801 |
|
802 TAltSetConfig *altSetConfig = new TAltSetConfig; |
|
803 altSetConfig->iNumOfAltSet = 1; |
|
804 TEndpointDescription temp = {2,1,1}; |
|
805 altSetConfig->iEpsDesc[0] = temp; |
|
806 |
|
807 test_KErrNone(SettingOne(0)); |
|
808 if (gSpecTest==EAltSet) |
|
809 { |
|
810 test_KErrNone(SettingTwo(1)); |
|
811 test_KErrNone(SettingThreeIn(2)); |
|
812 test_KErrNone(SettingFourOut(3)); |
|
813 |
|
814 altSetConfig->iNumOfAltSet = 4; |
|
815 TEndpointDescription temp1 = {5,4,1}; |
|
816 TEndpointDescription temp2 = {3,0,3}; |
|
817 TEndpointDescription temp3 = {3,3,0}; |
|
818 |
|
819 altSetConfig->iEpsDesc[1] = temp1; |
|
820 altSetConfig->iEpsDesc[2] = temp2; |
|
821 altSetConfig->iEpsDesc[3] = temp3; |
|
822 } |
|
823 |
|
824 TInt r = gPort.RealizeInterface(gChunk); |
|
825 test_KErrNone(r); |
|
826 |
|
827 if (gRealHardware) |
|
828 { |
|
829 TUsbcScChunkHeader chunkHeader(gChunk); |
|
830 |
|
831 test.Printf(_L("\n \n Trying hardware\nPlease start the Host side application...\n")); |
|
832 |
|
833 TRequestStatus status; |
|
834 gPort.ReEnumerate(status); |
|
835 User::WaitForRequest(status); |
|
836 |
|
837 TUsbcDeviceState device_state = EUsbcDeviceStateUndefined; |
|
838 TInt r = gPort.DeviceStatus(device_state); |
|
839 if (r != KErrNone) |
|
840 { |
|
841 test.Printf(_L("Error %d on querying device state"), r); |
|
842 } |
|
843 else |
|
844 { |
|
845 DEBUGPRINT(test.Printf(_L("Current device state: %s \n"), |
|
846 (device_state == EUsbcDeviceStateUndefined) ? _S("Undefined") : |
|
847 ((device_state == EUsbcDeviceStateAttached) ? _S("Attached") : |
|
848 ((device_state == EUsbcDeviceStatePowered) ? _S("Powered") : |
|
849 ((device_state == EUsbcDeviceStateDefault) ? _S("Default") : |
|
850 ((device_state == EUsbcDeviceStateAddress) ? _S("Address") : |
|
851 ((device_state == EUsbcDeviceStateConfigured) ? _S("Configured") : |
|
852 ((device_state == EUsbcDeviceStateSuspended) ? _S("Suspended") : |
|
853 _S("Unknown"))))))))); |
|
854 } |
|
855 |
|
856 CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler(); |
|
857 CActiveScheduler::Install(myScheduler); |
|
858 |
|
859 __UHEAP_MARK; |
|
860 |
|
861 CActiveConsole* myActiveConsole = new CActiveConsole(); |
|
862 myActiveConsole->GetCharacter(); |
|
863 |
|
864 CActiveDeviceStateNotifier* myDeviceStateNotifier = new CActiveDeviceStateNotifier(); |
|
865 myDeviceStateNotifier->Activate(); |
|
866 |
|
867 CActiveStallNotifier* myEndpointStateNotifier = new CActiveStallNotifier(); |
|
868 myEndpointStateNotifier->Activate(); |
|
869 |
|
870 TBuffer* bufferEp0 = new TBuffer(KUsbcScEndpointZero); |
|
871 |
|
872 // Keep an array of pointer of Buffers |
|
873 TBuffer* bufferArray[KUsbcMaxBuffers]; |
|
874 for(TInt i = 0; i < chunkHeader.iBuffers->NumberOfBuffers(); i++) |
|
875 { |
|
876 TBuffer* buf = new TBuffer(i); |
|
877 bufferArray[i] = buf; |
|
878 } |
|
879 |
|
880 TInterface* interface1 = new TInterface; |
|
881 TAlternateSetting* alternateSetting; |
|
882 |
|
883 // Keep an array of pointer of the alternate settings |
|
884 TAlternateSetting** altSetArray; |
|
885 altSetArray = new TAlternateSetting *[KUsbcMaxAltSetting]; |
|
886 TInt number = 0; |
|
887 |
|
888 |
|
889 CActiveRW *endpoint0 = new CActiveRW(0,KUsbScHdrEpDirectionBiDir, bufferEp0); |
|
890 |
|
891 // Keep an array of pointer of Endpoints |
|
892 CActiveRW** array; |
|
893 array = new CActiveRW *[KUsbcMaxEndpoints]; |
|
894 TInt count = 0; |
|
895 array[count++] = endpoint0; |
|
896 |
|
897 |
|
898 for(TInt i = 0; i < chunkHeader.iAltSettings->iNumOfAltSettings; i++) |
|
899 { |
|
900 TInt8* iEp = (TInt8*) (chunkHeader.iAltSettings->iAltTableOffset[i] + (TInt) gChunk.Base()); |
|
901 alternateSetting = new TAlternateSetting(i); |
|
902 alternateSetting->AddEndpoint(*endpoint0); |
|
903 |
|
904 for (TInt epNum = 1; epNum <= chunkHeader.GetNumberOfEndpoints(i); epNum++) |
|
905 { |
|
906 TUsbcScHdrEndpointRecord* endpointInf = (TUsbcScHdrEndpointRecord*) &(iEp[epNum * chunkHeader.iAltSettings->iEpRecordSize]); |
|
907 DEBUGPRINT(test.Printf(_L("Endpoint %d owns buffer %d BufferOffset 0x%x Dir %d Type %d\n"), epNum, endpointInf->iBufferNo, chunkHeader.iBuffers->Buffers(endpointInf->iBufferNo)->Offset(), |
|
908 endpointInf->Direction(), endpointInf->Type())); |
|
909 CActiveRW *EndpointRW = new CActiveRW(epNum, endpointInf->Direction(), bufferArray[endpointInf->iBufferNo]); |
|
910 alternateSetting->AddEndpoint(*EndpointRW); |
|
911 array[count++] = EndpointRW; |
|
912 } |
|
913 altSetArray[number++] = alternateSetting; |
|
914 interface1->AddAlternateSetting(*alternateSetting); |
|
915 } |
|
916 |
|
917 interface1->SetActiveAlternateSetting(0); |
|
918 CActiveScheduler::Start(); |
|
919 // User::After(2000000); |
|
920 |
|
921 test.Printf(_L("Cleaning Up \n")); |
|
922 |
|
923 test.Printf(_L("Delete endpoint array \n")); |
|
924 for(TInt i = 0; i < count; i++) |
|
925 { |
|
926 delete array[i]; |
|
927 } |
|
928 delete [] array; |
|
929 |
|
930 test.Printf(_L("Delete altset array \n")); |
|
931 for (TInt i = 0; i < number; i++) |
|
932 { |
|
933 delete altSetArray[i]; |
|
934 } |
|
935 delete [] altSetArray; |
|
936 |
|
937 delete interface1; |
|
938 |
|
939 test.Printf(_L("Delete buffer array \n")); |
|
940 for(TInt i = 0; i < chunkHeader.iBuffers->NumberOfBuffers(); i++) |
|
941 { |
|
942 delete bufferArray[i]; |
|
943 } |
|
944 test.Printf(_L("Delete buffer ep0 \n")); |
|
945 delete bufferEp0; |
|
946 |
|
947 delete myEndpointStateNotifier; |
|
948 delete myDeviceStateNotifier; |
|
949 delete myActiveConsole; |
|
950 |
|
951 __UHEAP_MARKEND; |
|
952 |
|
953 test.Printf(_L("Uninstalling scheduler \n")); |
|
954 |
|
955 CActiveScheduler::Install(NULL); // Uninstalling the scheduler |
|
956 delete myScheduler; |
|
957 } |
|
958 delete altSetConfig; |
|
959 |
|
960 CloseChannel(); |
|
961 UnloadDriver(); |
|
962 } |
|
963 |
|
964 //To do Move Around Later |
|
965 //Function definitions for Class TBuffer |
|
966 TBuffer::TBuffer(TInt aBufNum) |
|
967 :iBufNum(aBufNum), |
|
968 iIsHeaderSetUp(EFalse), |
|
969 iSetup(NULL), //Ep0 |
|
970 iTransfer(NULL), |
|
971 iHeader(NULL), |
|
972 iOldTail(0), |
|
973 iBytesReceived(0), |
|
974 iTickCount(0), |
|
975 iPrevAltSeq(0) |
|
976 { |
|
977 iBase = (TUint) gChunk.Base(); |
|
978 } |
|
979 |
|
980 TBuffer::~TBuffer() |
|
981 { } |
|
982 |
|
983 void TBuffer::SetEndpointHandle(CActiveRW* aEndpoint) |
|
984 { |
|
985 iEndpoint = aEndpoint; |
|
986 } |
|
987 |
|
988 void TBuffer::SendEP0Packet(TInt aLength) |
|
989 { |
|
990 const char testString[] = "Once upon a time, there was a developer, that really did dispair. "; |
|
991 TUint8* data; |
|
992 TInt maxSize; |
|
993 TUsbcScChunkHeader chunkHeader(gChunk); |
|
994 |
|
995 iBufferOffset = chunkHeader.iBuffers->Ep0In()->Offset(); |
|
996 data = (TUint8*) (((TUint) iBufferOffset + iBase)); |
|
997 |
|
998 maxSize = chunkHeader.iBuffers->Ep0In()->Size(); |
|
999 test_Compare(maxSize, >= , aLength); |
|
1000 |
|
1001 TInt strPos=0; |
|
1002 TInt i; |
|
1003 for (i=0; i<aLength; i++, strPos++) |
|
1004 { |
|
1005 if (testString[strPos]==0) |
|
1006 strPos=0; |
|
1007 data[i]=testString[strPos]; |
|
1008 } |
|
1009 test.Printf(_L("Sending data.....")); |
|
1010 // copy data into buffer TO DO |
|
1011 gPort.WriteData(KUsbcScEndpointZero, iBufferOffset, aLength, 0, iEndpoint->iStatus); |
|
1012 User::WaitForRequest(iEndpoint->iStatus); |
|
1013 test_KErrNone(iEndpoint->iStatus.Int()); |
|
1014 test.Printf(_L("Sent!\n")); |
|
1015 } |
|
1016 |
|
1017 _LIT(KUndefined,"Undefined"); _LIT(KAttached,"KAttached"); _LIT(KPowered,"KPowered"); _LIT(KDefault,"Default"); |
|
1018 _LIT(KAddress,"Address"); _LIT(KConfigured,"Configured"); _LIT(KSuspended,"Suspended"); _LIT(KOther," <?> "); |
|
1019 const TDesC* const KStates[8] = {&KUndefined,&KAttached,&KPowered,&KDefault,&KAddress,&KConfigured,&KSuspended,&KOther}; |
|
1020 |
|
1021 void TBuffer::SetUpHeader() |
|
1022 { |
|
1023 DEBUGPRINT(test.Printf(_L("CActiveRW::SetUpHeader() for Buffer %d belonging to Endpoint %d in Alternate Setting %d \n"), |
|
1024 iBufNum, iEndpoint->GetEndpointNumber(), iEndpoint->GetAlternateSettingOfEndpoint())); |
|
1025 TUsbcScChunkHeader chunkHeader(gChunk); |
|
1026 TUsbcScHdrEndpointRecord* epInfo; |
|
1027 |
|
1028 #if _DEBUG |
|
1029 iLoop =0; |
|
1030 #endif |
|
1031 iEp0Phase=EReady; |
|
1032 |
|
1033 if (iEndpoint->GetEndpointNumber() == 0) |
|
1034 { |
|
1035 if ((gSpecTest == EEp0) || (gSpecTest == EAltSet)) |
|
1036 { |
|
1037 iBufNum = KUsbcScEndpointZero; |
|
1038 iHeader = (SUsbcScBufferHeader*) (( (TInt) chunkHeader.iBuffers->Ep0Out()->Offset()) + iBase); |
|
1039 |
|
1040 // To check instance of Alternate Setting Sequence Number |
|
1041 iTransfer = (TUsbcScTransferHeader*) (iHeader->iTail + iBase); |
|
1042 |
|
1043 iMaxBufferSize = chunkHeader.iBuffers->Ep0Out()->Size(); |
|
1044 DEBUGPRINT(test.Printf(_L("MaxBufferSize %d \n"), iMaxBufferSize)); |
|
1045 |
|
1046 TUint ep0MaxPacketSize = gPort.EndpointZeroMaxPacketSizes(); |
|
1047 DEBUGPRINT(test.Printf(_L("ep0 Max Packet Size = %d\n"), ep0MaxPacketSize)); |
|
1048 |
|
1049 iMaxPacketSize = (ep0MaxPacketSize == KUsbEpSize64) ? 64 : |
|
1050 ((ep0MaxPacketSize == KUsbEpSize32) ? 32 : |
|
1051 ((ep0MaxPacketSize == KUsbEpSize16) ? 16 : |
|
1052 ((ep0MaxPacketSize == KUsbEpSize8) ? 8 : 0))); |
|
1053 |
|
1054 test_Compare(iMaxPacketSize,>,0); |
|
1055 if (gSpecTest == EEp0) |
|
1056 test.Printf(_L("Writing from buffer %d \n On host side, on the Class or Vendor Request Tab, send a Vendor request from an Interface on Device-to-Host or Host-to-Device(to an Interface) \n\n"), iBufNum); |
|
1057 iEndpoint->QueueRequests(); |
|
1058 } |
|
1059 } |
|
1060 else |
|
1061 { |
|
1062 TInt r; |
|
1063 TBuf8<KUsbDescSize_Endpoint> endpointSizeDescriptor; |
|
1064 |
|
1065 r = gPort.GetEndpointDescriptor(iEndpoint->GetAlternateSettingOfEndpoint(), iEndpoint->GetEndpointNumber(), endpointSizeDescriptor); |
|
1066 test_KErrNone(r); |
|
1067 iMaxPacketSize = EpSize(endpointSizeDescriptor[KEpDesc_PacketSizeOffset], endpointSizeDescriptor[KEpDesc_PacketSizeOffset+1]); |
|
1068 test_Compare(iMaxPacketSize,>,0); |
|
1069 DEBUGPRINT(test.Printf(_L("Endpoint %d Max Packet Size = %d\n"), iEndpoint->GetEndpointNumber(), iMaxPacketSize)); |
|
1070 |
|
1071 if (iEndpoint->GetDirection() == KUsbScHdrEpDirectionOut) |
|
1072 { |
|
1073 if ((gSpecTest == EBufRead) || (gSpecTest == EAltSet)) |
|
1074 { |
|
1075 TUsbcScBufferRecord* buff = chunkHeader.GetBuffer(iEndpoint->GetAlternateSettingOfEndpoint(), iEndpoint->GetEndpointNumber(), epInfo); |
|
1076 test_NotNull(buff); |
|
1077 iHeader = (SUsbcScBufferHeader *) (buff->Offset() + iBase); |
|
1078 // To check instance of Alternate Setting Sequence Number |
|
1079 iTransfer = (TUsbcScTransferHeader*) (iHeader->iTail + iBase); |
|
1080 iMaxBufferSize = buff->Size(); |
|
1081 |
|
1082 if (gSpecTest == EBufRead) |
|
1083 test.Printf(_L("Reading from buffer %d \n On host side, on the Pipes Tab, please select endpoint %d and read from a file and send to pipe\n"), iBufNum, iEndpoint->GetEndpointNumber()); |
|
1084 iEndpoint->QueueRequests(); |
|
1085 } |
|
1086 } |
|
1087 |
|
1088 if (iEndpoint->GetDirection() == KUsbScHdrEpDirectionIn) |
|
1089 { |
|
1090 if ((gSpecTest == EBufWrite) || (gSpecTest == EAltSet)) |
|
1091 { |
|
1092 const char testString[] = "Hello, this is a test! Its not very exciting, but it does demonstrate if USBCSC can write to the IN endpoint. Please dont keep reading this file, if your expecting great works of litrature, for there will be none. To be honest, i'm not even sure why the test is going on this long with these insain ramballings. Never mind a! I guess at this point i think i should sum up by stateing that if you got this far, USBC probebly works to some degree. However really you need to see if it can write this lots of times. And i dont just mean this sentance, but the entire buffer. For a teat i'll sing you a song. Ten green bottles, Hanging on the wall, Ten green bottles, Hanging on the wall, And if one green bottle, Should accidentally fall, There'll be nine green bottles, Hanging on the wall. Nine green bottles, Hanging on the wall, Nine green bottles, Hanging on the wall, And if one green bottle, Should accidentally fall . . . you get the idea. Ok, I started by ramble by saying \""; |
|
1093 |
|
1094 TUsbcScBufferRecord* buff = chunkHeader.GetBuffer(iEndpoint->GetAlternateSettingOfEndpoint(), iEndpoint->GetEndpointNumber(), epInfo); |
|
1095 iBufferOffset = buff->Offset(); |
|
1096 iLength = buff->Size(); |
|
1097 |
|
1098 TUint8* buffer = (TUint8*) (iBufferOffset + iBase); |
|
1099 |
|
1100 TUint i; |
|
1101 TInt strPos=0; |
|
1102 for (i=0; i<iLength; i++, strPos++) |
|
1103 { |
|
1104 if (testString[strPos]==0) |
|
1105 strPos=0; |
|
1106 buffer[i]=testString[strPos]; |
|
1107 } |
|
1108 buffer[iLength-1] = '$'; |
|
1109 if (gSpecTest == EBufWrite) |
|
1110 test.Printf(_L("Writing from buffer %d \n On host side, on the Pipes Tab, please select endpoint %d and read from pipe and write to file \n"), iBufNum, iEndpoint->GetEndpointNumber()); |
|
1111 iEndpoint->QueueRequests(); |
|
1112 } |
|
1113 } |
|
1114 } |
|
1115 } |
|
1116 |
|
1117 TInt CActiveRW::StartRead() |
|
1118 { |
|
1119 TInt r = gPort.ReadDataNotify(iBuffer->iBufNum,iStatus); |
|
1120 return r; |
|
1121 } |
|
1122 |
|
1123 void CActiveRW::StartWrite() |
|
1124 { |
|
1125 // Test if starting address is aligned |
|
1126 test_Compare( ((iBuffer->iBufferOffset + iBuffer->iBase) % iBuffer->iMaxPacketSize), ==, 0); |
|
1127 gPort.WriteData(iBuffer->iBufNum, iBuffer->iBufferOffset, iBuffer->iLength, 0 /*flags*/ ,iStatus); |
|
1128 if (iStatus.Int() != KErrEof) |
|
1129 SetActive(); |
|
1130 } |
|
1131 |
|
1132 void CActiveRW::RunL() |
|
1133 { |
|
1134 DEBUGPRINT(test.Printf(_L("CActiveRW::RunL for Buffer number iBufNum %d AlternateSetting %d iDirection %d\n"), |
|
1135 iBuffer->iBufNum, iAltSetting->GetAlternateSetting(), iDirection)); |
|
1136 test_Compare(IsActive(), ==, EFalse); |
|
1137 if ((iLogicalEndpointNum == 0) || (iDirection == KUsbScHdrEpDirectionOut)) //RunL for ReadData |
|
1138 { |
|
1139 TInt r = 0; |
|
1140 do |
|
1141 { |
|
1142 iBuffer->ProcessData(); |
|
1143 if ((iBuffer->iBytesReceived > gBytesReceived) && (iBuffer->iHeader->iHead != iBuffer->iHeader->iTail)) |
|
1144 { |
|
1145 iBuffer->iBytesReceived = 0; |
|
1146 Deque(); |
|
1147 CActiveScheduler::Add(this); |
|
1148 SetActive(); |
|
1149 TRequestStatus *status = &iStatus; |
|
1150 User::RequestComplete(status, KErrNone); |
|
1151 return; |
|
1152 } |
|
1153 else if ((iAltSetting->GetAlternateSetting() == iBuffer->iTransfer->iAltSetting)) |
|
1154 { |
|
1155 if (!IsActive()) |
|
1156 r = StartRead(); |
|
1157 } |
|
1158 else if (iAltSetting->GetAlternateSetting() != iBuffer->iTransfer->iAltSetting) |
|
1159 { |
|
1160 return; |
|
1161 } |
|
1162 } while (r == KErrCompletion); |
|
1163 if (!IsActive()) |
|
1164 SetActive(); |
|
1165 } |
|
1166 else // RunL for WriteData |
|
1167 { |
|
1168 if (iStatus.Int() != KErrCancel) |
|
1169 { |
|
1170 test.Printf(_L("%c"), sym[iBuffer->iBufNum]); |
|
1171 StartWrite(); |
|
1172 } |
|
1173 } |
|
1174 } |
|
1175 |
|
1176 void TBuffer::ProcessData() |
|
1177 { |
|
1178 test_Compare(iOldTail, != , iHeader->iTail); // Should progress every time arroud the loop. |
|
1179 iOldTail = iHeader->iTail; |
|
1180 |
|
1181 DEBUGPRINT(test.Printf(_L("iHeader->iTail 0x%x, iHeader->iHead 0x%x \n"), iHeader->iTail, iHeader->iHead)); |
|
1182 if (iHeader->iTail == iHeader->iHead) |
|
1183 { |
|
1184 test.Printf(_L("No data after available, but returned. iHead 0x%x \n"),iHeader->iHead); |
|
1185 test(0); |
|
1186 } |
|
1187 |
|
1188 iTransfer = (TUsbcScTransferHeader*) (iHeader->iTail + iBase); |
|
1189 |
|
1190 if (iTransfer->iBytes > 0) |
|
1191 { |
|
1192 |
|
1193 if (iEndpoint->GetEndpointNumber() == 0) // We have to respond to Control requests. |
|
1194 { |
|
1195 if (iEp0Phase==EDataIn) |
|
1196 { |
|
1197 iEp0Phase=EReady; |
|
1198 gPort.SendEp0StatusPacket(); |
|
1199 if (iTransfer->iBytes) {test.Printf(_L("EP0 Data: "));} |
|
1200 for (TUint ii=0; ii<iTransfer->iBytes; ii++) |
|
1201 test.Printf(_L(" 0x%2x "),iTransfer->iData.b[ii]); |
|
1202 test.Printf(_L("\n\n")); |
|
1203 } |
|
1204 else |
|
1205 { |
|
1206 if (iTransfer->iFlags&KUsbcScStateChange) |
|
1207 { |
|
1208 TInt s = *iTransfer->iData.i; |
|
1209 test.Printf(_L("STATE CHANGE! %d : %S \n"),s,((s<0) || (s>7))?KStates[8]:KStates[s]); |
|
1210 } |
|
1211 else |
|
1212 { |
|
1213 iSetup = (Sep0SetupPacket* ) iTransfer->iData.b; |
|
1214 test.Printf(_L("EP0 Command: t %x r %x v %x i %x l %x :"), iSetup->iRequestType, iSetup->iRequest, iSetup->iwValue, iSetup->iwIndex, iSetup->iWlength); |
|
1215 if ((iSetup->iRequestType&KDeviceToHost))// && (iSetup->iWlength>0)) //Temp To do remove |
|
1216 { |
|
1217 test.Printf(_L("EP0 Command: Device to Host\n")); |
|
1218 SendEP0Packet(iSetup->iWlength); |
|
1219 } |
|
1220 else |
|
1221 { |
|
1222 test.Printf(_L("EP0 Command: Host to Device. 0x%x bytes\n"), iSetup->iWlength); |
|
1223 iEp0Phase=EDataIn; |
|
1224 } |
|
1225 } |
|
1226 } // end EP0 phase |
|
1227 } // iLogicalEndpointNum = 0 |
|
1228 else // else, its not ep0 |
|
1229 { |
|
1230 if ((++iTickCount)>100) |
|
1231 { |
|
1232 test.Printf(_L("%c"), sym[iBufNum]); |
|
1233 iTickCount=0; |
|
1234 } |
|
1235 } |
|
1236 } // end if data |
|
1237 else |
|
1238 { |
|
1239 test.Printf(_L("Empty Transfer received for buffer Num = %d as = %d\n"), iBufNum, iTransfer->iAltSetting); |
|
1240 if (iPrevAltSeq >= iTransfer->iAltSettingSeq) |
|
1241 { |
|
1242 test.Printf(_L("Empty Transfer *WAS NOT* an alt setting change!\n")); |
|
1243 iPrevAltSeq = iTransfer->iAltSettingSeq; |
|
1244 } |
|
1245 } |
|
1246 |
|
1247 //Checking Transfer Header contents |
|
1248 //Checking if Alternate Setting has changed |
|
1249 if ((iTransfer->iBytes == 0) && (iEndpoint->GetInterfaceAltSettingChangeSequenceNum() != iTransfer->iAltSettingSeq)) |
|
1250 { |
|
1251 DEBUGPRINT(test.Printf(_L("Current Alternate Setting of Endpoint = %d iTransfer->iAltSetting = %d iTransfer->iAltSettingSeq = %d \n"), |
|
1252 iEndpoint->GetAlternateSettingOfEndpoint(), iTransfer->iAltSetting, iTransfer->iAltSettingSeq)); |
|
1253 test.Printf(_L("Empty Transfer received for buffer Num = %d \n"), iBufNum); |
|
1254 test_Compare(iEndpoint->GetInterfaceAltSettingChangeSequenceNum(), +1== , iTransfer->iAltSettingSeq); |
|
1255 |
|
1256 |
|
1257 #if _DEBUG |
|
1258 // checking Sequence Numbers are in order i.e. One more than previous, Should enter this loop only the first time the buffer is ever used |
|
1259 if (iLoop == 0) |
|
1260 { |
|
1261 iPrevSequence = iTransfer->iSequence - 1; |
|
1262 iLoop++; |
|
1263 } |
|
1264 test_Compare((iTransfer->iSequence - iPrevSequence), ==, 1); |
|
1265 iPrevSequence = iTransfer->iSequence; |
|
1266 #endif |
|
1267 |
|
1268 iHeader->iTail = iTransfer->iNext; |
|
1269 iHeader->iBilTail = iTransfer->iNext; |
|
1270 |
|
1271 test_Equal(iTransfer->iFlags&KUsbcScStateChange, 0) |
|
1272 |
|
1273 //The following function call Sets the alternate setting change request flag to true |
|
1274 iEndpoint->SetChangeRequestFlag(this); |
|
1275 |
|
1276 //Function checks if alternate setting change request flag for all endpoints of this Alternate Setting is set to true |
|
1277 TBool settingRequestReceivedForAllEps = iEndpoint->CheckFlagForAllOutEndpoints(); |
|
1278 DEBUGPRINT(test.Printf(_L("SettingRequestReceivedForAllEps = %d \n"),settingRequestReceivedForAllEps)); |
|
1279 if(settingRequestReceivedForAllEps) |
|
1280 { |
|
1281 // change alternative setting |
|
1282 test.Printf(_L("AS!\n")); |
|
1283 iEndpoint->CallChangeAlternateSetting(iTransfer->iAltSetting); |
|
1284 } |
|
1285 } |
|
1286 else |
|
1287 { |
|
1288 // Checking if Data does not overlap chunk offset of the next transfer to be extracted |
|
1289 TUint startOfBuf=(TUint) &(iHeader->iBilTail) +sizeof(TUint) - (TUint)gChunk.Base(); |
|
1290 |
|
1291 if (iTransfer->iNext > TUint (iHeader->iTail)) |
|
1292 { |
|
1293 test_Compare(&(iTransfer->iData.b[iTransfer->iBytes - 1]), <=, (TUint8*) (iBase + iTransfer->iNext)); |
|
1294 } |
|
1295 else |
|
1296 { |
|
1297 test_Compare((TInt) (iTransfer->iNext), >=, startOfBuf ); |
|
1298 DEBUGPRINT(test.Printf(_L("Endpoint Buffer of size %d is filled. Next transfer from Start of Buffer \n"), iMaxBufferSize)); |
|
1299 } |
|
1300 |
|
1301 //Checking that no data or information goes beyond the end address of the buffer |
|
1302 test_Compare(iTransfer->iNext + (TUint) iBase, <, (TUint) iHeader + iMaxBufferSize); |
|
1303 test_Compare(&(iTransfer->iData.b[iTransfer->iBytes - 1]), <=, (TUint) iHeader + iMaxBufferSize); |
|
1304 |
|
1305 // Checking if data is aligned to iMaxPacketSize, except EP0 as data not DMA'd for EP0 |
|
1306 if (iEndpoint->GetEndpointNumber() != 0) |
|
1307 test_Compare(((TUint) (iTransfer->iData.b) % iMaxPacketSize), ==, 0); |
|
1308 |
|
1309 #if _DEBUG |
|
1310 // checking Sequence Numbers are in order i.e. One more than previous |
|
1311 if (iLoop == 0) |
|
1312 { |
|
1313 iPrevSequence = iTransfer->iSequence - 1; |
|
1314 iLoop++; |
|
1315 |
|
1316 // Checking if first transfer greater than or equal to the lowest chunk offset a transfer can be |
|
1317 test_Compare(iHeader->iTail, >=, startOfBuf); |
|
1318 } |
|
1319 DEBUGPRINT(test.Printf(_L("Previous Sequence Number 0x%x Current Sequence Number 0x%x \n"), iPrevSequence, iTransfer->iSequence)); |
|
1320 test_Compare((iTransfer->iSequence - iPrevSequence), ==, 1); |
|
1321 iPrevSequence = iTransfer->iSequence; |
|
1322 #endif |
|
1323 |
|
1324 if (gVerbose) |
|
1325 { |
|
1326 #if _DEBUG |
|
1327 //Print transfer contents |
|
1328 test.Printf(_L("Recieved packet Hash ID 0x%x Sequence Number 0x%x Bytes 0x%x Flags 0x%x Next 0x%x Alternate Setting Seq 0x%x Current Alternate Setting 0x%x \n"), |
|
1329 iTransfer->iHashId,iTransfer->iSequence, iTransfer->iBytes, iTransfer->iFlags, iTransfer->iNext, |
|
1330 iTransfer->iAltSettingSeq, iTransfer->iAltSetting); |
|
1331 #else |
|
1332 test.Printf(_L("Recieved packet Bytes 0x%x Flags 0x%x Next 0x%x Alternate Setting Seq 0x%x Current Alternate Setting 0x%x \n"), |
|
1333 iTransfer->iBytes, iTransfer->iFlags, |
|
1334 iTransfer->iNext, iTransfer->iAltSettingSeq, iTransfer->iAltSetting ); |
|
1335 #endif |
|
1336 if (gVerbose>1) |
|
1337 { |
|
1338 for (TUint ii=0; ii<iTransfer->iBytes; ii++) |
|
1339 { |
|
1340 test.Printf(_L(" %c "),iTransfer->iData.b[ii]); |
|
1341 } |
|
1342 test.Printf(_L("\n")); |
|
1343 } |
|
1344 } // if verbose |
|
1345 |
|
1346 iBytesReceived += iTransfer->iBytes; |
|
1347 iHeader->iTail = iTransfer->iNext; |
|
1348 iHeader->iBilTail = iTransfer->iNext; |
|
1349 } // if not alternate setting change |
|
1350 } |
|
1351 |
|
1352 static void TestCancel() |
|
1353 { |
|
1354 test.Start(_L("Testing Read and Write Cancel API's \n")); |
|
1355 LoadDriver(); |
|
1356 OpenChannel(); |
|
1357 |
|
1358 TInt r; |
|
1359 r = SettingOne(0); |
|
1360 test_KErrNone(r); |
|
1361 r = gPort.RealizeInterface(gChunk); |
|
1362 test_KErrNone(r); |
|
1363 |
|
1364 const TInt timeOut = 5000; //5 millisec |
|
1365 TUsbcScChunkHeader chunkHeader(gChunk); |
|
1366 |
|
1367 TUint base = (TUint) gChunk.Base(); |
|
1368 TUsbcScHdrEndpointRecord* epInfo; |
|
1369 TRequestStatus status; |
|
1370 |
|
1371 test.Next(_L("ReadCancel Test before enumeration\n")); |
|
1372 |
|
1373 TUsbcScTransferHeader* transfer; |
|
1374 SUsbcScBufferHeader* header; |
|
1375 header = (SUsbcScBufferHeader *) (chunkHeader.GetBuffer(0, 2, epInfo)->Offset() + base); |
|
1376 TInt outBuffNum = epInfo->iBufferNo; |
|
1377 |
|
1378 r = gPort.ReadDataNotify(outBuffNum,status); |
|
1379 test_Equal(r, KErrUsbInterfaceNotReady); |
|
1380 |
|
1381 test.Next(_L("WriteCancel Test before enumeration")); |
|
1382 TUsbcScBufferRecord* buff = chunkHeader.GetBuffer(0, 1, epInfo); |
|
1383 TInt inBuffNum = epInfo->iBufferNo; |
|
1384 TUint bufferOffset = buff->Offset(); |
|
1385 TUint length = buff->Size(); |
|
1386 TUint8* buffer = (TUint8*) (bufferOffset + base); |
|
1387 |
|
1388 gPort.WriteData(inBuffNum, bufferOffset, length, 1, status); |
|
1389 test_KErrNone(WaitUntilTimeout(timeOut, status)); |
|
1390 test_Equal(KErrUsbInterfaceNotReady, status.Int()); |
|
1391 |
|
1392 if (gRealHardware) |
|
1393 { |
|
1394 test.Printf(_L("\n\n Trying hardware\nPlease start the Host side application...\n")); |
|
1395 |
|
1396 |
|
1397 gPort.ReEnumerate(status); |
|
1398 User::WaitForRequest(status); |
|
1399 test.Printf(_L("Enumerated status = %d\n"), status.Int()); |
|
1400 |
|
1401 test.Next(_L("ReadCancel Test after enumeration\n")); |
|
1402 do // Drain out all data in buffer first, then queue cancel |
|
1403 { |
|
1404 r = gPort.ReadDataNotify(outBuffNum,status); |
|
1405 DEBUGPRINT(test.Printf(_L("header->iTail 0x%x header->iHead 0x%x\n"), header->iTail, header->iHead)); |
|
1406 transfer = (TUsbcScTransferHeader*) (header->iTail + base); |
|
1407 header->iTail = transfer->iNext; |
|
1408 } |
|
1409 while (r != KErrNone); |
|
1410 |
|
1411 gPort.ReadCancel(outBuffNum); |
|
1412 test_KErrNone(WaitUntilTimeout(timeOut, status)); |
|
1413 |
|
1414 test_Equal(status.Int(), KErrCancel); |
|
1415 |
|
1416 test.Next(_L("WriteCancel Test after enumeration\n")); |
|
1417 |
|
1418 test.Printf(_L("Generating test data %x %d\n"), buffer, inBuffNum); |
|
1419 for (TUint i=0; i<length; i++) |
|
1420 { |
|
1421 buffer[i]=i; |
|
1422 } |
|
1423 buffer[length-1] = '$'; |
|
1424 |
|
1425 gPort.WriteData(inBuffNum, bufferOffset, length, 1, status); |
|
1426 gPort.WriteCancel(inBuffNum); |
|
1427 test_KErrNone(WaitUntilTimeout(timeOut, status)); |
|
1428 test_Equal(status.Int(), KErrCancel); |
|
1429 |
|
1430 }//grealhardware |
|
1431 |
|
1432 CloseChannel(); |
|
1433 UnloadDriver(); |
|
1434 |
|
1435 test.End(); |
|
1436 } |
|
1437 |
|
1438 static void TestInvalidAPI() |
|
1439 { |
|
1440 TInt altSetNo = 0; |
|
1441 test.Start(_L("Test Invalid Reading and Writing API calls \n")); |
|
1442 LoadDriver(); |
|
1443 OpenChannel(); |
|
1444 TInt r = SettingTwo(altSetNo); |
|
1445 test_KErrNone(r); |
|
1446 |
|
1447 r = gPort.RealizeInterface(gChunk); |
|
1448 test_KErrNone(r); |
|
1449 |
|
1450 TInt out_buf = 0; |
|
1451 TInt in_buf = 0; |
|
1452 TInt in_ep = 0; |
|
1453 |
|
1454 TUsbcScChunkHeader chunkHeader(gChunk); |
|
1455 |
|
1456 for (TInt i = 0; i < chunkHeader.iAltSettings->iNumOfAltSettings; i++) |
|
1457 { |
|
1458 TInt8* endpoint = (TInt8*) (chunkHeader.iAltSettings->iAltTableOffset[i] + (TInt) gChunk.Base()); |
|
1459 for (TInt j = 1; j <= chunkHeader.GetNumberOfEndpoints(i); j++) |
|
1460 { |
|
1461 TUsbcScHdrEndpointRecord* endpointInf = (TUsbcScHdrEndpointRecord*) &(endpoint[j * chunkHeader.iAltSettings->iEpRecordSize]); |
|
1462 if (endpointInf->Direction() == KUsbScHdrEpDirectionOut) |
|
1463 { |
|
1464 out_buf = endpointInf->iBufferNo; |
|
1465 } |
|
1466 else |
|
1467 { |
|
1468 in_ep = j; |
|
1469 in_buf = endpointInf->iBufferNo; |
|
1470 } |
|
1471 } |
|
1472 } |
|
1473 |
|
1474 |
|
1475 test.Next(_L("Test invalid parameters to ReadDataNotify API \n")); |
|
1476 TRequestStatus status; |
|
1477 |
|
1478 r = gPort.ReadDataNotify(in_buf,status); |
|
1479 test_Compare(r, ==, KErrNotSupported); |
|
1480 |
|
1481 r = gPort.ReadDataNotify(KMaxEndpointsPerClient + 1,status); // Any number greater than max num of ep's for an Alt set |
|
1482 test_Compare(r, ==, KErrArgument); |
|
1483 |
|
1484 r = gPort.ReadDataNotify(-2,status); // Negative Number |
|
1485 test_Compare(r, ==, KErrArgument); |
|
1486 |
|
1487 test.Next(_L("Test Invalid parameters to WriteData API \n")); |
|
1488 |
|
1489 TUsbcScHdrEndpointRecord* epInfo; |
|
1490 |
|
1491 TUsbcScBufferRecord* buff = chunkHeader.GetBuffer(0, in_ep, epInfo); |
|
1492 TUint bufferOffset = buff->Offset(); |
|
1493 TUint length = buff->Size(); |
|
1494 |
|
1495 // Testing with invalid buffer values |
|
1496 test.Printf(_L("Test Buffer Writing with invalid buffer values\n")); |
|
1497 gPort.WriteData(out_buf, bufferOffset, length, 0, status); |
|
1498 User::WaitForRequest(status); |
|
1499 test_Compare(status.Int(), ==, KErrArgument); |
|
1500 |
|
1501 gPort.WriteData(KMaxEndpointsPerClient + 1, bufferOffset, length, 0, status); |
|
1502 User::WaitForRequest(status); |
|
1503 test_Compare(status.Int(), ==, KErrArgument); |
|
1504 |
|
1505 gPort.WriteData(-3, bufferOffset, length, 0,status); |
|
1506 User::WaitForRequest(status); |
|
1507 test_Compare(status.Int(), ==, KErrArgument); |
|
1508 /* |
|
1509 // Unaligned argument |
|
1510 test.Printf(_L("Test Buffer Writing with invalid buffer offsets\n")); |
|
1511 gPort.WriteData(in_buf, bufferOffset + sizeof(TUint), length, 0,status); |
|
1512 User::WaitForRequest(status); |
|
1513 test_Compare(status.Int(), ==, KErrArgument); |
|
1514 */ |
|
1515 //Offset passed is greater than end offset |
|
1516 gPort.WriteData(in_buf, (bufferOffset + length + 4), length, 0,status); |
|
1517 User::WaitForRequest(status); |
|
1518 test_Compare(status.Int(), ==, KErrArgument); |
|
1519 |
|
1520 //Length greater than buffer size |
|
1521 gPort.WriteData(in_buf, bufferOffset, (length + sizeof (TUint) * 3), 0,status); |
|
1522 User::WaitForRequest(status); |
|
1523 test_Compare(status.Int(), ==, KErrArgument); |
|
1524 |
|
1525 CloseChannel(); |
|
1526 UnloadDriver(); |
|
1527 |
|
1528 test.End(); |
|
1529 } |
|
1530 |
|
1531 static void TestSetInterface() |
|
1532 { |
|
1533 test.Start(_L("Test chunk's construction and clean up for various interface setting Configurations \n")); |
|
1534 TInt r; |
|
1535 TAltSetConfig *altSetConfig = new TAltSetConfig; |
|
1536 TInt altSetNo = 0; |
|
1537 __KHEAP_MARK; |
|
1538 //1 - This test is to see if chunk is populated correctly (Default Setting), - It is |
|
1539 //2 - Test Release Interface |
|
1540 //3 - Test Set and Release Interface after Realize Interface |
|
1541 test.Next(_L("Check if chunk is populated correctly with One Setting with two endpoints\n")); |
|
1542 LoadDriver(); |
|
1543 OpenChannel(); |
|
1544 |
|
1545 r = SettingOne(altSetNo); |
|
1546 test_KErrNone(r); |
|
1547 r = SettingOne(++altSetNo); |
|
1548 test_KErrNone(r); |
|
1549 |
|
1550 test.Printf(_L("Release Interface %d\n"), --altSetNo); |
|
1551 r = gPort.ReleaseInterface(altSetNo); |
|
1552 test_Compare(r, !=, KErrNone); |
|
1553 |
|
1554 test.Printf(_L("Release Interface %d\n"), ++altSetNo); |
|
1555 r = gPort.ReleaseInterface(altSetNo); |
|
1556 test_KErrNone(r); |
|
1557 |
|
1558 altSetConfig->iNumOfAltSet = 1; |
|
1559 TEndpointDescription temp = {2,1,1}; |
|
1560 altSetConfig->iEpsDesc[0] = temp; //{2,1,1}; |
|
1561 |
|
1562 TestBufferConstruction(altSetConfig); // Should have only one AltSet |
|
1563 |
|
1564 // Should not be be able to set interface once chunk realized |
|
1565 r = SettingOne(altSetNo); |
|
1566 test_Compare(r, ==, KErrUsbAlreadyRealized); |
|
1567 |
|
1568 // Should not be allowed to release Interface once Chunk Realized |
|
1569 test.Printf(_L("Release Interface %d \n"), altSetNo); |
|
1570 r = gPort.ReleaseInterface(altSetNo); |
|
1571 test_Compare(r, ==, KErrUsbAlreadyRealized); |
|
1572 CloseChannel(); |
|
1573 UnloadDriver(); |
|
1574 |
|
1575 //1 - Test if chunk constructed correctly with two Alternate Settings |
|
1576 //2 - If Realize Interface is called twice driver doesn not unload properly. |
|
1577 //3 - Multiple channels opened simultaneously also faults. |
|
1578 test.Next(_L("Check if chunk is populated correctly with Two Settings with two endpoints each \n")); |
|
1579 |
|
1580 LoadDriver(); |
|
1581 OpenChannel(); |
|
1582 |
|
1583 r = SettingOne(--altSetNo); |
|
1584 test_KErrNone(r); |
|
1585 |
|
1586 r = SettingOne(++altSetNo); |
|
1587 test_KErrNone(r); |
|
1588 |
|
1589 altSetConfig->iNumOfAltSet = 2; |
|
1590 altSetConfig->iEpsDesc[0] = temp; //{2,1,1}; |
|
1591 altSetConfig->iEpsDesc[1] = temp; //{2,1,1}; |
|
1592 |
|
1593 TestBufferConstruction(altSetConfig); |
|
1594 |
|
1595 RChunk tmpChunk; |
|
1596 r = gPort.RealizeInterface(tmpChunk); //TO do Uncomment to test Realize interface call twice |
|
1597 test_Equal(KErrUsbAlreadyRealized, r); |
|
1598 |
|
1599 CloseChannel(); |
|
1600 TestMultipleChannels(); |
|
1601 UnloadDriver(); |
|
1602 |
|
1603 test.Next(_L("Check if chunk is populated correctly with 2 settings, first setting with two endpoints and second with five endpoints \n")); |
|
1604 LoadDriver(); |
|
1605 OpenChannel(); |
|
1606 |
|
1607 altSetNo = 0; |
|
1608 r = SettingOne(altSetNo); |
|
1609 test_KErrNone(r); |
|
1610 altSetNo++; |
|
1611 r = SettingTwo(altSetNo); |
|
1612 test_KErrNone(r); |
|
1613 |
|
1614 altSetConfig->iNumOfAltSet = 2; |
|
1615 altSetConfig->iEpsDesc[0] = temp; //{2,1,1}; |
|
1616 TEndpointDescription temp1 = {5,4,1}; |
|
1617 altSetConfig->iEpsDesc[1] = temp1; //{5,4,1}; |
|
1618 |
|
1619 TestBufferConstruction(altSetConfig); |
|
1620 |
|
1621 CloseChannel(); |
|
1622 UnloadDriver(); |
|
1623 |
|
1624 |
|
1625 test.Next(_L("Test SetInterface with Dodgy alternate setting - Check if destructors Cleaning up properly \n")); |
|
1626 |
|
1627 LoadDriver(); |
|
1628 OpenChannel(); |
|
1629 |
|
1630 altSetNo = 0; |
|
1631 r = SettingOne(altSetNo); |
|
1632 test_KErrNone(r); |
|
1633 altSetNo++; |
|
1634 r = InvalidSettingOne(altSetNo); |
|
1635 test_Compare(r, !=, KErrNone); |
|
1636 |
|
1637 altSetConfig->iNumOfAltSet = 1; |
|
1638 altSetConfig->iEpsDesc[0] = temp; //{2,1,1}; |
|
1639 |
|
1640 test.Printf(_L("Check chunk still populated with one interface\n")); |
|
1641 TestBufferConstruction(altSetConfig); |
|
1642 |
|
1643 CloseChannel(); |
|
1644 UnloadDriver(); |
|
1645 |
|
1646 test.Next(_L("Test SetInterface with invalid alternate setting \n")); |
|
1647 |
|
1648 LoadDriver(); |
|
1649 OpenChannel(); |
|
1650 |
|
1651 altSetNo = 0; |
|
1652 r = SettingOne(altSetNo); |
|
1653 test_KErrNone(r); |
|
1654 altSetNo++; |
|
1655 r = InvalidSettingTwo(altSetNo); |
|
1656 test_Compare(r, !=, KErrNone); |
|
1657 |
|
1658 test.Printf(_L("Check chunk still populated with one interface \n")); |
|
1659 TestBufferConstruction(altSetConfig); |
|
1660 |
|
1661 CloseChannel(); |
|
1662 UnloadDriver(); |
|
1663 |
|
1664 test.Next(_L("Test SetInterface with Number of endpoints much greater than maximum per client \n")); |
|
1665 LoadDriver(); |
|
1666 OpenChannel(); |
|
1667 altSetNo = 0; |
|
1668 r = InvalidSettingThree(altSetNo); |
|
1669 test(r != KErrNone); |
|
1670 |
|
1671 altSetConfig->iNumOfAltSet = 0; |
|
1672 TEndpointDescription temp2 = {0,0,0}; |
|
1673 altSetConfig->iEpsDesc[0] = temp2; //{0,0,0}; |
|
1674 |
|
1675 test.Printf(_L("Check chunk not populated with any valid data as all interfaces would be destroyed \n")); |
|
1676 TestBufferConstruction(altSetConfig); |
|
1677 |
|
1678 CloseChannel(); |
|
1679 UnloadDriver(); |
|
1680 test.Next(_L("Test Release Interface, No interface set but call Release interface and test Chunk construction \n")); |
|
1681 |
|
1682 LoadDriver(); |
|
1683 OpenChannel(); |
|
1684 |
|
1685 r = gPort.ReleaseInterface(1); |
|
1686 test_KErrNone(r); |
|
1687 |
|
1688 TestBufferConstruction(altSetConfig); |
|
1689 |
|
1690 CloseChannel(); |
|
1691 UnloadDriver(); |
|
1692 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)5000, 0); |
|
1693 __KHEAP_MARKEND; |
|
1694 test.Next(_L("Test Release Interface, Release all interfaces one by one \n")); |
|
1695 __KHEAP_MARK; |
|
1696 LoadDriver(); |
|
1697 OpenChannel(); |
|
1698 |
|
1699 r = SettingOne(altSetNo); |
|
1700 test_KErrNone(r); |
|
1701 r = SettingTwo(++altSetNo); |
|
1702 test_KErrNone(r); |
|
1703 |
|
1704 gPort.ReleaseInterface(1); |
|
1705 test_KErrNone(r); |
|
1706 |
|
1707 gPort.ReleaseInterface(0); |
|
1708 test_KErrNone(r); |
|
1709 |
|
1710 TestBufferConstruction(altSetConfig); |
|
1711 |
|
1712 CloseChannel(); |
|
1713 UnloadDriver(); |
|
1714 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)5000, 0); |
|
1715 __KHEAP_MARKEND; |
|
1716 delete altSetConfig; |
|
1717 test.End(); |
|
1718 } |
|
1719 |
|
1720 //This has to be called once atleast before testing reading and writing as global variables used for checking data alignment are set in this function |
|
1721 void CheckDeviceCapabilities() |
|
1722 { |
|
1723 // Device caps |
|
1724 test.Next(_L("Query USB device caps")); |
|
1725 TUsbDeviceCaps d_caps; |
|
1726 TInt r = gPort.DeviceCaps(d_caps); |
|
1727 test_KErrNone(r); |
|
1728 TInt numOfEndPoints = d_caps().iTotalEndpoints; |
|
1729 |
|
1730 // Global variable - we'll need this value later. |
|
1731 gSupportsHighSpeed = d_caps().iHighSpeed; |
|
1732 |
|
1733 test.Printf(_L("USB device capabilities:\n")); |
|
1734 test.Printf(_L("Number of endpoints: %d\n"), numOfEndPoints); |
|
1735 test.Printf(_L("Supports Software-Connect: %s\n"), |
|
1736 d_caps().iConnect ? _S("yes") : _S("no")); |
|
1737 test.Printf(_L("Device is Self-Powered: %s\n"), |
|
1738 d_caps().iSelfPowered ? _S("yes") : _S("no")); |
|
1739 test.Printf(_L("Supports Remote-Wakeup: %s\n"), |
|
1740 d_caps().iRemoteWakeup ? _S("yes") : _S("no")); |
|
1741 test.Printf(_L("Supports High-speed: %s\n"), |
|
1742 gSupportsHighSpeed ? _S("yes") : _S("no")); |
|
1743 test.Printf(_L("Supports unpowered cable detection: %s\n"), |
|
1744 (d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ? |
|
1745 _S("yes") : _S("no")); |
|
1746 |
|
1747 test_Compare(numOfEndPoints, >=, 2); |
|
1748 test.Printf(_L("(Device has sufficient endpoints.)\n")); |
|
1749 |
|
1750 // Endpoint caps |
|
1751 test.Next(_L("Query USB endpoint caps")); |
|
1752 TUsbcEndpointData data[KUsbcMaxEndpoints]; |
|
1753 TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data)); |
|
1754 r = gPort.EndpointCaps(dataptr); |
|
1755 test_KErrNone(r); |
|
1756 |
|
1757 test.Printf(_L("USB device endpoint capabilities:\n")); |
|
1758 |
|
1759 TInt dir; |
|
1760 for (TInt i = 0; i < numOfEndPoints; i++) |
|
1761 { |
|
1762 const TUsbcEndpointCaps* caps = &data[i].iCaps; |
|
1763 dir = caps->iTypesAndDir; |
|
1764 test.Printf(_L("Endpoint: SizeBf= 0x%08x Type/Dir= 0x%08x"), |
|
1765 caps->iSizes, dir); |
|
1766 |
|
1767 if (dir&KUsbEpDirIn) |
|
1768 test.Printf(_L(" In ")); |
|
1769 if (dir&KUsbEpDirOut) |
|
1770 test.Printf(_L(" Out")); |
|
1771 if (dir&KUsbEpDirBidirect) |
|
1772 test.Printf(_L(" Bi ")); |
|
1773 |
|
1774 if (dir&KUsbEpTypeControl) |
|
1775 { |
|
1776 test.Printf(_L(" Control")); |
|
1777 } |
|
1778 if (dir&KUsbEpTypeIsochronous) |
|
1779 { |
|
1780 test.Printf(_L(" Isochronus")); |
|
1781 } |
|
1782 if (dir&KUsbEpTypeBulk) |
|
1783 { |
|
1784 test.Printf(_L(" Bulk")); |
|
1785 } |
|
1786 if (dir&KUsbEpTypeInterrupt) |
|
1787 { |
|
1788 test.Printf(_L(" Interrupt")); |
|
1789 } |
|
1790 |
|
1791 test.Printf(_L("\n")); |
|
1792 |
|
1793 if (caps->iHighBandwidth) |
|
1794 { |
|
1795 // Must be HS Int or Iso ep |
|
1796 test(gSupportsHighSpeed); |
|
1797 test(caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpTypeInterrupt)); |
|
1798 } |
|
1799 |
|
1800 if ((dir&KUsbEpDirIn) && (dir&KUsbEpTypeInterrupt)) |
|
1801 gInterruptInEpFound++; |
|
1802 } |
|
1803 } |
|
1804 |
|
1805 |
|
1806 TInt SettingOne(TInt aAltSetNo) |
|
1807 { |
|
1808 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (S1)\n")); |
|
1809 TInt r; |
|
1810 TUsbcScInterfaceInfoBuf ifc; |
|
1811 // Endpoint 0 |
|
1812 ifc().iEndpointData[0].iType = KUsbEpTypeBulk; |
|
1813 ifc().iEndpointData[0].iDir = KUsbEpDirIn; |
|
1814 ifc().iEndpointData[0].iSize = KUsbEpSize64; |
|
1815 //Endpoint 1 |
|
1816 ifc().iEndpointData[1].iType = KUsbEpTypeBulk; |
|
1817 ifc().iEndpointData[1].iDir = KUsbEpDirOut; |
|
1818 ifc().iEndpointData[1].iSize = KUsbEpSize64; |
|
1819 |
|
1820 test.Printf(_L("RTEST: Setting up interface %d with two endpoints (s1)\n"), aAltSetNo); |
|
1821 _LIT16(string, "T_USBCSC Test Interface"); |
|
1822 ifc().iString = const_cast<TDesC16*>(&string); |
|
1823 ifc().iTotalEndpointsUsed = 2; |
|
1824 ifc().iClass.iClassNum = 0xff; |
|
1825 ifc().iClass.iSubClassNum = 0xff; |
|
1826 ifc().iClass.iProtocolNum = 0xff; |
|
1827 // Tell the driver that this setting is interested in Ep0 requests: |
|
1828 ifc().iFeatureWord |= 0; |
|
1829 |
|
1830 // Set up the interface. |
|
1831 r = gPort.SetInterface(aAltSetNo, ifc); |
|
1832 return r; |
|
1833 } |
|
1834 |
|
1835 TInt SettingTwo(TInt aAltSetNo) |
|
1836 { |
|
1837 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (S2)\n")); |
|
1838 TUsbcScInterfaceInfoBuf ifc; |
|
1839 TInt ep_found = 0; |
|
1840 if (gInterruptInEpFound) |
|
1841 { |
|
1842 ifc().iEndpointData[ep_found].iType = KUsbEpTypeInterrupt; |
|
1843 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
1844 if (gSupportsHighSpeed) |
|
1845 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1846 else |
|
1847 ifc().iEndpointData[ep_found].iSize = KUsbEpSize8; |
|
1848 ifc().iEndpointData[ep_found].iInterval = 5; |
|
1849 ++ep_found; |
|
1850 } |
|
1851 else |
|
1852 { |
|
1853 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1854 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
1855 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1856 ++ep_found; |
|
1857 } |
|
1858 |
|
1859 do |
|
1860 { |
|
1861 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1862 ifc().iEndpointData[ep_found].iDir = KUsbEpDirOut; |
|
1863 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1864 } while (++ep_found < 5); |
|
1865 |
|
1866 test.Printf(_L("Setting up interface %d with Five Endpoints (s2)\n"), aAltSetNo); |
|
1867 _LIT16(string, "T_USBSC API Test Interface"); |
|
1868 ifc().iString = const_cast<TDesC16*>(&string); |
|
1869 ifc().iTotalEndpointsUsed = ep_found; |
|
1870 ifc().iClass.iClassNum = 0x08; |
|
1871 ifc().iClass.iSubClassNum = 0x06; |
|
1872 ifc().iClass.iProtocolNum = 0x50; |
|
1873 ifc().iFeatureWord |= 0; |
|
1874 TInt r = gPort.SetInterface(aAltSetNo, ifc); |
|
1875 return r; |
|
1876 } |
|
1877 |
|
1878 TInt SettingThreeIn(TInt aAltSetNo) |
|
1879 { |
|
1880 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (S3)\n")); |
|
1881 TInt r; |
|
1882 TUsbcScInterfaceInfoBuf ifc; |
|
1883 TInt ep_found = 0; |
|
1884 do |
|
1885 { |
|
1886 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1887 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
1888 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1889 } while (++ep_found < 3); |
|
1890 |
|
1891 test.Printf(_L("Setting up interface %d with three Bulk In endpoints(s3)\n"), aAltSetNo); |
|
1892 _LIT16(string, "T_USBCSC Test Interface"); |
|
1893 ifc().iString = const_cast<TDesC16*>(&string); |
|
1894 ifc().iTotalEndpointsUsed = ep_found; |
|
1895 ifc().iClass.iClassNum = 0xff; |
|
1896 ifc().iClass.iSubClassNum = 0xff; |
|
1897 ifc().iClass.iProtocolNum = 0xff; |
|
1898 ifc().iFeatureWord |= 0; |
|
1899 // Set up the interface. |
|
1900 r = gPort.SetInterface(aAltSetNo, ifc); |
|
1901 return r; |
|
1902 } |
|
1903 |
|
1904 TInt SettingFourOut(TInt aAltSetNo) |
|
1905 { |
|
1906 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (S4)\n")); |
|
1907 TInt r; |
|
1908 TUsbcScInterfaceInfoBuf ifc; |
|
1909 TInt ep_found = 0; |
|
1910 do |
|
1911 { |
|
1912 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1913 ifc().iEndpointData[ep_found].iDir = KUsbEpDirOut; |
|
1914 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1915 } while (++ep_found < 3); |
|
1916 |
|
1917 test.Printf(_L("Setting up interface %d with three Bulk Out endpoints(s4)\n"), aAltSetNo); |
|
1918 _LIT16(string, "T_USBCSC Test Interface"); |
|
1919 ifc().iString = const_cast<TDesC16*>(&string); |
|
1920 ifc().iTotalEndpointsUsed = ep_found; |
|
1921 ifc().iClass.iClassNum = 0xff; |
|
1922 ifc().iClass.iSubClassNum = 0xff; |
|
1923 ifc().iClass.iProtocolNum = 0xff; |
|
1924 ifc().iFeatureWord |= 0; |
|
1925 // Set up the interface. |
|
1926 r = gPort.SetInterface(aAltSetNo, ifc); |
|
1927 return r; |
|
1928 } |
|
1929 |
|
1930 TInt SettingFive(TInt aAltSetNo) |
|
1931 { |
|
1932 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (S5)\n")); |
|
1933 TUsbcScInterfaceInfoBuf ifc; |
|
1934 TInt ep_found = 0; |
|
1935 if (gInterruptInEpFound) |
|
1936 { |
|
1937 ifc().iEndpointData[ep_found].iType = KUsbEpTypeInterrupt; |
|
1938 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
1939 if (gSupportsHighSpeed) |
|
1940 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1941 else |
|
1942 ifc().iEndpointData[ep_found].iSize = KUsbEpSize8; |
|
1943 ifc().iEndpointData[ep_found].iInterval = 5; |
|
1944 ifc().iEndpointData[ep_found].iExtra = 2; // 2 extra bytes for Audio Class EP descriptor |
|
1945 ++ep_found; |
|
1946 } |
|
1947 else |
|
1948 { |
|
1949 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1950 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
1951 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1952 ifc().iEndpointData[ep_found].iExtra = 2; // 2 extra bytes for Audio Class EP descriptor |
|
1953 ++ep_found; |
|
1954 } |
|
1955 |
|
1956 do |
|
1957 { |
|
1958 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1959 ifc().iEndpointData[ep_found].iDir = KUsbEpDirOut; |
|
1960 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1961 } while (++ep_found < 4); |
|
1962 |
|
1963 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
1964 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
1965 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
1966 |
|
1967 test.Printf(_L("Setting up interface %d with Five Endpoints(s5)\n"), aAltSetNo); |
|
1968 _LIT16(string, "T_USBSC API Test Interface"); |
|
1969 ifc().iString = const_cast<TDesC16*>(&string); |
|
1970 ifc().iTotalEndpointsUsed = ep_found; |
|
1971 ifc().iClass.iClassNum = 0x01; |
|
1972 ifc().iClass.iSubClassNum = 0x02; |
|
1973 ifc().iClass.iProtocolNum = 0x00; |
|
1974 ifc().iFeatureWord |= 0; |
|
1975 TInt r = gPort.SetInterface(aAltSetNo, ifc); |
|
1976 return r; |
|
1977 } |
|
1978 |
|
1979 TInt InvalidSettingOne(TInt aAltSetNo) // Invalid Interface - request more than what is available on device. |
|
1980 // This will not be a valid test on the current high speed platform as the size requested is not available |
|
1981 // and will however return with an error, not because we are requesting one more than what is available of an interrupt endpoint |
|
1982 { |
|
1983 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (I1)\n")); |
|
1984 TUsbcScInterfaceInfoBuf ifc; |
|
1985 TInt interruptInEpFound = gInterruptInEpFound + 1; |
|
1986 |
|
1987 if (interruptInEpFound>KMaxEndpointsPerClient) |
|
1988 interruptInEpFound = KMaxEndpointsPerClient; |
|
1989 |
|
1990 for (TInt i = 0; i < interruptInEpFound; i++) |
|
1991 { |
|
1992 ifc().iEndpointData[i].iType = KUsbEpTypeInterrupt; |
|
1993 ifc().iEndpointData[i].iDir = KUsbEpDirIn; |
|
1994 ifc().iEndpointData[i].iSize = KUsbEpSize8; |
|
1995 ifc().iEndpointData[i].iInterval = 1; |
|
1996 } |
|
1997 |
|
1998 test.Next(_L("RTest: Setting up Erroneous Alternate interface, Endpoints already in use (I1)")); |
|
1999 _LIT16(string2, "T_USBSC API Test Interface"); |
|
2000 ifc().iString = const_cast<TDesC16*>(&string2); |
|
2001 ifc().iTotalEndpointsUsed = interruptInEpFound; |
|
2002 ifc().iClass.iClassNum = 0x01; |
|
2003 ifc().iClass.iSubClassNum = 0x02; |
|
2004 ifc().iClass.iProtocolNum = 0x00; |
|
2005 ifc().iFeatureWord |= 0; |
|
2006 // Set up the interface. |
|
2007 TInt r1 = gPort.SetInterface(aAltSetNo, ifc); |
|
2008 return r1; |
|
2009 } |
|
2010 |
|
2011 TInt InvalidSettingTwo(TInt aAltSetNo) //Invalid Setting by requesting an endpoint that is not available. |
|
2012 //Only control endpoints are bi-directional. Request any other type which has bidirectional capability. |
|
2013 { |
|
2014 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (I2)\n")); |
|
2015 |
|
2016 TUsbcScInterfaceInfoBuf ifc; |
|
2017 // Endpoint 0 |
|
2018 ifc().iEndpointData[0].iType = KUsbEpTypeInterrupt; |
|
2019 ifc().iEndpointData[0].iDir = KUsbEpDirIn; |
|
2020 ifc().iEndpointData[0].iSize = KUsbEpSize8; |
|
2021 //Endpoint 1 |
|
2022 ifc().iEndpointData[1].iType = KUsbEpTypeInterrupt; |
|
2023 ifc().iEndpointData[1].iDir = KUsbEpDirBidirect; |
|
2024 ifc().iEndpointData[1].iSize = KUsbEpSize8; |
|
2025 |
|
2026 test.Next(_L("Setting up Erroneous Alternate interface (2), Endpoint not available on device (I2)")); |
|
2027 _LIT16(string2, "T_USBSC API Test Interface"); |
|
2028 ifc().iString = const_cast<TDesC16*>(&string2); |
|
2029 ifc().iTotalEndpointsUsed = 2; |
|
2030 ifc().iClass.iClassNum = 0x01; |
|
2031 ifc().iClass.iSubClassNum = 0x02; |
|
2032 ifc().iClass.iProtocolNum = 0x00; |
|
2033 ifc().iFeatureWord |= 0; |
|
2034 // Set up the interface. |
|
2035 TInt r1 = gPort.SetInterface(aAltSetNo, ifc); |
|
2036 return r1; |
|
2037 } |
|
2038 |
|
2039 TInt InvalidSettingThree(TInt aAltSetNo) |
|
2040 { |
|
2041 test.Printf(_L("RTEST: Interigate Endpoint Capabilities (I3)\n")); |
|
2042 TInt r; |
|
2043 TUsbcScInterfaceInfoBuf ifc; |
|
2044 TInt ep_found = 0; |
|
2045 do |
|
2046 { |
|
2047 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
2048 ifc().iEndpointData[ep_found].iDir = KUsbEpDirIn; |
|
2049 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
2050 } while (++ep_found < 3); |
|
2051 do |
|
2052 { |
|
2053 ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk; |
|
2054 ifc().iEndpointData[ep_found].iDir = KUsbEpDirOut; |
|
2055 ifc().iEndpointData[ep_found].iSize = KUsbEpSize64; |
|
2056 } while (++ep_found < 5); |
|
2057 |
|
2058 test.Printf(_L("RTEST: Setting up interface %d, with invalid setting three (I3).\n"), aAltSetNo); |
|
2059 _LIT16(string, "T_USBCSC Test Interface"); |
|
2060 ifc().iString = const_cast<TDesC16*>(&string); |
|
2061 ifc().iTotalEndpointsUsed = ep_found+1; |
|
2062 ifc().iClass.iClassNum = 0x01; |
|
2063 ifc().iClass.iSubClassNum = 0x02; |
|
2064 ifc().iClass.iProtocolNum = 0x00; |
|
2065 ifc().iFeatureWord |= 0; |
|
2066 // Set up the interface. |
|
2067 r = gPort.SetInterface(aAltSetNo, ifc); |
|
2068 return r; |
|
2069 } |
|
2070 |
|
2071 static void TestDeviceDescriptor() |
|
2072 { |
|
2073 test.Start(_L("Device Descriptor Manipulation")); |
|
2074 |
|
2075 test.Next(_L("GetDeviceDescriptorSize()")); |
|
2076 TInt desc_size = 0; |
|
2077 gPort.GetDeviceDescriptorSize(desc_size); |
|
2078 test(static_cast<TUint>(desc_size) == KUsbDescSize_Device); |
|
2079 |
|
2080 test.Next(_L("GetDeviceDescriptor()")); |
|
2081 TBuf8<KUsbDescSize_Device> descriptor; |
|
2082 TInt r = gPort.GetDeviceDescriptor(descriptor); |
|
2083 test_KErrNone(r); |
|
2084 |
|
2085 test.Next(_L("SetDeviceDescriptor()")); |
|
2086 // Change the USB spec number to 2.00 |
|
2087 descriptor[KDevDesc_SpecOffset] = 0x00; |
|
2088 descriptor[KDevDesc_SpecOffset+1] = 0x02; |
|
2089 // Change the device vendor ID (VID) to 0x1234 |
|
2090 descriptor[KDevDesc_VendorIdOffset] = 0x22; // little endian |
|
2091 descriptor[KDevDesc_VendorIdOffset+1] = 0x0E; |
|
2092 // Change the device product ID (PID) to 0x1111 |
|
2093 descriptor[KDevDesc_ProductIdOffset] = 0x11; |
|
2094 descriptor[KDevDesc_ProductIdOffset+1] = 0x11; |
|
2095 // Change the device release number to 3.05 |
|
2096 descriptor[KDevDesc_DevReleaseOffset] = 0x05; |
|
2097 descriptor[KDevDesc_DevReleaseOffset+1] = 0x03; |
|
2098 r = gPort.SetDeviceDescriptor(descriptor); |
|
2099 test_KErrNone(r); |
|
2100 |
|
2101 test.Next(_L("GetDeviceDescriptor()")); |
|
2102 TBuf8<KUsbDescSize_Device> descriptor2; |
|
2103 r = gPort.GetDeviceDescriptor(descriptor2); |
|
2104 test_KErrNone(r); |
|
2105 |
|
2106 test.Next(_L("Compare device descriptor with value set")); |
|
2107 r = descriptor2.Compare(descriptor); |
|
2108 test_KErrNone(r); |
|
2109 |
|
2110 if (gSupportsHighSpeed) |
|
2111 { |
|
2112 // HS only allows one possible packet size. |
|
2113 test(descriptor[KDevDesc_Ep0SizeOffset] == 64); |
|
2114 } |
|
2115 |
|
2116 test.End(); |
|
2117 } |
|
2118 |
|
2119 |
|
2120 static void TestDeviceQualifierDescriptor() |
|
2121 { |
|
2122 test.Start(_L("Device_Qualifier Descriptor Manipulation")); |
|
2123 |
|
2124 if (!gSupportsHighSpeed) |
|
2125 { |
|
2126 test.Printf(_L("*** Not supported - skipping Device_Qualifier descriptor tests\n")); |
|
2127 test.End(); |
|
2128 return; |
|
2129 } |
|
2130 |
|
2131 test.Next(_L("GetDeviceQualifierDescriptor()")); |
|
2132 TBuf8<KUsbDescSize_DeviceQualifier> descriptor; |
|
2133 TInt r = gPort.GetDeviceQualifierDescriptor(descriptor); |
|
2134 test_KErrNone(r); |
|
2135 |
|
2136 test.Next(_L("SetDeviceQualifierDescriptor()")); |
|
2137 // Change the USB spec number to 3.00 |
|
2138 descriptor[KDevDesc_SpecOffset] = 0x00; |
|
2139 descriptor[KDevDesc_SpecOffset+1] = 0x03; |
|
2140 // Change the device class, subclass and protocol codes |
|
2141 descriptor[KDevDesc_DevClassOffset] = 0xA1; |
|
2142 descriptor[KDevDesc_DevSubClassOffset] = 0xB2; |
|
2143 descriptor[KDevDesc_DevProtocolOffset] = 0xC3; |
|
2144 r = gPort.SetDeviceQualifierDescriptor(descriptor); |
|
2145 test_KErrNone(r); |
|
2146 |
|
2147 test.Next(_L("GetDeviceQualifierDescriptor()")); |
|
2148 TBuf8<KUsbDescSize_DeviceQualifier> descriptor2; |
|
2149 r = gPort.GetDeviceQualifierDescriptor(descriptor2); |
|
2150 test_KErrNone(r); |
|
2151 |
|
2152 test.Next(_L("Compare Device_Qualifier desc with value set")); |
|
2153 r = descriptor2.Compare(descriptor); |
|
2154 test_KErrNone(r); |
|
2155 |
|
2156 test.End(); |
|
2157 } |
|
2158 |
|
2159 |
|
2160 static void TestConfigurationDescriptor() |
|
2161 { |
|
2162 test.Start(_L("Configuration Descriptor Manipulation")); |
|
2163 |
|
2164 test.Next(_L("GetConfigurationDescriptorSize()")); |
|
2165 TInt desc_size = 0; |
|
2166 gPort.GetConfigurationDescriptorSize(desc_size); |
|
2167 test(static_cast<TUint>(desc_size) == KUsbDescSize_Config); |
|
2168 |
|
2169 test.Next(_L("GetConfigurationDescriptor()")); |
|
2170 TBuf8<KUsbDescSize_Config> descriptor; |
|
2171 TInt r = gPort.GetConfigurationDescriptor(descriptor); |
|
2172 test_KErrNone(r); |
|
2173 |
|
2174 test.Next(_L("SetConfigurationDescriptor()")); |
|
2175 // Invert Remote-Wakup support |
|
2176 descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup); |
|
2177 // Change the reported max power to 200mA (2 * 0x64) |
|
2178 descriptor[KConfDesc_MaxPowerOffset] = 0x64; |
|
2179 r = gPort.SetConfigurationDescriptor(descriptor); |
|
2180 test_KErrNone(r); |
|
2181 |
|
2182 test.Next(_L("GetConfigurationDescriptor()")); |
|
2183 TBuf8<KUsbDescSize_Config> descriptor2; |
|
2184 r = gPort.GetConfigurationDescriptor(descriptor2); |
|
2185 test_KErrNone(r); |
|
2186 |
|
2187 test.Next(_L("Compare configuration desc with value set")); |
|
2188 r = descriptor2.Compare(descriptor); |
|
2189 test_KErrNone(r); |
|
2190 |
|
2191 test.End(); |
|
2192 } |
|
2193 |
|
2194 |
|
2195 static void TestOtherSpeedConfigurationDescriptor() |
|
2196 { |
|
2197 test.Start(_L("Other_Speed_Configuration Desc Manipulation")); |
|
2198 |
|
2199 if (!gSupportsHighSpeed) |
|
2200 { |
|
2201 test.Printf(_L("*** Not supported - skipping Other_Speed_Configuration desc tests\n")); |
|
2202 test.End(); |
|
2203 return; |
|
2204 } |
|
2205 |
|
2206 test.Next(_L("GetOtherSpeedConfigurationDescriptor()")); |
|
2207 TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor; |
|
2208 TInt r = gPort.GetOtherSpeedConfigurationDescriptor(descriptor); |
|
2209 test_KErrNone(r); |
|
2210 |
|
2211 test.Next(_L("SetOtherSpeedConfigurationDescriptor()")); |
|
2212 // Invert Remote-Wakup support |
|
2213 descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup); |
|
2214 // Change the reported max power to 330mA (2 * 0xA5) |
|
2215 descriptor[KConfDesc_MaxPowerOffset] = 0xA5; |
|
2216 r = gPort.SetOtherSpeedConfigurationDescriptor(descriptor); |
|
2217 test_KErrNone(r); |
|
2218 |
|
2219 test.Next(_L("GetOtherSpeedConfigurationDescriptor()")); |
|
2220 TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor2; |
|
2221 r = gPort.GetOtherSpeedConfigurationDescriptor(descriptor2); |
|
2222 test_KErrNone(r); |
|
2223 |
|
2224 test.Next(_L("Compare O_S_Config desc with value set")); |
|
2225 r = descriptor2.Compare(descriptor); |
|
2226 test_KErrNone(r); |
|
2227 |
|
2228 test.End(); |
|
2229 } |
|
2230 |
|
2231 |
|
2232 static void TestInterfaceDescriptor() |
|
2233 { |
|
2234 test.Start(_L("Interface Descriptor Manipulation")); |
|
2235 |
|
2236 // First the standard Interface descriptor |
|
2237 test.Next(_L("GetInterfaceDescriptorSize()")); |
|
2238 TInt desc_size = 0; |
|
2239 TInt r = gPort.GetInterfaceDescriptorSize(0, desc_size); |
|
2240 test_KErrNone(r); |
|
2241 test(static_cast<TUint>(desc_size) == KUsbDescSize_Interface); |
|
2242 |
|
2243 test.Next(_L("GetInterfaceDescriptor()")); |
|
2244 TBuf8<KUsbDescSize_Interface> descriptor; |
|
2245 r = gPort.GetInterfaceDescriptor(0, descriptor); |
|
2246 test_KErrNone(r); |
|
2247 |
|
2248 test.Next(_L("SetInterfaceDescriptor()")); |
|
2249 // Change the interface protocol to 0x78(+) |
|
2250 TUint8 prot = 0x78; |
|
2251 if (descriptor[KIfcDesc_ProtocolOffset] == prot) |
|
2252 prot++; |
|
2253 descriptor[KIfcDesc_ProtocolOffset] = prot; |
|
2254 r = gPort.SetInterfaceDescriptor(0, descriptor); |
|
2255 test_KErrNone(r); |
|
2256 |
|
2257 test.Next(_L("GetInterfaceDescriptor()")); |
|
2258 TBuf8<KUsbDescSize_Interface> descriptor2; |
|
2259 r = gPort.GetInterfaceDescriptor(0, descriptor2); |
|
2260 test_KErrNone(r); |
|
2261 |
|
2262 test.Next(_L("Compare interface descriptor with value set")); |
|
2263 r = descriptor2.Compare(descriptor); |
|
2264 test_KErrNone(r); |
|
2265 |
|
2266 test.End(); |
|
2267 } |
|
2268 |
|
2269 static void TestClassSpecificDescriptors() |
|
2270 { |
|
2271 test.Start(_L("Class-specific Descriptor Manipulation")); |
|
2272 |
|
2273 // First a class-specific Interface descriptor |
|
2274 test.Next(_L("SetCSInterfaceDescriptorBlock()")); |
|
2275 // choose arbitrary new descriptor size |
|
2276 const TInt KUsbDescSize_CS_Interface = KUsbDescSize_Interface + 10; |
|
2277 TBuf8<KUsbDescSize_CS_Interface> cs_ifc_descriptor; |
|
2278 cs_ifc_descriptor.FillZ(cs_ifc_descriptor.MaxLength()); |
|
2279 cs_ifc_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Interface; |
|
2280 cs_ifc_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Interface; |
|
2281 TInt r = gPort.SetCSInterfaceDescriptorBlock(0, cs_ifc_descriptor); |
|
2282 test_KErrNone(r); |
|
2283 |
|
2284 test.Next(_L("GetCSInterfaceDescriptorBlockSize()")); |
|
2285 TInt desc_size = 0; |
|
2286 r = gPort.GetCSInterfaceDescriptorBlockSize(0, desc_size); |
|
2287 test_KErrNone(r); |
|
2288 test(desc_size == KUsbDescSize_CS_Interface); |
|
2289 |
|
2290 test.Next(_L("GetCSInterfaceDescriptorBlock()")); |
|
2291 TBuf8<KUsbDescSize_CS_Interface> descriptor; |
|
2292 r = gPort.GetCSInterfaceDescriptorBlock(0, descriptor); |
|
2293 test_KErrNone(r); |
|
2294 |
|
2295 test.Next(_L("Compare CS ifc descriptor with value set")); |
|
2296 r = descriptor.Compare(cs_ifc_descriptor); |
|
2297 test_KErrNone(r); |
|
2298 |
|
2299 // Next a class-specific Endpoint descriptor |
|
2300 test.Next(_L("SetCSEndpointDescriptorBlock()")); |
|
2301 // choose arbitrary new descriptor size |
|
2302 const TInt KUsbDescSize_CS_Endpoint = KUsbDescSize_Endpoint + 5; |
|
2303 TBuf8<KUsbDescSize_CS_Endpoint> cs_ep_descriptor; |
|
2304 cs_ep_descriptor.FillZ(cs_ep_descriptor.MaxLength()); |
|
2305 cs_ep_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Endpoint; |
|
2306 cs_ep_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Endpoint; |
|
2307 r = gPort.SetCSEndpointDescriptorBlock(0, 2, cs_ep_descriptor); |
|
2308 test_KErrNone(r); |
|
2309 |
|
2310 test.Next(_L("GetCSEndpointDescriptorBlockSize()")); |
|
2311 r = gPort.GetCSEndpointDescriptorBlockSize(0, 2, desc_size); |
|
2312 test_KErrNone(r); |
|
2313 test(desc_size == KUsbDescSize_CS_Endpoint); |
|
2314 |
|
2315 test.Next(_L("GetCSEndpointDescriptorBlock()")); |
|
2316 TBuf8<KUsbDescSize_CS_Endpoint> descriptor2; |
|
2317 r = gPort.GetCSEndpointDescriptorBlock(0, 2, descriptor2); |
|
2318 test_KErrNone(r); |
|
2319 |
|
2320 test.Next(_L("Compare CS ep descriptor with value set")); |
|
2321 r = descriptor2.Compare(cs_ep_descriptor); |
|
2322 test_KErrNone(r); |
|
2323 |
|
2324 test.End(); |
|
2325 } |
|
2326 |
|
2327 static void TestAlternateInterfaceManipulation() |
|
2328 { |
|
2329 test.Start(_L("Alternate Interface Setting Manipulation")); |
|
2330 |
|
2331 if (!SupportsAlternateInterfaces()) |
|
2332 { |
|
2333 test.Printf(_L("*** Not supported - skipping alternate interface settings tests\n")); |
|
2334 test.End(); |
|
2335 return; |
|
2336 } |
|
2337 test_KErrNone(SettingFive(1)); |
|
2338 |
|
2339 TInt r; |
|
2340 test.Next(_L("Set alternate setting number to 8")); |
|
2341 TBuf8<KUsbDescSize_Interface> descriptor; |
|
2342 r = gPort.GetInterfaceDescriptor(1, descriptor); |
|
2343 test_KErrNone(r); |
|
2344 descriptor[KIfcDesc_SettingOffset] = 8; |
|
2345 r = gPort.SetInterfaceDescriptor(1, descriptor); |
|
2346 test(r != KErrNone); |
|
2347 |
|
2348 test.Next(_L("Change ifc # in def setting whith alt ifcs")); |
|
2349 r = gPort.GetInterfaceDescriptor(0, descriptor); |
|
2350 test_KErrNone(r); |
|
2351 descriptor[KIfcDesc_SettingOffset] = 8; |
|
2352 r = gPort.SetInterfaceDescriptor(0, descriptor); |
|
2353 test(r != KErrNone); |
|
2354 |
|
2355 test.Next(_L("Change the ifc # in default setting to 8")); |
|
2356 r = gPort.ReleaseInterface(1); |
|
2357 test_KErrNone(r); |
|
2358 r = gPort.SetInterfaceDescriptor(0, descriptor); |
|
2359 test_KErrNone(r); |
|
2360 |
|
2361 test.Next(_L("Create new setting - this should also get #8")); |
|
2362 test_KErrNone(SettingFive(1)); |
|
2363 |
|
2364 r = gPort.GetInterfaceDescriptor(1, descriptor); |
|
2365 test_KErrNone(r); |
|
2366 test(descriptor[KIfcDesc_SettingOffset] == 8); |
|
2367 |
|
2368 test.Next(_L("Change the ifc # in default setting to 0")); |
|
2369 r = gPort.ReleaseInterface(1); |
|
2370 test_KErrNone(r); |
|
2371 r = gPort.GetInterfaceDescriptor(0, descriptor); |
|
2372 test_KErrNone(r); |
|
2373 descriptor[KIfcDesc_SettingOffset] = 0; |
|
2374 r = gPort.SetInterfaceDescriptor(0, descriptor); |
|
2375 test_KErrNone(r); |
|
2376 |
|
2377 test.Next(_L("Create new setting - this should also get #0")); |
|
2378 test_KErrNone(SettingFive(1)); |
|
2379 |
|
2380 r = gPort.GetInterfaceDescriptor(1, descriptor); |
|
2381 test_KErrNone(r); |
|
2382 test(descriptor[KIfcDesc_SettingOffset] == 0); |
|
2383 |
|
2384 test.End(); |
|
2385 } |
|
2386 |
|
2387 static void TestEndpointDescriptor() |
|
2388 { |
|
2389 test.Start(_L("Endpoint Descriptor Manipulation")); |
|
2390 |
|
2391 test.Next(_L("GetEndpointDescriptorSize(1)")); |
|
2392 TInt epNumber = 1; |
|
2393 TInt desc_size = 0; |
|
2394 TInt r = gPort.GetEndpointDescriptorSize(0, epNumber, desc_size); |
|
2395 test_KErrNone(r); |
|
2396 test(static_cast<TUint>(desc_size) == KUsbDescSize_Endpoint); |
|
2397 |
|
2398 test.Next(_L("GetEndpointDescriptor(1)")); |
|
2399 TBuf8<KUsbDescSize_Endpoint> descriptor; |
|
2400 r = gPort.GetEndpointDescriptor(0, epNumber, descriptor); |
|
2401 test_KErrNone(r); |
|
2402 |
|
2403 test.Next(_L("SetEndpointDescriptor(1)")); |
|
2404 // Change the endpoint poll interval |
|
2405 TUint8 ival = 0x66; |
|
2406 if (descriptor[KEpDesc_IntervalOffset] == ival) |
|
2407 ival++; |
|
2408 descriptor[KEpDesc_IntervalOffset] = ival; |
|
2409 r = gPort.SetEndpointDescriptor(0, epNumber, descriptor); |
|
2410 test_KErrNone(r); |
|
2411 |
|
2412 test.Next(_L("GetEndpointDescriptor(1)")); |
|
2413 TBuf8<KUsbDescSize_Endpoint> descriptor2; |
|
2414 r = gPort.GetEndpointDescriptor(0, epNumber, descriptor2); |
|
2415 test_KErrNone(r); |
|
2416 |
|
2417 test.Next(_L("Compare endpoint descriptor with value set")); |
|
2418 r = descriptor2.Compare(descriptor); |
|
2419 test_KErrNone(r); |
|
2420 |
|
2421 test.End(); |
|
2422 } |
|
2423 |
|
2424 static void TestExtendedEndpointDescriptor() |
|
2425 { |
|
2426 test.Start(_L("Extended Endpoint Descriptor Manipulation")); |
|
2427 |
|
2428 if (!SupportsAlternateInterfaces()) |
|
2429 { |
|
2430 test.Printf(_L("*** Not supported - skipping Extended Endpoint descriptor tests\n")); |
|
2431 test.End(); |
|
2432 return; |
|
2433 } |
|
2434 |
|
2435 // Extended Endpoint Descriptor manipulation (Audio class endpoint) |
|
2436 test.Next(_L("GetEndpointDescriptorSize()")); |
|
2437 TInt epNumber = 1; // refering to first endpoint |
|
2438 TInt desc_size = 0; |
|
2439 TInt r = gPort.GetEndpointDescriptorSize(1, epNumber, desc_size); |
|
2440 test_KErrNone(r); |
|
2441 test(static_cast<TUint>(desc_size) == KUsbDescSize_AudioEndpoint); |
|
2442 |
|
2443 test.Next(_L("GetEndpointDescriptor()")); |
|
2444 TBuf8<KUsbDescSize_AudioEndpoint> descriptor; |
|
2445 r = gPort.GetEndpointDescriptor(1, epNumber, descriptor); |
|
2446 test_KErrNone(r); |
|
2447 |
|
2448 test.Next(_L("SetEndpointDescriptor()")); |
|
2449 // Change the Audio Endpoint bSynchAddress field |
|
2450 TUint8 addr = 0x85; // bogus address |
|
2451 if (descriptor[KEpDesc_SynchAddressOffset] == addr) |
|
2452 addr++; |
|
2453 descriptor[KEpDesc_SynchAddressOffset] = addr; |
|
2454 r = gPort.SetEndpointDescriptor(1, epNumber, descriptor); |
|
2455 test_KErrNone(r); |
|
2456 |
|
2457 test.Next(_L("GetEndpointDescriptor()")); |
|
2458 TBuf8<KUsbDescSize_AudioEndpoint> descriptor2; |
|
2459 r = gPort.GetEndpointDescriptor(1, epNumber, descriptor2); |
|
2460 test_KErrNone(r); |
|
2461 |
|
2462 test.Next(_L("Compare endpoint descriptor with value set")); |
|
2463 r = descriptor2.Compare(descriptor); |
|
2464 test_KErrNone(r); |
|
2465 |
|
2466 test.End(); |
|
2467 } |
|
2468 |
|
2469 |
|
2470 static void TestStandardStringDescriptors() |
|
2471 { |
|
2472 test.Start(_L("String Descriptor Manipulation")); |
|
2473 |
|
2474 // --- LANGID code |
|
2475 test.Next(_L("GetStringDescriptorLangId()")); |
|
2476 TUint16 rd_langid_orig; |
|
2477 TInt r = gPort.GetStringDescriptorLangId(rd_langid_orig); |
|
2478 test_KErrNone(r); |
|
2479 test.Printf(_L("Original LANGID code: 0x%04X\n"), rd_langid_orig); |
|
2480 |
|
2481 test.Next(_L("SetStringDescriptorLangId()")); |
|
2482 TUint16 wr_langid = 0x0809; // English (UK) Language ID |
|
2483 if (wr_langid == rd_langid_orig) |
|
2484 wr_langid = 0x0444; // Tatar Language ID |
|
2485 r = gPort.SetStringDescriptorLangId(wr_langid); |
|
2486 test_KErrNone(r); |
|
2487 |
|
2488 test.Next(_L("GetStringDescriptorLangId()")); |
|
2489 TUint16 rd_langid; |
|
2490 r = gPort.GetStringDescriptorLangId(rd_langid); |
|
2491 test_KErrNone(r); |
|
2492 test.Printf(_L("New LANGID code: 0x%04X\n"), rd_langid); |
|
2493 |
|
2494 test.Next(_L("Compare LANGID codes")); |
|
2495 test(rd_langid == wr_langid); |
|
2496 |
|
2497 test.Next(_L("Restore original LANGID code")); |
|
2498 r = gPort.SetStringDescriptorLangId(rd_langid_orig); |
|
2499 test_KErrNone(r); |
|
2500 r = gPort.GetStringDescriptorLangId(rd_langid); |
|
2501 test_KErrNone(r); |
|
2502 test(rd_langid == rd_langid_orig); |
|
2503 |
|
2504 // --- Manufacturer string |
|
2505 test.Next(_L("GetManufacturerStringDescriptor()")); |
|
2506 TBuf16<KUsbStringDescStringMaxSize / 2> rd_str_orig; |
|
2507 r = gPort.GetManufacturerStringDescriptor(rd_str_orig); |
|
2508 test(r == KErrNone || r == KErrNotFound); |
|
2509 TBool restore_string; |
|
2510 if (r == KErrNone) |
|
2511 { |
|
2512 test.Printf(_L("Original Manufacturer string: \"%lS\"\n"), &rd_str_orig); |
|
2513 restore_string = ETrue; |
|
2514 } |
|
2515 else |
|
2516 { |
|
2517 test.Printf(_L("No Manufacturer string set\n")); |
|
2518 restore_string = EFalse; |
|
2519 } |
|
2520 |
|
2521 test.Next(_L("SetManufacturerStringDescriptor()")); |
|
2522 _LIT16(manufacturer, "Manufacturer Which Manufactures Devices"); |
|
2523 TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(manufacturer); |
|
2524 r = gPort.SetManufacturerStringDescriptor(wr_str); |
|
2525 test_KErrNone(r); |
|
2526 |
|
2527 test.Next(_L("GetManufacturerStringDescriptor()")); |
|
2528 TBuf16<KUsbStringDescStringMaxSize / 2> rd_str; |
|
2529 r = gPort.GetManufacturerStringDescriptor(rd_str); |
|
2530 test_KErrNone(r); |
|
2531 test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str); |
|
2532 |
|
2533 test.Next(_L("Compare Manufacturer strings")); |
|
2534 r = rd_str.Compare(wr_str); |
|
2535 test_KErrNone(r); |
|
2536 |
|
2537 test.Next(_L("SetManufacturerStringDescriptor()")); |
|
2538 _LIT16(manufacturer2, "Different Manufacturer Which Manufactures Different Devices"); |
|
2539 wr_str.FillZ(wr_str.MaxLength()); |
|
2540 wr_str = manufacturer2; |
|
2541 r = gPort.SetManufacturerStringDescriptor(wr_str); |
|
2542 test_KErrNone(r); |
|
2543 |
|
2544 test.Next(_L("GetManufacturerStringDescriptor()")); |
|
2545 rd_str.FillZ(rd_str.MaxLength()); |
|
2546 r = gPort.GetManufacturerStringDescriptor(rd_str); |
|
2547 test_KErrNone(r); |
|
2548 test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str); |
|
2549 |
|
2550 test.Next(_L("Compare Manufacturer strings")); |
|
2551 r = rd_str.Compare(wr_str); |
|
2552 test_KErrNone(r); |
|
2553 |
|
2554 test.Next(_L("RemoveManufacturerStringDescriptor()")); |
|
2555 r = gPort.RemoveManufacturerStringDescriptor(); |
|
2556 test_KErrNone(r); |
|
2557 r = gPort.GetManufacturerStringDescriptor(rd_str); |
|
2558 test(r == KErrNotFound); |
|
2559 |
|
2560 if (restore_string) |
|
2561 { |
|
2562 test.Next(_L("Restore original string")); |
|
2563 r = gPort.SetManufacturerStringDescriptor(rd_str_orig); |
|
2564 test_KErrNone(r); |
|
2565 r = gPort.GetManufacturerStringDescriptor(rd_str); |
|
2566 test_KErrNone(r); |
|
2567 r = rd_str.Compare(rd_str_orig); |
|
2568 test_KErrNone(r); |
|
2569 } |
|
2570 |
|
2571 // --- Product string |
|
2572 test.Next(_L("GetProductStringDescriptor()")); |
|
2573 rd_str_orig.FillZ(rd_str.MaxLength()); |
|
2574 r = gPort.GetProductStringDescriptor(rd_str_orig); |
|
2575 test(r == KErrNone || r == KErrNotFound); |
|
2576 if (r == KErrNone) |
|
2577 { |
|
2578 test.Printf(_L("Old Product string: \"%lS\"\n"), &rd_str_orig); |
|
2579 restore_string = ETrue; |
|
2580 } |
|
2581 else |
|
2582 restore_string = EFalse; |
|
2583 |
|
2584 test.Next(_L("SetProductStringDescriptor()")); |
|
2585 _LIT16(product, "Product That Was Produced By A Manufacturer"); |
|
2586 wr_str.FillZ(wr_str.MaxLength()); |
|
2587 wr_str = product; |
|
2588 r = gPort.SetProductStringDescriptor(wr_str); |
|
2589 test_KErrNone(r); |
|
2590 |
|
2591 test.Next(_L("GetProductStringDescriptor()")); |
|
2592 rd_str.FillZ(rd_str.MaxLength()); |
|
2593 r = gPort.GetProductStringDescriptor(rd_str); |
|
2594 test_KErrNone(r); |
|
2595 test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str); |
|
2596 |
|
2597 test.Next(_L("Compare Product strings")); |
|
2598 r = rd_str.Compare(wr_str); |
|
2599 test_KErrNone(r); |
|
2600 |
|
2601 test.Next(_L("SetProductStringDescriptor()")); |
|
2602 _LIT16(product2, "Different Product That Was Produced By A Different Manufacturer"); |
|
2603 wr_str.FillZ(wr_str.MaxLength()); |
|
2604 wr_str = product2; |
|
2605 r = gPort.SetProductStringDescriptor(wr_str); |
|
2606 test_KErrNone(r); |
|
2607 |
|
2608 test.Next(_L("GetProductStringDescriptor()")); |
|
2609 rd_str.FillZ(rd_str.MaxLength()); |
|
2610 r = gPort.GetProductStringDescriptor(rd_str); |
|
2611 test_KErrNone(r); |
|
2612 test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str); |
|
2613 |
|
2614 test.Next(_L("Compare Product strings")); |
|
2615 r = rd_str.Compare(wr_str); |
|
2616 test_KErrNone(r); |
|
2617 |
|
2618 test.Next(_L("RemoveProductStringDescriptor()")); |
|
2619 r = gPort.RemoveProductStringDescriptor(); |
|
2620 test_KErrNone(r); |
|
2621 r = gPort.GetProductStringDescriptor(rd_str); |
|
2622 test(r == KErrNotFound); |
|
2623 |
|
2624 if (restore_string) |
|
2625 { |
|
2626 test.Next(_L("Restore original string")); |
|
2627 r = gPort.SetProductStringDescriptor(rd_str_orig); |
|
2628 test_KErrNone(r); |
|
2629 r = gPort.GetProductStringDescriptor(rd_str); |
|
2630 test_KErrNone(r); |
|
2631 r = rd_str.Compare(rd_str_orig); |
|
2632 test_KErrNone(r); |
|
2633 } |
|
2634 |
|
2635 // --- Serial Number string |
|
2636 test.Next(_L("GetSerialNumberStringDescriptor()")); |
|
2637 rd_str_orig.FillZ(rd_str.MaxLength()); |
|
2638 r = gPort.GetSerialNumberStringDescriptor(rd_str_orig); |
|
2639 test(r == KErrNone || r == KErrNotFound); |
|
2640 if (r == KErrNone) |
|
2641 { |
|
2642 test.Printf(_L("Old Serial Number: \"%lS\"\n"), &rd_str_orig); |
|
2643 restore_string = ETrue; |
|
2644 } |
|
2645 else |
|
2646 restore_string = EFalse; |
|
2647 |
|
2648 test.Next(_L("SetSerialNumberStringDescriptor()")); |
|
2649 _LIT16(serial, "000666000XYZ"); |
|
2650 wr_str.FillZ(wr_str.MaxLength()); |
|
2651 wr_str = serial; |
|
2652 r = gPort.SetSerialNumberStringDescriptor(wr_str); |
|
2653 test_KErrNone(r); |
|
2654 |
|
2655 test.Next(_L("GetSerialNumberStringDescriptor()")); |
|
2656 rd_str.FillZ(rd_str.MaxLength()); |
|
2657 r = gPort.GetSerialNumberStringDescriptor(rd_str); |
|
2658 test_KErrNone(r); |
|
2659 test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str); |
|
2660 |
|
2661 test.Next(_L("Compare Serial Number strings")); |
|
2662 r = rd_str.Compare(wr_str); |
|
2663 test_KErrNone(r); |
|
2664 |
|
2665 test.Next(_L("SetSerialNumberStringDescriptor()")); |
|
2666 _LIT16(serial2, "Y11611193111711111Y"); |
|
2667 wr_str.FillZ(wr_str.MaxLength()); |
|
2668 wr_str = serial2; |
|
2669 r = gPort.SetSerialNumberStringDescriptor(wr_str); |
|
2670 test_KErrNone(r); |
|
2671 |
|
2672 test.Next(_L("GetSerialNumberStringDescriptor()")); |
|
2673 rd_str.FillZ(rd_str.MaxLength()); |
|
2674 r = gPort.GetSerialNumberStringDescriptor(rd_str); |
|
2675 test_KErrNone(r); |
|
2676 test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str); |
|
2677 |
|
2678 test.Next(_L("Compare Serial Number strings")); |
|
2679 r = rd_str.Compare(wr_str); |
|
2680 test_KErrNone(r); |
|
2681 |
|
2682 test.Next(_L("RemoveSerialNumberStringDescriptor()")); |
|
2683 r = gPort.RemoveSerialNumberStringDescriptor(); |
|
2684 test_KErrNone(r); |
|
2685 r = gPort.GetSerialNumberStringDescriptor(rd_str); |
|
2686 test(r == KErrNotFound); |
|
2687 |
|
2688 if (restore_string) |
|
2689 { |
|
2690 test.Next(_L("Restore original string")); |
|
2691 r = gPort.SetSerialNumberStringDescriptor(rd_str_orig); |
|
2692 test_KErrNone(r); |
|
2693 r = gPort.GetSerialNumberStringDescriptor(rd_str); |
|
2694 test_KErrNone(r); |
|
2695 r = rd_str.Compare(rd_str_orig); |
|
2696 test_KErrNone(r); |
|
2697 } |
|
2698 |
|
2699 // --- Configuration string |
|
2700 test.Next(_L("GetConfigurationStringDescriptor()")); |
|
2701 rd_str_orig.FillZ(rd_str.MaxLength()); |
|
2702 r = gPort.GetConfigurationStringDescriptor(rd_str_orig); |
|
2703 test(r == KErrNone || r == KErrNotFound); |
|
2704 if (r == KErrNone) |
|
2705 { |
|
2706 test.Printf(_L("Old Configuration string: \"%lS\"\n"), &rd_str_orig); |
|
2707 restore_string = ETrue; |
|
2708 } |
|
2709 else |
|
2710 restore_string = EFalse; |
|
2711 |
|
2712 test.Next(_L("SetConfigurationStringDescriptor()")); |
|
2713 _LIT16(config, "Relatively Simple Configuration That Is Still Useful"); |
|
2714 wr_str.FillZ(wr_str.MaxLength()); |
|
2715 wr_str = config; |
|
2716 r = gPort.SetConfigurationStringDescriptor(wr_str); |
|
2717 test_KErrNone(r); |
|
2718 |
|
2719 test.Next(_L("GetConfigurationStringDescriptor()")); |
|
2720 rd_str.FillZ(rd_str.MaxLength()); |
|
2721 r = gPort.GetConfigurationStringDescriptor(rd_str); |
|
2722 test_KErrNone(r); |
|
2723 test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str); |
|
2724 |
|
2725 test.Next(_L("Compare Configuration strings")); |
|
2726 r = rd_str.Compare(wr_str); |
|
2727 test_KErrNone(r); |
|
2728 |
|
2729 test.Next(_L("SetConfigurationStringDescriptor()")); |
|
2730 _LIT16(config2, "Convenient Configuration That Can Be Very Confusing"); |
|
2731 wr_str.FillZ(wr_str.MaxLength()); |
|
2732 wr_str = config2; |
|
2733 r = gPort.SetConfigurationStringDescriptor(wr_str); |
|
2734 test_KErrNone(r); |
|
2735 |
|
2736 test.Next(_L("GetConfigurationStringDescriptor()")); |
|
2737 rd_str.FillZ(rd_str.MaxLength()); |
|
2738 r = gPort.GetConfigurationStringDescriptor(rd_str); |
|
2739 test_KErrNone(r); |
|
2740 test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str); |
|
2741 |
|
2742 test.Next(_L("Compare Configuration strings")); |
|
2743 r = rd_str.Compare(wr_str); |
|
2744 test_KErrNone(r); |
|
2745 |
|
2746 test.Next(_L("RemoveConfigurationStringDescriptor()")); |
|
2747 r = gPort.RemoveConfigurationStringDescriptor(); |
|
2748 test_KErrNone(r); |
|
2749 r = gPort.GetConfigurationStringDescriptor(rd_str); |
|
2750 test(r == KErrNotFound); |
|
2751 |
|
2752 if (restore_string) |
|
2753 { |
|
2754 test.Next(_L("Restore original string")); |
|
2755 r = gPort.SetConfigurationStringDescriptor(rd_str_orig); |
|
2756 test_KErrNone(r); |
|
2757 r = gPort.GetConfigurationStringDescriptor(rd_str); |
|
2758 test_KErrNone(r); |
|
2759 r = rd_str.Compare(rd_str_orig); |
|
2760 test_KErrNone(r); |
|
2761 } |
|
2762 |
|
2763 test.End(); |
|
2764 } |
|
2765 |
|
2766 static void TestArbitraryStringDescriptors() |
|
2767 { |
|
2768 test.Start(_L("Arbitrary String Descriptor Manipulation")); |
|
2769 |
|
2770 const TUint8 stridx1 = 0xEE; |
|
2771 const TUint8 stridx2 = 0xCC; |
|
2772 const TUint8 stridx3 = 0xDD; |
|
2773 const TUint8 stridx4 = 0xFF; |
|
2774 |
|
2775 // First test string |
|
2776 test.Next(_L("GetStringDescriptor() 1")); |
|
2777 TBuf16<KUsbStringDescStringMaxSize / 2> rd_str; |
|
2778 TInt r = gPort.GetStringDescriptor(stridx1, rd_str); |
|
2779 test(r == KErrNotFound); |
|
2780 |
|
2781 test.Next(_L("SetStringDescriptor() 1")); |
|
2782 _LIT16(string_one, "Arbitrary String Descriptor Test String 1"); |
|
2783 TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(string_one); |
|
2784 r = gPort.SetStringDescriptor(stridx1, wr_str); |
|
2785 test_KErrNone(r); |
|
2786 |
|
2787 test.Next(_L("GetStringDescriptor() 1")); |
|
2788 r = gPort.GetStringDescriptor(stridx1, rd_str); |
|
2789 test_KErrNone(r); |
|
2790 test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx1, &rd_str); |
|
2791 |
|
2792 test.Next(_L("Compare test strings 1")); |
|
2793 r = rd_str.Compare(wr_str); |
|
2794 test_KErrNone(r); |
|
2795 |
|
2796 // Second test string |
|
2797 test.Next(_L("GetStringDescriptor() 2")); |
|
2798 rd_str.FillZ(rd_str.MaxLength()); |
|
2799 r = gPort.GetStringDescriptor(stridx2, rd_str); |
|
2800 test(r == KErrNotFound); |
|
2801 |
|
2802 test.Next(_L("SetStringDescriptor() 2")); |
|
2803 _LIT16(string_two, "Arbitrary String Descriptor Test String 2"); |
|
2804 wr_str.FillZ(wr_str.MaxLength()); |
|
2805 wr_str = string_two; |
|
2806 r = gPort.SetStringDescriptor(stridx2, wr_str); |
|
2807 test_KErrNone(r); |
|
2808 |
|
2809 // In between we create another interface setting to see what happens |
|
2810 // to the existing string descriptor indices. |
|
2811 // (We don't have to test this on every platform - |
|
2812 // besides, those that don't support alt settings |
|
2813 // are by now very rare.) |
|
2814 if (SupportsAlternateInterfaces()) |
|
2815 { |
|
2816 TUsbcScInterfaceInfoBuf ifc; |
|
2817 _LIT16(string, "T_USBAPI Bogus Test Interface (Setting 2)"); |
|
2818 ifc().iString = const_cast<TDesC16*>(&string); |
|
2819 ifc().iTotalEndpointsUsed = 0; |
|
2820 TInt r = gPort.SetInterface(2, ifc); |
|
2821 test_KErrNone(r); |
|
2822 } |
|
2823 |
|
2824 test.Next(_L("GetStringDescriptor() 2")); |
|
2825 r = gPort.GetStringDescriptor(stridx2, rd_str); |
|
2826 test_KErrNone(r); |
|
2827 test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx2, &rd_str); |
|
2828 |
|
2829 test.Next(_L("Compare test strings 2")); |
|
2830 r = rd_str.Compare(wr_str); |
|
2831 test_KErrNone(r); |
|
2832 |
|
2833 // Third test string |
|
2834 test.Next(_L("GetStringDescriptor() 3")); |
|
2835 rd_str.FillZ(rd_str.MaxLength()); |
|
2836 r = gPort.GetStringDescriptor(stridx3, rd_str); |
|
2837 test(r == KErrNotFound); |
|
2838 |
|
2839 test.Next(_L("SetStringDescriptor() 3")); |
|
2840 _LIT16(string_three, "Arbitrary String Descriptor Test String 3"); |
|
2841 wr_str.FillZ(wr_str.MaxLength()); |
|
2842 wr_str = string_three; |
|
2843 r = gPort.SetStringDescriptor(stridx3, wr_str); |
|
2844 test_KErrNone(r); |
|
2845 |
|
2846 test.Next(_L("GetStringDescriptor() 3")); |
|
2847 r = gPort.GetStringDescriptor(stridx3, rd_str); |
|
2848 test_KErrNone(r); |
|
2849 test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx3, &rd_str); |
|
2850 |
|
2851 test.Next(_L("Compare test strings 3")); |
|
2852 r = rd_str.Compare(wr_str); |
|
2853 test_KErrNone(r); |
|
2854 |
|
2855 // Remove string descriptors |
|
2856 test.Next(_L("RemoveStringDescriptor() 4")); |
|
2857 r = gPort.RemoveStringDescriptor(stridx4); |
|
2858 test(r == KErrNotFound); |
|
2859 |
|
2860 test.Next(_L("RemoveStringDescriptor() 3")); |
|
2861 r = gPort.RemoveStringDescriptor(stridx3); |
|
2862 test_KErrNone(r); |
|
2863 r = gPort.GetStringDescriptor(stridx3, rd_str); |
|
2864 test(r == KErrNotFound); |
|
2865 |
|
2866 test.Next(_L("RemoveStringDescriptor() 2")); |
|
2867 r = gPort.RemoveStringDescriptor(stridx2); |
|
2868 test_KErrNone(r); |
|
2869 r = gPort.GetStringDescriptor(stridx2, rd_str); |
|
2870 test(r == KErrNotFound); |
|
2871 |
|
2872 test.Next(_L("RemoveStringDescriptor() 1")); |
|
2873 r = gPort.RemoveStringDescriptor(stridx1); |
|
2874 test_KErrNone(r); |
|
2875 r = gPort.GetStringDescriptor(stridx1, rd_str); |
|
2876 test(r == KErrNotFound); |
|
2877 |
|
2878 test.End(); |
|
2879 } |
|
2880 |
|
2881 static TEndpointState QueryEndpointState(TInt aEndpoint) |
|
2882 { |
|
2883 TEndpointState ep_state = EEndpointStateUnknown; |
|
2884 TInt r = gPort.EndpointStatus(aEndpoint, ep_state); |
|
2885 test(r == KErrNone); |
|
2886 test.Printf(_L("Endpoint %d state: %s\n"), aEndpoint, |
|
2887 (ep_state == EEndpointStateNotStalled) ? _S("Not stalled") : |
|
2888 ((ep_state == EEndpointStateStalled) ? _S("Stalled") : |
|
2889 _S("Unknown..."))); |
|
2890 return ep_state; |
|
2891 } |
|
2892 |
|
2893 static void TestEndpointStallStatus() |
|
2894 { |
|
2895 test.Start(_L("Test Endpoint Stall Status")); |
|
2896 |
|
2897 if (!SupportsEndpointStall()) |
|
2898 { |
|
2899 test.Printf(_L("*** Not supported - skipping endpoint stall status tests\n")); |
|
2900 test.End(); |
|
2901 return; |
|
2902 } |
|
2903 |
|
2904 test.Next(_L("Endpoint stall status")); |
|
2905 TEndpointState epState = EEndpointStateUnknown; |
|
2906 test_Equal(EEndpointStateNotStalled, QueryEndpointState(1)); |
|
2907 test_Equal(EEndpointStateNotStalled, QueryEndpointState(2)); |
|
2908 |
|
2909 test.Next(_L("Stall Ep1")); |
|
2910 gPort.HaltEndpoint(1); |
|
2911 epState = QueryEndpointState(1); |
|
2912 test(epState == EEndpointStateStalled); |
|
2913 |
|
2914 test.Next(_L("Clear Stall Ep1")); |
|
2915 gPort.ClearHaltEndpoint(1); |
|
2916 epState = QueryEndpointState(1); |
|
2917 test(epState == EEndpointStateNotStalled); |
|
2918 |
|
2919 test.Next(_L("Stall Ep2")); |
|
2920 gPort.HaltEndpoint(2); |
|
2921 epState = QueryEndpointState(2); |
|
2922 test(epState == EEndpointStateStalled); |
|
2923 |
|
2924 test.Next(_L("Clear Stall Ep2")); |
|
2925 gPort.ClearHaltEndpoint(2); |
|
2926 epState = QueryEndpointState(2); |
|
2927 test(epState == EEndpointStateNotStalled); |
|
2928 |
|
2929 test.End(); |
|
2930 } |
|
2931 |
|
2932 static void TestEndpointStatusNotify() |
|
2933 { |
|
2934 test.Start(_L("Test Endpoint Status Notification")); |
|
2935 |
|
2936 TRequestStatus ep_status; |
|
2937 TUint epStateBitmap = 0xffffffff; // put in a nonsense value |
|
2938 test.Next(_L("EndpointStatusNotify()")); |
|
2939 gPort.EndpointStatusNotify(ep_status, epStateBitmap); |
|
2940 test.Next(_L("EndpointStatusNotifyCancel()")); |
|
2941 gPort.EndpointStatusNotifyCancel(); |
|
2942 User::WaitForRequest(ep_status); |
|
2943 test(ep_status.Int() == KErrCancel); |
|
2944 test.Next(_L("Check endpoint state bitmap returned")); |
|
2945 // Our interface only uses 2 eps + ep0 |
|
2946 const TUint usedEpBitmap = (1 << 0 | 1 << 1 | 1 << 2); |
|
2947 // Must not return info about non existent Eps: |
|
2948 test((epStateBitmap & ~usedEpBitmap) == 0); |
|
2949 for (TInt i = 0; i <= 2; i++) |
|
2950 { |
|
2951 if ((epStateBitmap & (1 << i)) == EEndpointStateNotStalled) |
|
2952 { |
|
2953 test.Printf(_L("EndpointStatusNotify: Ep %d NOT STALLED\n"), i); |
|
2954 } |
|
2955 else |
|
2956 { |
|
2957 test.Printf(_L("EndpointStatusNotify: Ep %d STALLED\n"), i); |
|
2958 } |
|
2959 } |
|
2960 |
|
2961 test.End(); |
|
2962 } |
|
2963 |
|
2964 static void TestAlternateDeviceStatusNotify() |
|
2965 { |
|
2966 test.Start(_L("Test Alternate Device Status Notification")); |
|
2967 |
|
2968 TRequestStatus dev_status; |
|
2969 TUint deviceState = 0xffffffff; // put in a nonsense value |
|
2970 test.Next(_L("AlternateDeviceStatusNotify()")); |
|
2971 gPort.AlternateDeviceStatusNotify(dev_status, deviceState); |
|
2972 test.Next(_L("AlternateDeviceStatusNotifyCancel()")); |
|
2973 gPort.AlternateDeviceStatusNotifyCancel(); |
|
2974 User::WaitForRequest(dev_status); |
|
2975 test(dev_status == KErrCancel || dev_status == KErrNone); |
|
2976 if (deviceState & KUsbAlternateSetting) |
|
2977 { |
|
2978 TUint setting = (deviceState & ~KUsbAlternateSetting); |
|
2979 test.Printf(_L("Alternate setting change to setting %d - unexpected"), setting); |
|
2980 test(EFalse); |
|
2981 } |
|
2982 else |
|
2983 { |
|
2984 switch (deviceState) |
|
2985 { |
|
2986 case EUsbcDeviceStateUndefined: |
|
2987 test.Printf(_L("TestAlternateDeviceStatusNotify: Undefined state\n")); |
|
2988 break; |
|
2989 case EUsbcDeviceStateAttached: |
|
2990 test.Printf(_L("TestAlternateDeviceStatusNotify: Attached state\n")); |
|
2991 break; |
|
2992 case EUsbcDeviceStatePowered: |
|
2993 test.Printf(_L("TestAlternateDeviceStatusNotify: Powered state\n")); |
|
2994 break; |
|
2995 case EUsbcDeviceStateDefault: |
|
2996 test.Printf(_L("TestAlternateDeviceStatusNotify: Default state\n")); |
|
2997 break; |
|
2998 case EUsbcDeviceStateAddress: |
|
2999 test.Printf(_L("TestAlternateDeviceStatusNotify: Address state\n")); |
|
3000 break; |
|
3001 case EUsbcDeviceStateConfigured: |
|
3002 test.Printf(_L("TestAlternateDeviceStatusNotify: Configured state\n")); |
|
3003 break; |
|
3004 case EUsbcDeviceStateSuspended: |
|
3005 test.Printf(_L("TestAlternateDeviceStatusNotify: Suspended state\n")); |
|
3006 break; |
|
3007 case EUsbcNoState: |
|
3008 test.Printf(_L("TestAlternateDeviceStatusNotify: State buffering error\n")); |
|
3009 test(EFalse); |
|
3010 break; |
|
3011 default: |
|
3012 test.Printf(_L("TestAlternateDeviceStatusNotify: Unknown state\n")); |
|
3013 test(EFalse); |
|
3014 } |
|
3015 } |
|
3016 test.End(); |
|
3017 } |
|
3018 |
|
3019 static void TestDeviceControl() |
|
3020 { |
|
3021 test.Start(_L("Test Device Control")); |
|
3022 |
|
3023 test.Next(_L("SetDeviceControl()")); |
|
3024 TInt r = gPort.SetDeviceControl(); |
|
3025 test_KErrNone(r); |
|
3026 test.Next(_L("ReleaseDeviceControl()")); |
|
3027 r = gPort.ReleaseDeviceControl(); |
|
3028 test_KErrNone(r); |
|
3029 |
|
3030 test.End(); |
|
3031 } |
|
3032 |
|
3033 static void TestDescriptorManipulation() |
|
3034 { |
|
3035 test.Start(_L("Test USB Descriptor Manipulation")); |
|
3036 |
|
3037 LoadDriver(); |
|
3038 OpenChannel(); |
|
3039 test_KErrNone(SettingOne(0)); |
|
3040 |
|
3041 TestDeviceControl(); |
|
3042 |
|
3043 TestAlternateDeviceStatusNotify(); |
|
3044 |
|
3045 TestDeviceDescriptor(); |
|
3046 |
|
3047 TestDeviceQualifierDescriptor(); |
|
3048 |
|
3049 TestConfigurationDescriptor(); |
|
3050 |
|
3051 TestOtherSpeedConfigurationDescriptor(); |
|
3052 |
|
3053 TestInterfaceDescriptor(); |
|
3054 |
|
3055 TestEndpointDescriptor(); |
|
3056 |
|
3057 TestClassSpecificDescriptors(); |
|
3058 |
|
3059 TestStandardStringDescriptors(); |
|
3060 |
|
3061 TestAlternateInterfaceManipulation(); |
|
3062 |
|
3063 TestExtendedEndpointDescriptor(); |
|
3064 |
|
3065 TestArbitraryStringDescriptors(); |
|
3066 |
|
3067 TestEndpointStallStatus(); |
|
3068 |
|
3069 TestEndpointStatusNotify(); |
|
3070 |
|
3071 CloseChannel(); |
|
3072 UnloadDriver(); |
|
3073 |
|
3074 test.End(); |
|
3075 } |
|
3076 |
|
3077 void LoadDriver() |
|
3078 { |
|
3079 test.Next(_L("Load USB LDD")); |
|
3080 TInt r = User::LoadLogicalDevice(KLddName); |
|
3081 test_Value(r, r == KErrNone || r == KErrAlreadyExists); |
|
3082 } |
|
3083 |
|
3084 void OpenChannel() |
|
3085 { |
|
3086 test.Next(_L("Open Channel")); |
|
3087 |
|
3088 TInt r = gPort.Open(0); |
|
3089 test_KErrNone(r); |
|
3090 } |
|
3091 |
|
3092 void TestMultipleChannels() |
|
3093 { |
|
3094 RDevUsbcScClient lPort1; |
|
3095 test.Next(_L("Open local USB channel 1")); |
|
3096 TInt r = lPort1.Open(0); |
|
3097 test_KErrNone(r); |
|
3098 |
|
3099 RDevUsbcScClient lPort2; |
|
3100 test.Next(_L("Open local USB channel 2")); |
|
3101 r = lPort2.Open(0); |
|
3102 test_KErrNone(r); |
|
3103 |
|
3104 test.Next(_L("Close USB Channel 1")); |
|
3105 lPort1.Close(); |
|
3106 |
|
3107 RDevUsbcScClient lPort3; |
|
3108 test.Next(_L("Open local USB channel 3")); |
|
3109 r = lPort3.Open(0); |
|
3110 test_KErrNone(r); |
|
3111 |
|
3112 test.Next(_L("Close USB Channel 2")); |
|
3113 lPort2.Close(); |
|
3114 |
|
3115 test.Next(_L("Close USB Channel 3")); |
|
3116 lPort3.Close(); |
|
3117 } |
|
3118 |
|
3119 void CloseChannel() |
|
3120 { |
|
3121 test.Next(_L("Close Chunk Handle")); |
|
3122 gChunk.Close(); |
|
3123 |
|
3124 test.Next(_L("Close USB Channel")); |
|
3125 gPort.Close(); |
|
3126 } |
|
3127 |
|
3128 void UnloadDriver() |
|
3129 { |
|
3130 // This delay isnt technically needed - its here for test reasons only! |
|
3131 // By waiting, we can see if we get a KErrNone, meaning we know the chunk went away. |
|
3132 // In a real life case - some other client might be using the chunk for a while, |
|
3133 // but this wouldnt matter, it just means we get a diffrent error code. |
|
3134 |
|
3135 test.Next(_L("Free USB LDD")); |
|
3136 User::After(100000); |
|
3137 TInt r = User::FreeLogicalDevice(KUsbDeviceName); |
|
3138 test_KErrNone(r); |
|
3139 } |
|
3140 |
|
3141 void SetupBulkInterfaces(TUint aInterfaceNo,TUint nReadEps, TUint nWriteEps) |
|
3142 { |
|
3143 test.Printf(_L("SetupBulkInterfaces: %d, %d, %d\n"),aInterfaceNo,nReadEps,nWriteEps); |
|
3144 TUsbcScInterfaceInfoBuf ifc; |
|
3145 TUint i; |
|
3146 for(i=0; i<nWriteEps;i++) |
|
3147 { |
|
3148 ifc().iEndpointData[i].iType = KUsbEpTypeBulk; |
|
3149 ifc().iEndpointData[i].iDir = KUsbEpDirIn; |
|
3150 ifc().iEndpointData[i].iSize = KUsbEpSize64; |
|
3151 } |
|
3152 |
|
3153 while(i < (nReadEps + nWriteEps)) |
|
3154 { |
|
3155 ifc().iEndpointData[i].iType = KUsbEpTypeBulk; |
|
3156 ifc().iEndpointData[i].iDir = KUsbEpDirOut; |
|
3157 ifc().iEndpointData[i].iSize = KUsbEpSize64; |
|
3158 i++; |
|
3159 } |
|
3160 |
|
3161 _LIT16(string, "T_USBAPI Test Interface"); |
|
3162 ifc().iString = const_cast<TDesC16*>(&string); |
|
3163 ifc().iTotalEndpointsUsed = nReadEps + nWriteEps; |
|
3164 ifc().iClass.iClassNum = 0xff; |
|
3165 ifc().iClass.iSubClassNum = 0xff; |
|
3166 ifc().iClass.iProtocolNum = 0xff; |
|
3167 TInt r = gPort.SetInterface(aInterfaceNo, ifc); |
|
3168 test_KErrNone(r); |
|
3169 } |
|
3170 |
|
3171 void PrintBILTestOptions() |
|
3172 { |
|
3173 test.Printf(_L("Select an option\n")); |
|
3174 test.Printf(_L("1.Test BIL API\n")); //unimplemented |
|
3175 test.Printf(_L("2.Test BIL Read Write\n")); |
|
3176 test.Printf(_L("3.Test EP0 using BIL API's\n")); |
|
3177 test.Printf(_L("4.Test AlternateSetting Change BIL API's\n")); //unimplemented |
|
3178 test.Printf(_L("5.Run All\n")); |
|
3179 test.Printf(_L("6.Quit\n")); |
|
3180 } |
|
3181 |
|
3182 void PrintWriteOptions() |
|
3183 { |
|
3184 test.Printf(_L("Select an option\n")); |
|
3185 test.Printf(_L("1.Test single buffer write\n")); |
|
3186 test.Printf(_L("2.Test double buffer write\n")); |
|
3187 test.Printf(_L("3.Test multiple queing write\n")); |
|
3188 } |
|
3189 |
|
3190 |
|
3191 _LIT(KLitHostToDev,"Host to Device"); |
|
3192 _LIT(KLitDevToHost,"Device to Host"); |
|
3193 const TDesC* const KLitDirections[2] = {&KLitHostToDev, &KLitDevToHost}; |
|
3194 |
|
3195 _LIT(KLitStandard, "standard"); |
|
3196 _LIT(KLitClass, "class"); |
|
3197 _LIT(KLitVendor, "vendor"); |
|
3198 _LIT(KLitUnkown, "unknown"); |
|
3199 const TDesC* const KLitType[4] = {&KLitStandard, &KLitClass, &KLitVendor, &KLitUnkown}; |
|
3200 |
|
3201 _LIT(KLitDevice, "Device"); |
|
3202 _LIT(KLitInterface, "Interface"); |
|
3203 _LIT(KLitEndpoint, "Endpoint"); |
|
3204 _LIT(KLitOther, "Other"); |
|
3205 const TDesC* const KLitDest[4] = {&KLitDevice, &KLitInterface, &KLitEndpoint, &KLitOther}; |
|
3206 |
|
3207 |
|
3208 void PrintSetupPkt(Sep0SetupPacket* setup) |
|
3209 { |
|
3210 |
|
3211 if(setup != NULL) |
|
3212 { |
|
3213 test.Printf(_L("EP0 command:\n")); |
|
3214 test.Printf(_L("Direction: %S, "),KLitDirections[(setup->iRequestType>>KDirBit) & 0x1]); |
|
3215 test.Printf(_L("Request type: %S, "), KLitType[((setup->iRequestType>>KReqTypeBit) & 0x3)]); |
|
3216 |
|
3217 if (setup->iRequestType & KRecepientReservedMask) |
|
3218 test.Printf(_L("Recepient: Unknown (0x%x), "), setup->iRequestType & KRecepientMask); |
|
3219 else |
|
3220 test.Printf(_L("Recepient: %S\n"), KLitDest[(setup->iRequestType & KRecepientMask)]); |
|
3221 |
|
3222 test.Printf(_L("bRequest:0x%x, "),setup->iRequest); |
|
3223 test.Printf(_L("wValue:0x%x, "),setup->iwValue); |
|
3224 test.Printf(_L("wIndex:0x%x, "),setup->iwIndex); |
|
3225 test.Printf(_L("wLength:0x%x\n"),setup->iWlength); |
|
3226 } |
|
3227 } |
|
3228 |
|
3229 void WriteDataToBuffer(TAny* aBufferStartAddr,TUint aLength,TDes8& aWriteBuf) |
|
3230 { |
|
3231 TUint8 * scBufferAddr = (TUint8*) aBufferStartAddr; |
|
3232 TUint i; |
|
3233 //create the write buffer |
|
3234 for(i=0;i<aLength;i++) |
|
3235 { |
|
3236 aWriteBuf.Append(i); //data is duplicated here in writebuffer and sc location, cant think of anyth better at the moment; |
|
3237 *(scBufferAddr) = i; |
|
3238 //test.Printf(_L("Addr:0x%x, data[i]:%d "),scBufferAddr,*(scBufferAddr)); |
|
3239 scBufferAddr += 1; |
|
3240 } |
|
3241 } |
|
3242 void BILWrite(TDes8& aWriteBuf) |
|
3243 { |
|
3244 TInt ret = KErrNone; |
|
3245 test.Printf(_L("TestBILWrite\n")); |
|
3246 TEndpointBuffer epBuf; |
|
3247 const TUint KWriteEp = 1; |
|
3248 TRequestStatus status; |
|
3249 TRequestStatus status1,status2; |
|
3250 TUint length; |
|
3251 TAny* buffer; |
|
3252 |
|
3253 //Open endpoint |
|
3254 test_KErrNone(gPort.OpenEndpoint(epBuf,KWriteEp)); |
|
3255 test_KErrNone(epBuf.GetInBufferRange(buffer, length)); |
|
3256 |
|
3257 char ch='0'; |
|
3258 do{ |
|
3259 PrintWriteOptions(); |
|
3260 ch = test.Getch(); |
|
3261 switch(ch) |
|
3262 { |
|
3263 case '1': |
|
3264 //case 1: Write a buffer fulll of data to USBIO demo app: Total data written- 1xBuffersize |
|
3265 test.Printf(_L("Length to be written: %d\n"),length); |
|
3266 WriteDataToBuffer(buffer,length,aWriteBuf); |
|
3267 //need to check allignment |
|
3268 test.Printf(_L("Data ready to be written out, Start 'read to file' on an IN endpoint onthe USBIO demo application then press a key when ready to proceed\n")); |
|
3269 test.Getch(); |
|
3270 test_KErrNone(epBuf.WriteBuffer(buffer,length,ETrue,status)); |
|
3271 //Note-Till here is common for all options and can be put in a common place. Repeating the code for the sake of better understanding |
|
3272 User::WaitForRequest(status); |
|
3273 if(gVerbose) |
|
3274 test.Printf(_L("Write status %d\n"),status.Int()); |
|
3275 test_KErrNone(status.Int()); |
|
3276 test.Printf(_L("Total bytes written:%d\n"),aWriteBuf.Length()); |
|
3277 test.Printf(_L("Stop writing at the USBIO demo dialog window, Press a key to continue##\n")); |
|
3278 test.Getch(); |
|
3279 break; |
|
3280 |
|
3281 case '2': |
|
3282 //case 2: Write a buffer fulll of data to USBIO demo app wait until it is written out, write a second buffer full of data: Total data written- 2xBuffersize |
|
3283 WriteDataToBuffer(buffer,length,aWriteBuf); |
|
3284 test.Printf(_L("Data ready to be written out, Start the write mode on USBIO demo application and press a key when ready to proceed\n")); |
|
3285 test.Getch(); |
|
3286 ret = epBuf.WriteBuffer(buffer,length,EFalse,status); |
|
3287 test_KErrNone(ret); |
|
3288 User::WaitForRequest(status); |
|
3289 test_KErrNone(status.Int()); |
|
3290 |
|
3291 WriteDataToBuffer(buffer,length,aWriteBuf); |
|
3292 ret = epBuf.WriteBuffer(buffer,length,ETrue,status); |
|
3293 test_KErrNone(ret); |
|
3294 User::WaitForRequest(status); |
|
3295 test_KErrNone(status.Int()); |
|
3296 |
|
3297 test.Printf(_L("Total bytes written:%d\n"),aWriteBuf.Length()); |
|
3298 test.Printf(_L("Stop writing at the USBIO demo dialog window,Press a key to continue\n")); |
|
3299 test.Getch(); |
|
3300 break; |
|
3301 |
|
3302 case '3': |
|
3303 //case 3: Write maxpacketsize (64 bytes) of data to USBIO demo app, queue remianing data in buffer (full buffer length-maxpacket size), wait for results: Total data written- 1xBuffersize |
|
3304 WriteDataToBuffer(buffer,64,aWriteBuf); |
|
3305 test.Printf(_L("Data ready to be written out, Start the write mode on USBIO demo application and press a key when ready to proceed\n")); |
|
3306 test.Getch(); |
|
3307 |
|
3308 ret = epBuf.WriteBuffer(buffer,64,EFalse,status1); |
|
3309 test_KErrNone(ret); |
|
3310 |
|
3311 WriteDataToBuffer((TUint8*)buffer+64,length-64,aWriteBuf); |
|
3312 ret = epBuf.WriteBuffer((TUint8*)buffer+64,length-64,ETrue,status2); |
|
3313 test_KErrNone(ret); |
|
3314 |
|
3315 User::WaitForRequest(status1); |
|
3316 test_KErrNone(status1.Int()); |
|
3317 User::WaitForRequest(status2); |
|
3318 test_KErrNone(status2.Int()); |
|
3319 |
|
3320 test.Printf(_L("Total bytes written: %d\n"),aWriteBuf.Length()); |
|
3321 test.Printf(_L("Stop writing at the USBIO demo dialog window,Press a key to continue\n")); |
|
3322 test.Getch(); |
|
3323 break; |
|
3324 |
|
3325 default: |
|
3326 ch='R'; //repeat |
|
3327 break; |
|
3328 } |
|
3329 }while(ch == 'R'); |
|
3330 |
|
3331 epBuf.Close(); |
|
3332 |
|
3333 } |
|
3334 |
|
3335 |
|
3336 void BILRead(TDes8& aReadBuf) |
|
3337 { |
|
3338 test.Printf(_L("TestBILRead\n")); |
|
3339 TEndpointBuffer epBuf; |
|
3340 const TUint KReadEp = 2; |
|
3341 TRequestStatus status; |
|
3342 |
|
3343 //Open endpoint |
|
3344 gPort.OpenEndpoint(epBuf,KReadEp); |
|
3345 test.Printf(_L("Open endpoint results for read endpoint\n")); |
|
3346 |
|
3347 //call GetBuffer, loop as long as EoF is not received |
|
3348 TAny *readBuf; |
|
3349 TUint aSize; |
|
3350 TBool aZlp; |
|
3351 |
|
3352 do |
|
3353 { |
|
3354 aSize = 0; |
|
3355 aZlp = EFalse; |
|
3356 TInt ret = KErrGeneral; |
|
3357 ret = epBuf.GetBuffer(readBuf,aSize,aZlp,status); |
|
3358 if(gVerbose) |
|
3359 test.Printf(_L("Getbuffer call returned %d, aSize: %d, aZlp: %d\n"),ret, aSize,aZlp); |
|
3360 |
|
3361 if(ret == KErrCompletion) |
|
3362 { |
|
3363 //add the data to read buffer |
|
3364 TUint8 *buffer = (TUint8 *)readBuf; |
|
3365 aReadBuf.Append(&buffer[0],aSize); |
|
3366 } |
|
3367 else |
|
3368 { |
|
3369 test_KErrNone(ret); |
|
3370 test.Printf(_L("Waiting for Data, Data read so far: %d\n"),aReadBuf.Length()); |
|
3371 User::WaitForRequest(status); |
|
3372 } |
|
3373 } |
|
3374 while(!aZlp); |
|
3375 |
|
3376 epBuf.Close(); |
|
3377 } |
|
3378 |
|
3379 TBool CompareBuffs(TDes8& aReadBuf, TDes8& aWriteBuf) |
|
3380 { |
|
3381 TInt wrLength = aWriteBuf.Length(); |
|
3382 TInt rdLength = aReadBuf.Length(); |
|
3383 if(wrLength != rdLength) |
|
3384 { |
|
3385 test.Printf(_L("Error: Disparity between length of data written and read back!")); |
|
3386 return EFalse; |
|
3387 } |
|
3388 for(TInt i=0; i < wrLength; i++) |
|
3389 { |
|
3390 if (aReadBuf[i] != aWriteBuf[i]) |
|
3391 { |
|
3392 test.Printf(_L("Error: for i = %d:"), i); |
|
3393 test.Printf(_L("aReadBuf: %d != aWriteBuf: %d"), |
|
3394 aReadBuf[i], aWriteBuf[i]); |
|
3395 return EFalse; |
|
3396 } |
|
3397 } |
|
3398 return ETrue; |
|
3399 } |
|
3400 |
|
3401 |
|
3402 /** |
|
3403 Test Read/write using BIL api's |
|
3404 -Sends data to PC application |
|
3405 -Reads data back (the host side should send back the data which was read in the previous step) |
|
3406 -Compare the data read to that written, verify they match. |
|
3407 */ |
|
3408 TBuf8<KMaxBufSize> iWriteBuf; |
|
3409 TBuf8<KMaxBufSize> iReadBuf; |
|
3410 void TestBILReadWrite() |
|
3411 { |
|
3412 TRequestStatus status; |
|
3413 |
|
3414 test.Next(_L("TestBILReadWrite")); |
|
3415 test.Printf(_L("Open global USB channel")); |
|
3416 TInt r = gPort.Open(0); |
|
3417 test_KErrNone(r); |
|
3418 //Test for a simple interface with 2 endpoints |
|
3419 test.Printf(_L("Set up interface\n")); |
|
3420 SetupBulkInterfaces(0,1,1); |
|
3421 RChunk *tChunk = &gChunk; |
|
3422 test.Printf(_L("Finalize Interface\n")); |
|
3423 gPort.FinalizeInterface(tChunk); |
|
3424 |
|
3425 if(gRealHardware) |
|
3426 { |
|
3427 test.Printf(_L("Please Start the USBIO demo application on the host side \n")); |
|
3428 gPort.ReEnumerate(status); |
|
3429 User::WaitForRequest(status); |
|
3430 test.Printf(_L("Enumerated. status = %d\n"), status.Int()); |
|
3431 test.Printf(_L("The following test attempts to write data to the host application. USBIO demo application is used on the PC side.\ |
|
3432 Using USBIO demo app, user should capture data to a file. When prompted, use USBIO application to send the recorded file back to device.\ |
|
3433 The device side application will compare the data and show the result\n")); |
|
3434 test.Printf(_L("Test Write using BIL apis\n")); |
|
3435 BILWrite(iWriteBuf); |
|
3436 |
|
3437 test.Printf(_L("Test Read using BIL api's\n")); |
|
3438 BILRead(iReadBuf); |
|
3439 |
|
3440 test.Printf(_L("Compare Read and Write buffers\n")); |
|
3441 TBool ret = CompareBuffs(iReadBuf, iWriteBuf); |
|
3442 if(!ret) |
|
3443 { |
|
3444 test.Printf(_L("!!warning- compare buffers found discrepancies!\n")); |
|
3445 } |
|
3446 } |
|
3447 gChunk.Close(); |
|
3448 test.Printf(_L("Close global USB channel\n")); |
|
3449 gPort.Close(); |
|
3450 } |
|
3451 |
|
3452 //At present, test only tests that multiple intefaces can be set up. |
|
3453 void TestBILAlternateSettingChange() |
|
3454 { |
|
3455 TRequestStatus status; |
|
3456 |
|
3457 test.Next(_L("BIL Alternate Setting Change")); |
|
3458 test.Printf(_L("Open global USB channel")); |
|
3459 TInt r = gPort.Open(0); |
|
3460 test_KErrNone(r); |
|
3461 //Test for a simple interface with 2 endpoints |
|
3462 test.Printf(_L("Set up interface 0\n")); |
|
3463 SetupBulkInterfaces(0,1,1); |
|
3464 test.Printf(_L("Set up interface 1\n")); |
|
3465 SetupBulkInterfaces(1,1,1); |
|
3466 RChunk *tChunk = &gChunk; |
|
3467 test.Printf(_L("Finalize Interface\n")); |
|
3468 gPort.FinalizeInterface(tChunk); |
|
3469 |
|
3470 if(gRealHardware) |
|
3471 { |
|
3472 gPort.ReEnumerate(status); |
|
3473 User::WaitForRequest(status); |
|
3474 test.Printf(_L("Enumerated. status = %d\n"), status.Int()); |
|
3475 } |
|
3476 gChunk.Close(); |
|
3477 test.Printf(_L("Close global USB channel\n")); |
|
3478 gPort.Close(); |
|
3479 } |
|
3480 |
|
3481 /** |
|
3482 Test EP0 Read/write using BIL api's |
|
3483 -Waits until a setup packet is received from host. Decodes the packet once it is received |
|
3484 -If data is expected from host, read the data and print it out |
|
3485 -If data is to be sent to host, write the data to host. |
|
3486 -Manual verification that data is received correctly |
|
3487 */ |
|
3488 void TestBILEp0() |
|
3489 { |
|
3490 test.Next(_L("Endpoint Zero")); |
|
3491 |
|
3492 TRequestStatus status; |
|
3493 TRequestStatus keyStatus; |
|
3494 |
|
3495 test_KErrNone(gPort.Open(0)); |
|
3496 //Test for a simple interface with 2 endpoints |
|
3497 SetupBulkInterfaces(0,1,1); |
|
3498 RChunk *tChunk = &gChunk; |
|
3499 test_KErrNone(gPort.FinalizeInterface(tChunk)); |
|
3500 |
|
3501 if(gRealHardware) |
|
3502 { |
|
3503 test.Printf(_L("With USBIO, open and configure the device, then send then and then recieve at lest 4 class/vendor requests to interface 0\n")); |
|
3504 |
|
3505 TBool passed=EFalse; |
|
3506 TBool error=EFalse; |
|
3507 gPort.ReEnumerate(status); |
|
3508 User::WaitForRequest(status); |
|
3509 test_KErrNone(status.Int()); |
|
3510 TEndpointBuffer epBuf; |
|
3511 const TUint KEp0Endpoint = 0; |
|
3512 //TRequestStatus status; |
|
3513 |
|
3514 //Open endpoint |
|
3515 test_KErrNone(gPort.OpenEndpoint(epBuf,KEp0Endpoint)); |
|
3516 //call readdatanotify |
|
3517 |
|
3518 Sep0SetupPacket* setup; |
|
3519 TUint8 *readBuf; |
|
3520 TUint aSize; |
|
3521 TBool aZlp; |
|
3522 aSize = 0; |
|
3523 aZlp = EFalse; |
|
3524 TInt ret = KErrGeneral; |
|
3525 TInt phase=0; |
|
3526 keyStatus=KErrNone; |
|
3527 |
|
3528 TUint dataLength=0; |
|
3529 TBool reqNeeded=ETrue; |
|
3530 |
|
3531 TInt goodReads=0; |
|
3532 TInt goodWrites=0; |
|
3533 TInt goodStateChange=0; |
|
3534 |
|
3535 while (ETrue) |
|
3536 { |
|
3537 if (keyStatus.Int()!=KRequestPending) |
|
3538 { |
|
3539 if (test.Console()->KeyCode() == EKeyEscape) |
|
3540 break; |
|
3541 else |
|
3542 test.Printf(_L("Press escape to end EP0 testing\n")); |
|
3543 |
|
3544 test.Console()->Read(keyStatus); |
|
3545 } |
|
3546 |
|
3547 if (reqNeeded) |
|
3548 { |
|
3549 ret = epBuf.GetBuffer((TAny*&)readBuf,aSize,aZlp,status); |
|
3550 if(gVerbose) |
|
3551 test.Printf(_L("Getbuffer returned %d, aSize: %d, aZlp: %d\n"),ret, aSize,aZlp); |
|
3552 } |
|
3553 |
|
3554 if (ret==KErrNone) |
|
3555 { |
|
3556 User::WaitForRequest(status, keyStatus); |
|
3557 TInt r = status.Int(); |
|
3558 test_Value(r, (r==KErrNone) || (r==KRequestPending)); |
|
3559 if (r!=KRequestPending) // Dealing with keys in the same loop, does confuse things. |
|
3560 ret=KErrCompletion; |
|
3561 } |
|
3562 else if (ret==TEndpointBuffer::KStateChange) |
|
3563 { |
|
3564 TInt state = *((TInt*) readBuf); |
|
3565 test.Printf(_L("Status Change:! %d : %S \n"),state,((state<0) || (state>7))?KStates[8]:KStates[state]); |
|
3566 test_Equal(aSize, 4); |
|
3567 goodStateChange++; |
|
3568 } |
|
3569 else |
|
3570 { |
|
3571 test_Equal(ret, KErrCompletion); |
|
3572 reqNeeded = ETrue; |
|
3573 if (phase==0) //Header |
|
3574 { |
|
3575 if (aSize!=8) |
|
3576 { |
|
3577 test.Printf(_L("Error: Malformed control packet of size %d.\n"),aSize); |
|
3578 error = ETrue; |
|
3579 } |
|
3580 else |
|
3581 { |
|
3582 setup = (Sep0SetupPacket* ) readBuf; |
|
3583 PrintSetupPkt(setup); |
|
3584 |
|
3585 if (setup->iRequestType&KDeviceToHost) |
|
3586 { |
|
3587 // Send data |
|
3588 test.Printf(_L("Sending %d bytes of data value increasing from 0x0 in 1 step. Verify data is received at the host\n"),setup->iWlength); |
|
3589 TUint8 *ep0Buffer; // = (TUint8 *)epBuf.Ep0In()BufferStart; |
|
3590 TUint ep0Length; |
|
3591 epBuf.GetInBufferRange(((TAny*&)ep0Buffer),ep0Length); |
|
3592 TUint8 *ep0Data = ep0Buffer; |
|
3593 for(TUint8 i=0;i< setup->iWlength;i++) |
|
3594 { |
|
3595 *(ep0Data++) = i; |
|
3596 } |
|
3597 test_KErrNone(epBuf.WriteBuffer(ep0Buffer,setup->iWlength,ETrue,status)); |
|
3598 User::WaitForRequest(status); |
|
3599 test_KErrNone(status.Int()); |
|
3600 goodWrites++; |
|
3601 } |
|
3602 else |
|
3603 { |
|
3604 dataLength = setup->iWlength; |
|
3605 if (dataLength) |
|
3606 { |
|
3607 phase=1; |
|
3608 iReadBuf.Zero(); |
|
3609 } |
|
3610 else |
|
3611 { |
|
3612 gPort.SendEp0StatusPacket(); |
|
3613 test.Printf(_L("No Data.\n")); |
|
3614 } |
|
3615 } // end HostToDevice type |
|
3616 } //packet Correct length |
|
3617 } |
|
3618 else // DataPhase |
|
3619 { |
|
3620 dataLength -= aSize; |
|
3621 iReadBuf.Append(&readBuf[0],aSize); |
|
3622 if (!dataLength) |
|
3623 phase=0; |
|
3624 |
|
3625 if (aZlp && dataLength) |
|
3626 { |
|
3627 test.Printf(_L("\nError: ZLP received before enough data is read out!\nFailing Test!\n")); |
|
3628 error=ETrue; |
|
3629 phase=0; |
|
3630 } |
|
3631 |
|
3632 if (!phase) |
|
3633 { |
|
3634 gPort.SendEp0StatusPacket(); |
|
3635 //Print read out values |
|
3636 test.Printf(_L("Data Read:")); |
|
3637 for(TInt i=0; i < iReadBuf.Length(); i++) |
|
3638 { |
|
3639 test.Printf(_L("0x%x "),iReadBuf[i]); |
|
3640 } |
|
3641 test.Printf(_L("\n")); |
|
3642 goodReads++; |
|
3643 } |
|
3644 |
|
3645 } // end DataPhase |
|
3646 } |
|
3647 |
|
3648 } // end while |
|
3649 epBuf.Close(); |
|
3650 |
|
3651 if ((goodWrites>3) && (goodReads>3) && (goodStateChange>6)) |
|
3652 passed=ETrue; |
|
3653 |
|
3654 if ((!passed) || (error)) |
|
3655 { |
|
3656 if (!error) |
|
3657 test.Printf(_L("\nInsifishant reads/writes where seen to work, to pass test.\n")); |
|
3658 |
|
3659 test.Printf(_L("\n ***************\n")); |
|
3660 test.Printf(_L(" * FAILED TEST *\n")); |
|
3661 test.Printf(_L(" ***************\n\nKey to Continue.")); |
|
3662 } |
|
3663 else |
|
3664 { |
|
3665 test.Printf(_L("\nIf the USBIO demo application responded as expected, then this can be called a passed test.\n\nKey to Continue.\n")); |
|
3666 } |
|
3667 |
|
3668 //Note- A disturbing fact! If host aborts data transmission and send a new setup packet, the userside is clueless as to what it's reading is |
|
3669 // data/setup data. |
|
3670 test.Getch(); |
|
3671 } // end if-real-hardware |
|
3672 gChunk.Close(); |
|
3673 test.Printf(_L("Close global USB channel\n")); |
|
3674 gPort.Close(); |
|
3675 } // end funcion |
|
3676 |
|
3677 |
|
3678 |
|
3679 void TestBIL() |
|
3680 { |
|
3681 TInt r; |
|
3682 test.Start(_L("BIL unit tests")); |
|
3683 test.Next(_L("Load driver")); |
|
3684 r = User::LoadLogicalDevice(KLddName); |
|
3685 test_Value(r, r == KErrNone || r == KErrAlreadyExists); |
|
3686 /* ---------------------------------------------------------------------------- |
|
3687 @SYMTestCaseID PBASE-USB-SC-1225 |
|
3688 @SYMTestCaseDesc BIL Testing: Functionality tests |
|
3689 @SYMPREQ PREQ1846 |
|
3690 @SYMTestPriority |
|
3691 @SYMTestActions |
|
3692 The test has 3 components- write content to USBIO demo application, read back the contents written and compare the written and read data to do data validation. |
|
3693 The test attempts to do 3 types of write |
|
3694 1) A full buffer write- Buffer is filled with data and written to host. The user should initiate the host side application to accept the incoming data and write it to a file. |
|
3695 2) A double buffer write- Data equivalent to twice the buffer size is written to host side. The test waits until 1 full buffer of data is written out, and then writes another full buffer of data. |
|
3696 The user should initiate the host side application to accept the incoming data and write to a file |
|
3697 3) A split buffer write- A full buffer of data is split into two portions and written to the buffer in quick succession. |
|
3698 The test waits for the status of both write operations after queuing the writes. |
|
3699 In each of the above cases, the sent data is written to a file by the USBIO demo application. User then sends back the file written to the device. |
|
3700 The test application reads in the file sent by the host application and compares it to written data which was saved during the write stage. |
|
3701 If the read data is same as written data, test succeeds. |
|
3702 @SYMTestExpectedResults |
|
3703 The test should read the same data as was sent. It should be able to handle all the 3 types of writes. |
|
3704 */ |
|
3705 if ((gSpecTest==EBilRw) || (gSpecTest==EAll)) |
|
3706 TestBILReadWrite(); |
|
3707 /* ---------------------------------------------------------------------------- |
|
3708 @SYMTestCaseID PBASE-USB-SC-1226 |
|
3709 @SYMTestCaseDesc BIL testing: EP0 Read/write |
|
3710 @SYMPREQ PREQ1846 |
|
3711 @SYMTestPriority |
|
3712 @SYMTestActions |
|
3713 The USBIO host application can be used to send a class/vendor request on EP0. |
|
3714 The test application should wait for an EP0 setup packet. Once a setup packet is received, the test application decodes the contents of the setup packet. |
|
3715 If there is data to be received from host, BIL read routines should read the data in and send a status packet back to the host. |
|
3716 If data is to be sent back to the host, ensure that data is received correctly at host |
|
3717 @SYMTestExpectedResults |
|
3718 Ensure setup packet is received correctly and data is received at host/device end correctly |
|
3719 */ |
|
3720 if ((gSpecTest==EBilEp0) || (gSpecTest==EAll)) |
|
3721 TestBILEp0(); |
|
3722 |
|
3723 if ((gSpecTest==EBilAlt) || (gSpecTest==EAll)) |
|
3724 TestBILAlternateSettingChange(); |
|
3725 |
|
3726 test.Next(_L("Unload driver")); |
|
3727 r = User::FreeLogicalDevice(KUsbDeviceName); |
|
3728 test_Value(r,(r==KErrNone) || (r==KErrInUse)); |
|
3729 test.End(); |
|
3730 } |
|
3731 |
|
3732 /* Where the testing starts */ |
|
3733 void StartTests(void) |
|
3734 { |
|
3735 switch (gSpecTest) |
|
3736 { |
|
3737 /* ---------------------------------------------------------------------------- |
|
3738 @SYMTestCaseID PBASE-USB-SC-1218 |
|
3739 @SYMTestCaseDesc Buffer Handling: Reads |
|
3740 @SYMPREQ PREQ1846 |
|
3741 @SYMTestPriority |
|
3742 @SYMTestActions |
|
3743 1. Queue read on OUT endpoint i.e. Call ReadDataNotify API. |
|
3744 Each time the transfer header is checked for the following |
|
3745 a) Tail pointer of previous transfer not the same as the current Tail pointer |
|
3746 b) Sequence Number of every transfer is always one more than previous |
|
3747 c) First transfer offset greater than start offset of buffer header. Transfer Offset when it wraps around to the beginning of the buffer is also greater than start offset of buffer header. |
|
3748 d) Data does not overlap chunk offset of the next transfer to be extracted |
|
3749 e) No data or metadata goes beyond the end address of the buffer |
|
3750 f) Data is aligned to MaxPacketSize of the endpoint |
|
3751 @SYMTestExpectedResults |
|
3752 1. If data is present API returns immediately with KErrCompletion else KErrNone. If data ready, user side walks the chunk. |
|
3753 Queues another read till no data present when the API will return KErrNone. |
|
3754 */ |
|
3755 case EBufRead: // Test Reading from an endpoint |
|
3756 { |
|
3757 test.Start(_L("PBASE-USB-SC-1218 Reading from an endpoint. On host side, select an OUT endpoint and send data from a file\n")); |
|
3758 TestBufferHandling(); |
|
3759 test.End(); |
|
3760 break; |
|
3761 } |
|
3762 /* ---------------------------------------------------------------------------- |
|
3763 @SYMTestCaseID PBASE-USB-SC-1219 |
|
3764 @SYMTestCaseDesc Buffer Handling: Writes |
|
3765 @SYMPREQ PREQ1846 |
|
3766 @SYMTestPriority |
|
3767 @SYMTestActions |
|
3768 1. Queue Write on an IN endpoint i.e. Call WriteData API. The buffer offset is checked to see if it is aligned to MaxPacketSize of endpoint. |
|
3769 @SYMTestExpectedResults |
|
3770 1. Chunk is populated with correct number of buffers and alternate settings with correct number and type of endpoints. |
|
3771 */ |
|
3772 case EBufWrite: // Test Writing to an endpoint |
|
3773 { |
|
3774 test.Start(_L("PBASE-USB-SC-1219 Writing to an endpoint. On host side, select an IN endpoint and write to a file\n")); |
|
3775 TestBufferHandling(); |
|
3776 test.End(); |
|
3777 break; |
|
3778 } |
|
3779 /* ---------------------------------------------------------------------------- |
|
3780 @SYMTestCaseID PBASE-USB-SC-1220 |
|
3781 @SYMTestCaseDesc Endpoint 0: Read, Write and Status Changes |
|
3782 @SYMPREQ PREQ1846 |
|
3783 @SYMTestPriority |
|
3784 @SYMTestActions |
|
3785 1. If the setup packet contains a command to send data from Host to Device, Queue read on EP0 endpoint i.e. Call ReadDataNotify API. |
|
3786 Each time the transfer header is checked for the following |
|
3787 a) Tail pointer of previous transfer not the same as the current Tail pointer |
|
3788 b) Sequence Number of every transfer is always one more than previous |
|
3789 c) First transfer offset greater than start offset of buffer header. Transfer Offset when it wraps around to the beginning of the buffer is also greater than start offset of buffer header. |
|
3790 d) Data does not overlap chunk offset of the next transfer to be extracted |
|
3791 e) No data or metadata goes beyond the end address of the buffer |
|
3792 f) Test for successful reading of odd number of bytes as data. |
|
3793 2. If the setup packet contains a command to send data from device to host, Queue Write on an EP0 endpoint i.e. Call WriteData API. |
|
3794 3. On unplugging and plugging back the USB cable, check that state change packets can be sent to user side. |
|
3795 @SYMTestExpectedResults |
|
3796 1. If data is present API returns immediately with KErrCompletion else KErrNone. If data ready, user side walks the chunk. Queues another read till no data present when the API will return KErrNone. |
|
3797 2. Data is successfully written out of the buffer |
|
3798 3. State change packets corresponding to the event that caused it are seen on user side |
|
3799 |
|
3800 */ |
|
3801 case EEp0: // Test Ep0 |
|
3802 { |
|
3803 test.Start(_L("PBASE-USB-SC-1220 Reading from and Writing to EP0. On host side, send a Vendor Request to interface from Host to Device or Device to Host\n")); |
|
3804 TestBufferHandling(); |
|
3805 test.End(); |
|
3806 break; |
|
3807 } |
|
3808 /* ---------------------------------------------------------------------------- |
|
3809 @SYMTestCaseID PBASE-USB-SC-1221 |
|
3810 @SYMTestCaseDesc Alternate Setting Changes |
|
3811 @SYMPREQ PREQ1846 |
|
3812 @SYMTestPriority |
|
3813 @SYMTestActions |
|
3814 1. Set up an interface with 2 or more alternate settings. Read/Write from the default setting (0). Switch to another alternate setting. Read/Write from the new alternate setting (1/2/3). Switch back to the default setting. Read/Write from the default setting (0). |
|
3815 Each time alternate setting is changed, ensure that for every OUT endpoint |
|
3816 a) The transfer header's alternate setting member contains the current alternate setting |
|
3817 b) The transfer header's alternate setting change sequence member in incremented |
|
3818 c) An empty transfer header containing the new alternate setting and alternate setting change sequence numbers. |
|
3819 d) EP0 OUT endpoint gets an empty transfer header containing the new alternate setting and alternate setting change sequence numbers. |
|
3820 @SYMTestExpectedResults |
|
3821 1. On Alternate setting change, all buffers corresponding to the OUT endpoints and EP0 OUT buffer receive a transfer with the new alternate setting number, new alternate setting change sequence number. |
|
3822 The device is able to read and write though the endpoints corresponding to the new alternate setting. |
|
3823 */ |
|
3824 case EAltSet: // AlternateSetting |
|
3825 { |
|
3826 test.Start(_L("PBASE-USB-SC-1221 Alternate Setting Change \n")); |
|
3827 TestBufferHandling(); |
|
3828 test.End(); |
|
3829 break; |
|
3830 } |
|
3831 /* ---------------------------------------------------------------------------- |
|
3832 @SYMTestCaseID PBASE-USB-SC-1217 |
|
3833 @SYMTestCaseDesc Buffer Construction |
|
3834 @SYMPREQ PREQ1846 |
|
3835 @SYMTestPriority |
|
3836 @SYMTestActions |
|
3837 1. Set up different number of interfaces. Check if chunk is populated correctly for various setting configurations set using SetInterface and RealizeInterface API |
|
3838 2. Positive and Negative tests using Release Interface |
|
3839 @SYMTestExpectedResults |
|
3840 1. Chunk is populated with correct number of buffers and alternate settings with correct number and type of endpoints. |
|
3841 2. Destructors clean up |
|
3842 */ |
|
3843 case EInterface: |
|
3844 { |
|
3845 test.Start(_L("PBASE-USB-SC-1217 SetInterface Test\n")); |
|
3846 TestSetInterface(); |
|
3847 test.End(); |
|
3848 break; |
|
3849 } |
|
3850 /* ---------------------------------------------------------------------------- |
|
3851 @SYMTestCaseID PBASE-USB-SC-1222 |
|
3852 @SYMTestCaseDesc Cancel Notifications |
|
3853 @SYMPREQ PREQ1846 |
|
3854 @SYMTestPriority |
|
3855 @SYMTestActions |
|
3856 Before Enumeration (negative tests) |
|
3857 1. Queue a notification for read. |
|
3858 2. Queue ReadCancel |
|
3859 3. Queue WriteData |
|
3860 4. Queue WriteCancel |
|
3861 After Enumeration (Positive Tests) |
|
3862 5. Queue a read notification and drain out the buffer of any data. Cancel the read. |
|
3863 6. Queue WriteData and cancel it with WriteCancel |
|
3864 @SYMTestExpectedResults |
|
3865 1. Notification should immediately return with KErrNone as device is not configured |
|
3866 2. API should almost immediately return with status as KErrCancel, panic otherwise |
|
3867 3. API should immediately return with KErrNone as device is not configured |
|
3868 4. API should almost immediately return with status as KErrCancel, panic otherwise |
|
3869 5. API should almost immediately return with status as KErrCancel, panic otherwise |
|
3870 6. Cancelling the request should return with KErrCancel, panic otherwise |
|
3871 */ |
|
3872 case ECancel: |
|
3873 { |
|
3874 test.Start(_L("PBASE-USB-SC-1222 Cancel Notifications Test \n")); |
|
3875 TestCancel(); |
|
3876 test.End(); |
|
3877 break; |
|
3878 } |
|
3879 /* ---------------------------------------------------------------------------- |
|
3880 @SYMTestCaseID PBASE-USB-SC-1223 |
|
3881 @SYMTestCaseDesc Invalid API Tests |
|
3882 @SYMPREQ PREQ1846 |
|
3883 @SYMTestPriority |
|
3884 @SYMTestActions |
|
3885 1. Call ReadDataNotify with invalid buffer numbers |
|
3886 a. Buffer does not exist. |
|
3887 b. Negative buffer Number |
|
3888 c. Buffer number corresponding to an IN endpoint |
|
3889 2. Test API with invalid parameters |
|
3890 a. Pass invalid buffer numbers to WriteData. Negative buffer numbers, buffer does not exist, buffer corresponding to an OUT endpoint. |
|
3891 b. Pass invalid buffer offsets to WriteData i.e. unaligned offset or an offset beyond end of buffer. |
|
3892 c. Pass invalid lenghts to WriteData i.e. length greater than the maximum size of buffer. |
|
3893 @SYMTestExpectedResults |
|
3894 1. a. API returns with KErrArgument. |
|
3895 b. API returns with KErrArgument. |
|
3896 c. API returns with KErrNotSupported. |
|
3897 2. a. Return with KErrArgument each case |
|
3898 b. Return with KErrArgument each case |
|
3899 c. Return with KErrArgument |
|
3900 */ |
|
3901 case EInvalidApi: |
|
3902 { |
|
3903 test.Start(_L("PBASE-USB-SC-1223 Invalid Api Tests \n")); |
|
3904 TestInvalidAPI(); |
|
3905 test.End(); |
|
3906 break; |
|
3907 } |
|
3908 /* ---------------------------------------------------------------------------- |
|
3909 @SYMTestCaseID PBASE-USB-SC-1224 |
|
3910 @SYMTestCaseDesc Descriptor Tests |
|
3911 @SYMPREQ PREQ1846 |
|
3912 @SYMTestPriority |
|
3913 @SYMTestActions |
|
3914 1. Test descriptor manipulation: validate the device, deviceQualifier, configuration, interface, endpoint, class specific, alternate interface, endpoint and string descriptor manipulation. |
|
3915 2. Test HaltEndpoint and ClearHaltEndpoint correctly result in endpoint status being reported as stalled/not stalled. |
|
3916 @SYMTestExpectedResults |
|
3917 1. All entries should match. |
|
3918 2. All entries should match. |
|
3919 */ |
|
3920 case EDescriptor: |
|
3921 { |
|
3922 test.Start(_L("PBASE-USB-SC-1224 Descriptor Tests \n")); |
|
3923 TestDescriptorManipulation(); |
|
3924 test.End(); |
|
3925 break; |
|
3926 } |
|
3927 default: |
|
3928 if (gSpecTest>=EBilRw) |
|
3929 TestBIL(); |
|
3930 else |
|
3931 test.Printf(_L("No such option \n")); |
|
3932 } |
|
3933 |
|
3934 |
|
3935 } |
|
3936 |
|
3937 void ProcessCommandLineOptions(void) |
|
3938 { |
|
3939 //ToDo: to put back in |
|
3940 // Open Driver and Check Device Capabilities - PowerUpUDC NOT Working |
|
3941 LoadDriver(); |
|
3942 OpenChannel(); |
|
3943 CheckDeviceCapabilities(); |
|
3944 test_KErrNone(SettingOne(0)); |
|
3945 TInt r; |
|
3946 r = gPort.RealizeInterface(gChunk); |
|
3947 test_KErrNone(r); |
|
3948 |
|
3949 TInt ifc_no = -1; |
|
3950 r = gPort.GetAlternateSetting(ifc_no); |
|
3951 test_Equal(KErrUsbDeviceNotConfigured, r); |
|
3952 |
|
3953 // Check for OTG support as if OTG is supported, client stack is disabled |
|
3954 TBuf8<KUsbDescSize_Otg> otg_desc; |
|
3955 r = gPort.GetOtgDescriptor(otg_desc); |
|
3956 test(r == KErrNotSupported || r == KErrNone); |
|
3957 TInt supportsOtg = (r != KErrNotSupported) ? ETrue : EFalse; |
|
3958 |
|
3959 // We turn on UDC here explicitly. This is done only once and just to test the API as such |
|
3960 test.Next(_L("Powering up UDC")); |
|
3961 r = gPort.PowerUpUdc(); |
|
3962 |
|
3963 if (!supportsOtg) |
|
3964 { |
|
3965 test_KErrNone(r); |
|
3966 } |
|
3967 else |
|
3968 { |
|
3969 test((r == KErrNone) || (r == KErrNotReady)); |
|
3970 } |
|
3971 |
|
3972 CloseChannel(); |
|
3973 UnloadDriver(); |
|
3974 if (gSpecTest == EAll) |
|
3975 { |
|
3976 for (TInt i = 1; i <= 7; i++) |
|
3977 { |
|
3978 gSpecTest = (TSpecTestType) i; |
|
3979 StartTests(); |
|
3980 } |
|
3981 for (TInt i = 100; i <= 102; i++) |
|
3982 { |
|
3983 gSpecTest = (TSpecTestType) i; |
|
3984 StartTests(); |
|
3985 } |
|
3986 |
|
3987 } |
|
3988 else |
|
3989 { |
|
3990 StartTests(); |
|
3991 } |
|
3992 } |
|
3993 |
|
3994 |
|
3995 |
|
3996 // - - - - - - - - - - - - - - - - - - - - - - - - - |
|
3997 |
|
3998 // |
|
3999 // ParseCommandLine reads the arguments and sets globals accordingly. |
|
4000 // |
|
4001 |
|
4002 TInt ParseCommandLine() |
|
4003 { |
|
4004 TBuf<32> args; |
|
4005 User::CommandLine(args); |
|
4006 TLex lex(args); |
|
4007 TInt err=KErrNone; |
|
4008 FOREVER |
|
4009 { |
|
4010 TPtrC token=lex.NextToken(); |
|
4011 TPtrC subtoken(_L("")); |
|
4012 |
|
4013 if(token.Length()!=0) |
|
4014 { |
|
4015 if ((token==_L("help")) || (token==_L("-h")) || (token==_L("/h")) || (token==_L("-?")) || (token==_L("/?"))) |
|
4016 { |
|
4017 test.Printf(_L("\nThis tests the Shared chunk version of the USBC driver. It focuses on the elements specific to this driver and should be used in conjuntion with other USBC tests in order to validate the driver.\n\n")); |
|
4018 test.Printf(_L("\n -h : Help.\n -r : test on Real hardware\n -v : Verbose\n -V : Very verbose\n-t <test> : Run a specific test.\n")); |
|
4019 test.Printf(_L("\nAvailable tests: buf_read, buf_write, ep0, altset, interface, cancel, api, descriptor, bil_rw, bil_ep0, bil_alt\n")); |
|
4020 err=KErrCancel; |
|
4021 } |
|
4022 else |
|
4023 if (token==_L("-r")) |
|
4024 gRealHardware = ETrue; |
|
4025 else |
|
4026 if (token==_L("-v")) |
|
4027 gVerbose = 1; |
|
4028 else |
|
4029 if (token==_L("-V")) |
|
4030 gVerbose = 2; |
|
4031 else |
|
4032 if (token==_L("-t")) |
|
4033 { |
|
4034 subtoken.Set(lex.NextToken()); |
|
4035 |
|
4036 if(subtoken.Length()!=0) |
|
4037 { |
|
4038 if (subtoken==_L("buf_read")) |
|
4039 { |
|
4040 gSpecTest=EBufRead; |
|
4041 gRealHardware = ETrue; |
|
4042 } |
|
4043 else if (subtoken==_L("buf_write")) |
|
4044 { |
|
4045 gSpecTest=EBufWrite; |
|
4046 gRealHardware = ETrue; |
|
4047 } |
|
4048 else if (subtoken==_L("ep0")) |
|
4049 { |
|
4050 gSpecTest=EEp0; |
|
4051 gRealHardware = ETrue; |
|
4052 } |
|
4053 else if (subtoken==_L("descriptor")) |
|
4054 gSpecTest=EDescriptor; |
|
4055 else if (subtoken==_L("interface")) |
|
4056 gSpecTest=EInterface; |
|
4057 else if (subtoken==_L("cancel")) |
|
4058 gSpecTest=ECancel; |
|
4059 else if (subtoken==_L("api")) |
|
4060 gSpecTest=EInvalidApi; |
|
4061 else if (subtoken==_L("bil_rw")) |
|
4062 { |
|
4063 gSpecTest=EBilRw; |
|
4064 gRealHardware = ETrue; |
|
4065 } |
|
4066 else if (subtoken==_L("bil_ep0")) |
|
4067 { |
|
4068 gSpecTest=EBilEp0; |
|
4069 gRealHardware = ETrue; |
|
4070 } |
|
4071 else if (subtoken==_L("bil_alt")) |
|
4072 { |
|
4073 gSpecTest=EBilAlt; |
|
4074 gRealHardware = ETrue; |
|
4075 } |
|
4076 else if (subtoken==_L("altset")) |
|
4077 { |
|
4078 gRealHardware = ETrue; |
|
4079 gSpecTest=EAltSet; |
|
4080 } |
|
4081 else |
|
4082 { |
|
4083 err=KErrArgument; |
|
4084 } |
|
4085 |
|
4086 } |
|
4087 else |
|
4088 { |
|
4089 subtoken.Set(_L("<NOTHING>")); |
|
4090 err = KErrArgument; |
|
4091 } |
|
4092 } // endif -t |
|
4093 else |
|
4094 { |
|
4095 err = KErrArgument; |
|
4096 } // endif token |
|
4097 } |
|
4098 else |
|
4099 break; |
|
4100 |
|
4101 if (err!=KErrNone) |
|
4102 { |
|
4103 if (err==KErrArgument) |
|
4104 test.Printf(_L("\nUnknown argument '%S%s%S'\n"), &token, (subtoken.Length()==0)?"":" ", &subtoken); |
|
4105 test.Printf(_L("\nUsage: t_usbcsc [-hrvVt]\n\n")); |
|
4106 test.Getch(); |
|
4107 return err; |
|
4108 } |
|
4109 } |
|
4110 return KErrNone; |
|
4111 } |
|
4112 |
|
4113 GLDEF_C TInt E32Main() |
|
4114 { |
|
4115 test.Title(); |
|
4116 __UHEAP_MARK; |
|
4117 if (ParseCommandLine()) |
|
4118 return KErrNone; |
|
4119 |
|
4120 test.Start(_L("USB client 'Shared Chunk' driver Tests")); |
|
4121 |
|
4122 TInt muid = 0; |
|
4123 TInt r = HAL::Get(HAL::EMachineUid, muid); |
|
4124 if (r != KErrNone) |
|
4125 { |
|
4126 test.Printf(_L("Unable to get Platform ID. Skipping tests\n")); |
|
4127 return KErrNone; |
|
4128 } |
|
4129 if (SupportsUsb() && (muid != HAL::EMachineUid_Lubbock)) |
|
4130 { |
|
4131 ProcessCommandLineOptions(); |
|
4132 } |
|
4133 else |
|
4134 { |
|
4135 test.Printf(_L("USB is not supported on this platform. Skipping test\n")); |
|
4136 } |
|
4137 |
|
4138 test.End(); |
|
4139 __UHEAP_MARKEND; |
|
4140 |
|
4141 return KErrNone; |
|
4142 } |
|
4143 |