Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // @file PBASE-T_USBDI-0482.cpp
19 #include "PBASE-T_USBDI-0482.h"
21 #include <d32usbdescriptors.h>
24 namespace NUnitTesting_USBDI
27 _LIT(KTestCaseId,"PBASE-T_USBDI-0482");
28 const TFunctorTestCase<CUT_PBASE_T_USBDI_0482,TBool> CUT_PBASE_T_USBDI_0482::iFunctor(KTestCaseId);
29 _LIT8(KHighRecordSamplingRate, "\x80\xBB\x00"); // sampling rate : 48,000 Hz
30 _LIT8(KLowSamplingRate , "\x22\x56\x00"); // sampling rate : 22,050 Hz
32 _LIT(KTrackFileName, "Z:\\scripts\\track.dat");
34 const TInt KRecordedDataId = 0x12345;
35 const TUint KRecordedPacketsExpected = 1000;
36 const TUint KAudioCDQualityFrequency = 176; // 176 kB/s
37 const TUint KMaxPacketSizeOutExpected = 192;
38 const TUint KMaxPacketSizeInExpected = 96;
39 const TUint KMaxPacketSizeOffset = 4;
40 const TUint KIsochInMaxNumPackets = 2000;
41 const TUint KChunkSize = 500000; // 0.5 Mb
44 TInt CUT_PBASE_T_USBDI_0482::iExpectedTransferId = 0;
46 CUT_PBASE_T_USBDI_0482* CUT_PBASE_T_USBDI_0482::NewL(TBool aHostRole)
48 CUT_PBASE_T_USBDI_0482* self = new (ELeave) CUT_PBASE_T_USBDI_0482(aHostRole);
49 CleanupStack::PushL(self);
51 CleanupStack::Pop(self);
56 CUT_PBASE_T_USBDI_0482::CUT_PBASE_T_USBDI_0482(TBool aHostRole)
57 : CBaseTestCase(KTestCaseId,aHostRole),
58 iCaseStep(EInProgress)
60 iEndpointAddressIn = 0x84;
61 iEndpointAddressOut = 0x01;
62 iOutTransferBuf.CreateL(KChunkSize);
66 void CUT_PBASE_T_USBDI_0482::ConstructL()
72 CUT_PBASE_T_USBDI_0482::~CUT_PBASE_T_USBDI_0482()
78 // Close pipes before interfaces
82 iUsbInterface0.Close();
83 iUsbInterface1.Close();
84 iUsbInterface2.Close();
87 iOutTransfers.ResetAndDestroy();
89 iOutTransferBuf.Close();
90 iDataPolledBuf.Close();
92 delete iIsochInTransfer;
97 void CUT_PBASE_T_USBDI_0482::ExecuteHostTestCaseL()
101 iActorFDF = CActorFDF::NewL(*this);
102 iControlEp0 = new (ELeave) CEp0Transfer(iUsbInterface0);
103 iActorFDF->Monitor();
105 // Wait for the usb headset to be connected
110 void CUT_PBASE_T_USBDI_0482::HostDoCancel()
116 void CUT_PBASE_T_USBDI_0482::ExecuteDeviceTestCaseL()
122 void CUT_PBASE_T_USBDI_0482::DeviceDoCancel()
128 void CUT_PBASE_T_USBDI_0482::DeviceStateChangeL(RUsbDevice::TDeviceState aPreviousState,RUsbDevice::TDeviceState aNewState,
129 TInt aCompletionCode)
135 TInt CUT_PBASE_T_USBDI_0482::FindOUTIsochronousEndpoint(TUsbGenericDescriptor*& aDescriptor)
140 TUsbInterfaceDescriptor alternate;
141 TInt err = iUsbInterface1.GetAlternateInterfaceDescriptor(1, alternate);
144 RDebug::Printf("iUsbInterface1.GetAlternateInterfaceDescriptor error = %d",err);
148 TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
151 RDebug::Printf("ibDescriptorType = %d", descriptor->ibDescriptorType);
152 if(descriptor->ibDescriptorType == EEndpoint)
154 aDescriptor = descriptor;
155 RDebug::Printf("found descriptor return KErrNone");
158 descriptor = descriptor->iNextPeer;
165 TInt CUT_PBASE_T_USBDI_0482::FindINIsochronousEndpoint(TUsbGenericDescriptor*& aDescriptor)
170 TUsbInterfaceDescriptor alternate;
171 TInt err = iUsbInterface2.GetAlternateInterfaceDescriptor(1, alternate);
174 RDebug::Printf("iUsbInterface2.GetAlternateInterfaceDescriptor error = %d",err);
178 TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
181 RDebug::Printf("ibDescriptorType = %d", descriptor->ibDescriptorType);
182 if(descriptor->ibDescriptorType == EEndpoint)
184 aDescriptor = descriptor;
185 RDebug::Printf("found descriptor return KErrNone");
188 descriptor = descriptor->iNextPeer;
196 void CUT_PBASE_T_USBDI_0482::DeviceInsertedL(TUint aDeviceHandle)
201 CUsbTestDevice& testDevice = iActorFDF->DeviceL(aDeviceHandle);
203 CHECK(CheckTreeAfterDeviceInsertion(testDevice, _L("RLogitechHeadSet")) == KErrNone);
205 TUint32 token0, token1, token2;
206 CHECK(testDevice.Device().GetTokenForInterface(0,token0) == KErrNone);
208 CHECK(iUsbInterface0.Open(token0) == KErrNone); // Default interface setting 0
211 // open interface 1, alt. sett. 1
212 CHECK(testDevice.Device().GetTokenForInterface(1,token1) == KErrNone);
214 CHECK(iUsbInterface1.Open(token1) == KErrNone); // Default interface setting 0
216 RDebug::Printf("Selecting alternate interface setting 1");
217 CHECK(iUsbInterface1.SelectAlternateInterface(1) == KErrNone);
220 // open interface 2, alt. sett. 1
221 CHECK(testDevice.Device().GetTokenForInterface(2,token2) == KErrNone);
223 CHECK(iUsbInterface2.Open(token2) == KErrNone); // Default interface setting 0
226 RDebug::Printf("Selecting alternate interface setting 1");
227 CHECK(iUsbInterface2.SelectAlternateInterface(1) == KErrNone);
230 iCaseStep = EWaitEndOfMusicTrack;
232 // Open a pipe for endpoint (Isoch out)
233 RDebug::Printf("Finding address for an out isoch endpoint on interface 1 setting 1");
235 TUsbGenericDescriptor* isochEpDescriptorOut;
236 CHECK(KErrNone == FindOUTIsochronousEndpoint(isochEpDescriptorOut));
238 // Get the maximum packet size for this isochronous endpoint
239 TUint16 wMaxPacketSizeOut = isochEpDescriptorOut->TUint16At(KMaxPacketSizeOffset);
240 RDebug::Printf("wMaxPacketSizeOut = %d", wMaxPacketSizeOut);
241 CHECK(wMaxPacketSizeOut == KMaxPacketSizeOutExpected);
244 TUsbGenericDescriptor* isochEpDescriptorIn;
245 CHECK(KErrNone == FindINIsochronousEndpoint(isochEpDescriptorIn));
247 // Get the maximum packet size for this isochronous endpoint
248 TUint16 wMaxPacketSizeIn = isochEpDescriptorIn->TUint16At(KMaxPacketSizeOffset);
249 RDebug::Printf("wMaxPacketSizeIn = %d", wMaxPacketSizeIn);
250 CHECK(wMaxPacketSizeIn == KMaxPacketSizeInExpected);
255 RDebug::Printf("Opening a pipe to %08x",iEndpointAddressOut);
256 CHECK(iUsbInterface1.OpenPipeForEndpoint(iPipeOut,iEndpointAddressOut,EFalse) == KErrNone);
258 RDebug::Printf("Opened pipe to endpoint address %08x for isochronous transfer to device",iEndpointAddressOut);
261 RDebug::Printf("Opening a pipe to %08x",iEndpointAddressIn);
262 CHECK(iUsbInterface2.OpenPipeForEndpoint(iPipeIn,iEndpointAddressIn,EFalse) == KErrNone);
264 RDebug::Printf("Opened pipe to endpoint address %08x for isochronous transfer to device",iEndpointAddressIn);
266 // SET_CUR class specific command
267 TSetCurRequest request(KHighRecordSamplingRate ,iEndpointAddressIn);
268 iControlEp0->SendRequest(request,this);
272 iIsochInTransfer = new (ELeave) CIsochTransfer(iPipeIn,iUsbInterface2,wMaxPacketSizeIn,
273 KIsochInMaxNumPackets ,*this, KRecordedDataId);
275 CHECK(iIsochInTransfer->RegisterTransferDescriptor() == KErrNone);
277 // Initialise the descriptors for transfer
278 RDebug::Printf("Initialising the transfer descriptors interface 2");
279 CHECK(iUsbInterface2.InitialiseTransferDescriptors() == KErrNone);
282 // que interrupt transfer
283 CHECK(iIsochInTransfer->TransferInL(KRecordedPacketsExpected) == KErrNone);
290 CHECK(ret==KErrNone || ret==KErrAlreadyExists);
292 CHECK(trackFile.Open(iFs,KTrackFileName,EFileShareAny|EFileRead) == KErrNone);
296 trackFile.Size(trackFileSize);
299 wMaxPacketSizeOut = KAudioCDQualityFrequency;
301 TInt nbChunks = trackFileSize/KChunkSize;
302 TInt remainderSize = trackFileSize%KChunkSize;
304 if(remainderSize != 0)
310 TInt size = KChunkSize;
313 for(iChunk = 0; iChunk < nbChunks; iChunk++)
315 RDebug::Printf("iChunk = %d", iChunk);
317 // remainder(last loop)
318 if(remainderSize != 0 && (iChunk == nbChunks-1))
320 size = remainderSize;
322 CIsochTransfer* transfer = new (ELeave) CIsochTransfer(iPipeOut,iUsbInterface1,wMaxPacketSizeOut,
323 (size/wMaxPacketSizeOut),*this, iChunk);
324 CHECK(transfer->RegisterTransferDescriptor() == KErrNone);
325 iOutTransfers.AppendL(transfer);
326 iOutTransferBuf.Zero();
329 // Initialise the descriptors for transfer
330 RDebug::Printf("Initialising the transfer descriptors");
331 CHECK(iUsbInterface1.InitialiseTransferDescriptors() == KErrNone);
333 // prepare & send transfers(TODO streaming algorithm with 3 Transfers only, filling 2 while the 3rd is transferring his data)
335 for(TInt iTransfers = 0; iTransfers < iOutTransfers.Count(); iTransfers++)
337 RDebug::Printf("iTransfers = %d", iTransfers);
338 // remainder(last loop)
339 if(remainderSize != 0 && (iTransfers == iOutTransfers.Count()-1))
341 RDebug::Printf("remainderSize = %d", remainderSize);
342 size = remainderSize;
344 CHECK(trackFile.Read(KChunkSize*iTransfers, iOutTransferBuf, size) == KErrNone);
345 CHECK(iOutTransfers[iTransfers]->PrepareTransfer(iOutTransferBuf) == KErrNone);
346 CHECK(iOutTransfers[iTransfers]->TransferOut() == KErrNone);
347 iOutTransferBuf.Zero();
351 TBool CUT_PBASE_T_USBDI_0482::ReplayRecordedData()
355 iOutTransferBuf.Zero();
358 TInt nbChunks = iDataPolledBuf.Length()/KChunkSize;
359 TInt remainderSize = iDataPolledBuf.Length()%KChunkSize;
360 RDebug::Printf("nbChunks = %d", nbChunks);
361 RDebug::Printf("remainderSize = %d", remainderSize);
363 if(remainderSize != 0)
369 for(TInt iTransfers = 0; iTransfers < nbChunks; iTransfers++)
371 RDebug::Printf("iTransfers = %d", iTransfers);
372 // remainder(last loop)
373 if(remainderSize != 0 && (iTransfers == nbChunks-1))
375 RDebug::Printf("remainderSize = %d", remainderSize);
377 CHECK_RET_BOOL(iOutTransfers[iTransfers]->PrepareTransfer(iDataPolledBuf) == KErrNone); // TODO retrieve relevant part of iDataPolledBuf if several chunks
378 CHECK_RET_BOOL(iOutTransfers[iTransfers]->TransferOut() == KErrNone);
379 iOutTransferBuf.Zero();
384 void CUT_PBASE_T_USBDI_0482::TransferCompleteL(TInt aTransferId,TInt aCompletionCode)
387 RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d",aTransferId, aCompletionCode);
390 if(aCompletionCode != KErrNone)
392 RDebug::Printf("<Error %d> Transfer %d not successful",aCompletionCode,aTransferId);
393 TestFailed(aCompletionCode);
397 if(aTransferId == KRecordedDataId)
399 // data successfully recorded
400 // 1. save data recorded
401 CHECK(iIsochInTransfer->DataPolled(KRecordedPacketsExpected, iDataPolledBuf));
402 // 2. waiting now for the end of the music track
408 case EWaitEndOfMusicTrack:
410 if(aTransferId != iExpectedTransferId)
412 RDebug::Printf("unexpected transfer!");
413 TestFailed(KErrCorrupt);
415 iExpectedTransferId++;
416 // is it the last transfer?
417 if(iExpectedTransferId == iOutTransfers.Count())
419 RDebug::Printf("last transfer successful! lets replay recorded data");
421 iCaseStep = EReplayRecordedData; // assuming that recording is finished
422 TSetCurRequest request(KLowSamplingRate ,iEndpointAddressOut);
423 iControlEp0->SendRequest(request,this);
428 case EReplayRecordedData:
430 TestPassed(); // TODO only one transfer used in this case(few data recorded), cope with several ones
435 TestFailed(KErrDisconnected);
440 void CUT_PBASE_T_USBDI_0482::Ep0TransferCompleteL(TInt aCompletionCode)
443 RDebug::Printf("Transfer EP0 completed aCompletionCode = %d", aCompletionCode);
445 if(aCompletionCode != KErrNone)
448 msg.Format(_L("<Error %d> Transfer to control endpoint 0 was not successful"),aCompletionCode);
454 case EWaitEndOfMusicTrack:
457 case EReplayRecordedData:
459 CHECK(ReplayRecordedData());
464 RDebug::Printf("<Error> Unknown test step");
465 TestFailed(KErrUnknown);
471 void CUT_PBASE_T_USBDI_0482::DeviceRemovedL(TUint aDeviceHandle)
479 TestFailed(KErrCompletion);
484 TestFailed(KErrDisconnected);
490 void CUT_PBASE_T_USBDI_0482::BusErrorL(TInt aError)
493 // This test case handles no failiures on the bus
494 TestFailed(KErrCompletion);
498 void CUT_PBASE_T_USBDI_0482::HostRunL()
502 // Obtain the completion code
503 TInt completionCode(iStatus.Int());
505 if(completionCode == KErrNone)
508 RDebug::Printf("<Error> Action timeout");
509 TestFailed(KErrTimedOut);
513 RDebug::Printf("<Error %d> Timeout timer could not complete",completionCode);
514 TestFailed(completionCode);
518 void CUT_PBASE_T_USBDI_0482::DeviceRunL()