1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-0482.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,522 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// @file PBASE-T_USBDI-0482.cpp
1.18 +// @internalComponent
1.19 +//
1.20 +//
1.21 +
1.22 +#include "PBASE-T_USBDI-0482.h"
1.23 +#include "tada22.h"
1.24 +#include <d32usbdescriptors.h>
1.25 +
1.26 +
1.27 +namespace NUnitTesting_USBDI
1.28 + {
1.29 +
1.30 +_LIT(KTestCaseId,"PBASE-T_USBDI-0482");
1.31 +const TFunctorTestCase<CUT_PBASE_T_USBDI_0482,TBool> CUT_PBASE_T_USBDI_0482::iFunctor(KTestCaseId);
1.32 +_LIT8(KHighRecordSamplingRate, "\x80\xBB\x00"); // sampling rate : 48,000 Hz
1.33 +_LIT8(KLowSamplingRate , "\x22\x56\x00"); // sampling rate : 22,050 Hz
1.34 +
1.35 +_LIT(KTrackFileName, "Z:\\scripts\\track.dat");
1.36 +
1.37 +const TInt KRecordedDataId = 0x12345;
1.38 +const TUint KRecordedPacketsExpected = 1000;
1.39 +const TUint KAudioCDQualityFrequency = 176; // 176 kB/s
1.40 +const TUint KMaxPacketSizeOutExpected = 192;
1.41 +const TUint KMaxPacketSizeInExpected = 96;
1.42 +const TUint KMaxPacketSizeOffset = 4;
1.43 +const TUint KIsochInMaxNumPackets = 2000;
1.44 +const TUint KChunkSize = 500000; // 0.5 Mb
1.45 +
1.46 +
1.47 +TInt CUT_PBASE_T_USBDI_0482::iExpectedTransferId = 0;
1.48 +
1.49 +CUT_PBASE_T_USBDI_0482* CUT_PBASE_T_USBDI_0482::NewL(TBool aHostRole)
1.50 + {
1.51 + CUT_PBASE_T_USBDI_0482* self = new (ELeave) CUT_PBASE_T_USBDI_0482(aHostRole);
1.52 + CleanupStack::PushL(self);
1.53 + self->ConstructL();
1.54 + CleanupStack::Pop(self);
1.55 + return self;
1.56 + }
1.57 +
1.58 +
1.59 +CUT_PBASE_T_USBDI_0482::CUT_PBASE_T_USBDI_0482(TBool aHostRole)
1.60 +: CBaseTestCase(KTestCaseId,aHostRole),
1.61 + iCaseStep(EInProgress)
1.62 + {
1.63 + iEndpointAddressIn = 0x84;
1.64 + iEndpointAddressOut = 0x01;
1.65 + iOutTransferBuf.CreateL(KChunkSize);
1.66 + }
1.67 +
1.68 +
1.69 +void CUT_PBASE_T_USBDI_0482::ConstructL()
1.70 + {
1.71 + BaseConstructL();
1.72 + }
1.73 +
1.74 +
1.75 +CUT_PBASE_T_USBDI_0482::~CUT_PBASE_T_USBDI_0482()
1.76 + {
1.77 + LOG_FUNC
1.78 +
1.79 + Cancel();
1.80 +
1.81 + // Close pipes before interfaces
1.82 + iPipeOut.Close();
1.83 + iPipeIn.Close();
1.84 +
1.85 + iUsbInterface0.Close();
1.86 + iUsbInterface1.Close();
1.87 + iUsbInterface2.Close();
1.88 +
1.89 + // Destroy transfers
1.90 + iOutTransfers.ResetAndDestroy();
1.91 +
1.92 + iOutTransferBuf.Close();
1.93 + iDataPolledBuf.Close();
1.94 +
1.95 + delete iIsochInTransfer;
1.96 + delete iControlEp0;
1.97 + delete iActorFDF;
1.98 + }
1.99 +
1.100 +void CUT_PBASE_T_USBDI_0482::ExecuteHostTestCaseL()
1.101 + {
1.102 + LOG_FUNC
1.103 +
1.104 + iActorFDF = CActorFDF::NewL(*this);
1.105 + iControlEp0 = new (ELeave) CEp0Transfer(iUsbInterface0);
1.106 + iActorFDF->Monitor();
1.107 +
1.108 + // Wait for the usb headset to be connected
1.109 + TimeoutIn(30);
1.110 + }
1.111 +
1.112 +
1.113 +void CUT_PBASE_T_USBDI_0482::HostDoCancel()
1.114 + {
1.115 + LOG_FUNC
1.116 + }
1.117 +
1.118 +
1.119 +void CUT_PBASE_T_USBDI_0482::ExecuteDeviceTestCaseL()
1.120 + {
1.121 + LOG_FUNC
1.122 + }
1.123 +
1.124 +
1.125 +void CUT_PBASE_T_USBDI_0482::DeviceDoCancel()
1.126 + {
1.127 + LOG_FUNC
1.128 + }
1.129 +
1.130 +
1.131 +void CUT_PBASE_T_USBDI_0482::DeviceStateChangeL(RUsbDevice::TDeviceState aPreviousState,RUsbDevice::TDeviceState aNewState,
1.132 + TInt aCompletionCode)
1.133 + {
1.134 + LOG_FUNC
1.135 + }
1.136 +
1.137 +
1.138 +TInt CUT_PBASE_T_USBDI_0482::FindOUTIsochronousEndpoint(TUsbGenericDescriptor*& aDescriptor)
1.139 + {
1.140 + LOG_FUNC
1.141 + aDescriptor = NULL;
1.142 +
1.143 + TUsbInterfaceDescriptor alternate;
1.144 + TInt err = iUsbInterface1.GetAlternateInterfaceDescriptor(1, alternate);
1.145 + if(err)
1.146 + {
1.147 + RDebug::Printf("iUsbInterface1.GetAlternateInterfaceDescriptor error = %d",err);
1.148 + return err;
1.149 + }
1.150 +
1.151 + TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
1.152 + while(descriptor)
1.153 + {
1.154 + RDebug::Printf("ibDescriptorType = %d", descriptor->ibDescriptorType);
1.155 + if(descriptor->ibDescriptorType == EEndpoint)
1.156 + {
1.157 + aDescriptor = descriptor;
1.158 + RDebug::Printf("found descriptor return KErrNone");
1.159 + return KErrNone;
1.160 + }
1.161 + descriptor = descriptor->iNextPeer;
1.162 + }
1.163 +
1.164 + return KErrNotFound;
1.165 + }
1.166 +
1.167 +
1.168 +TInt CUT_PBASE_T_USBDI_0482::FindINIsochronousEndpoint(TUsbGenericDescriptor*& aDescriptor)
1.169 + {
1.170 + LOG_FUNC
1.171 + aDescriptor = NULL;
1.172 +
1.173 + TUsbInterfaceDescriptor alternate;
1.174 + TInt err = iUsbInterface2.GetAlternateInterfaceDescriptor(1, alternate);
1.175 + if(err)
1.176 + {
1.177 + RDebug::Printf("iUsbInterface2.GetAlternateInterfaceDescriptor error = %d",err);
1.178 + return err;
1.179 + }
1.180 +
1.181 + TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
1.182 + while(descriptor)
1.183 + {
1.184 + RDebug::Printf("ibDescriptorType = %d", descriptor->ibDescriptorType);
1.185 + if(descriptor->ibDescriptorType == EEndpoint)
1.186 + {
1.187 + aDescriptor = descriptor;
1.188 + RDebug::Printf("found descriptor return KErrNone");
1.189 + return KErrNone;
1.190 + }
1.191 + descriptor = descriptor->iNextPeer;
1.192 + }
1.193 +
1.194 + return KErrNotFound;
1.195 + }
1.196 +
1.197 +
1.198 +
1.199 +void CUT_PBASE_T_USBDI_0482::DeviceInsertedL(TUint aDeviceHandle)
1.200 + {
1.201 + LOG_FUNC
1.202 +
1.203 + Cancel();
1.204 + CUsbTestDevice& testDevice = iActorFDF->DeviceL(aDeviceHandle);
1.205 +
1.206 + CHECK(CheckTreeAfterDeviceInsertion(testDevice, _L("RLogitechHeadSet")) == KErrNone);
1.207 +
1.208 + TUint32 token0, token1, token2;
1.209 + CHECK(testDevice.Device().GetTokenForInterface(0,token0) == KErrNone);
1.210 +
1.211 + CHECK(iUsbInterface0.Open(token0) == KErrNone); // Default interface setting 0
1.212 +
1.213 +
1.214 + // open interface 1, alt. sett. 1
1.215 + CHECK(testDevice.Device().GetTokenForInterface(1,token1) == KErrNone);
1.216 +
1.217 + CHECK(iUsbInterface1.Open(token1) == KErrNone); // Default interface setting 0
1.218 +
1.219 + RDebug::Printf("Selecting alternate interface setting 1");
1.220 + CHECK(iUsbInterface1.SelectAlternateInterface(1) == KErrNone);
1.221 +
1.222 +
1.223 + // open interface 2, alt. sett. 1
1.224 + CHECK(testDevice.Device().GetTokenForInterface(2,token2) == KErrNone);
1.225 +
1.226 + CHECK(iUsbInterface2.Open(token2) == KErrNone); // Default interface setting 0
1.227 +
1.228 +
1.229 + RDebug::Printf("Selecting alternate interface setting 1");
1.230 + CHECK(iUsbInterface2.SelectAlternateInterface(1) == KErrNone);
1.231 +
1.232 +
1.233 + iCaseStep = EWaitEndOfMusicTrack;
1.234 +
1.235 + // Open a pipe for endpoint (Isoch out)
1.236 + RDebug::Printf("Finding address for an out isoch endpoint on interface 1 setting 1");
1.237 + // Isochronous OUT
1.238 + TUsbGenericDescriptor* isochEpDescriptorOut;
1.239 + CHECK(KErrNone == FindOUTIsochronousEndpoint(isochEpDescriptorOut));
1.240 +
1.241 + // Get the maximum packet size for this isochronous endpoint
1.242 + TUint16 wMaxPacketSizeOut = isochEpDescriptorOut->TUint16At(KMaxPacketSizeOffset);
1.243 + RDebug::Printf("wMaxPacketSizeOut = %d", wMaxPacketSizeOut);
1.244 + CHECK(wMaxPacketSizeOut == KMaxPacketSizeOutExpected);
1.245 +
1.246 + // Isochronous IN
1.247 + TUsbGenericDescriptor* isochEpDescriptorIn;
1.248 + CHECK(KErrNone == FindINIsochronousEndpoint(isochEpDescriptorIn));
1.249 +
1.250 + // Get the maximum packet size for this isochronous endpoint
1.251 + TUint16 wMaxPacketSizeIn = isochEpDescriptorIn->TUint16At(KMaxPacketSizeOffset);
1.252 + RDebug::Printf("wMaxPacketSizeIn = %d", wMaxPacketSizeIn);
1.253 + CHECK(wMaxPacketSizeIn == KMaxPacketSizeInExpected);
1.254 +
1.255 +
1.256 + // open pipes now.
1.257 + // Out
1.258 + RDebug::Printf("Opening a pipe to %08x",iEndpointAddressOut);
1.259 + CHECK(iUsbInterface1.OpenPipeForEndpoint(iPipeOut,iEndpointAddressOut,EFalse) == KErrNone);
1.260 +
1.261 + RDebug::Printf("Opened pipe to endpoint address %08x for isochronous transfer to device",iEndpointAddressOut);
1.262 +
1.263 + // In
1.264 + RDebug::Printf("Opening a pipe to %08x",iEndpointAddressIn);
1.265 + CHECK(iUsbInterface2.OpenPipeForEndpoint(iPipeIn,iEndpointAddressIn,EFalse) == KErrNone);
1.266 +
1.267 + RDebug::Printf("Opened pipe to endpoint address %08x for isochronous transfer to device",iEndpointAddressIn);
1.268 +
1.269 + // SET_CUR class specific command
1.270 + TSetCurRequest request(KHighRecordSamplingRate ,iEndpointAddressIn);
1.271 + iControlEp0->SendRequest(request,this);
1.272 +
1.273 + // Que transfers now
1.274 + // Transfer IN
1.275 + iIsochInTransfer = new (ELeave) CIsochTransfer(iPipeIn,iUsbInterface2,wMaxPacketSizeIn,
1.276 + KIsochInMaxNumPackets ,*this, KRecordedDataId);
1.277 +
1.278 + CHECK(iIsochInTransfer->RegisterTransferDescriptor() == KErrNone);
1.279 +
1.280 + // Initialise the descriptors for transfer
1.281 + RDebug::Printf("Initialising the transfer descriptors interface 2");
1.282 + CHECK(iUsbInterface2.InitialiseTransferDescriptors() == KErrNone);
1.283 +
1.284 +
1.285 + // que interrupt transfer
1.286 + CHECK(iIsochInTransfer->TransferInL(KRecordedPacketsExpected) == KErrNone);
1.287 +
1.288 +
1.289 + // Transfer OUT
1.290 + RFs iFs;
1.291 + TInt ret = KErrNone;
1.292 + ret = iFs.Connect();
1.293 + CHECK(ret==KErrNone || ret==KErrAlreadyExists);
1.294 + RFile trackFile;
1.295 + CHECK(trackFile.Open(iFs,KTrackFileName,EFileShareAny|EFileRead) == KErrNone);
1.296 +
1.297 +
1.298 + TInt trackFileSize;
1.299 + trackFile.Size(trackFileSize);
1.300 +
1.301 +
1.302 + wMaxPacketSizeOut = KAudioCDQualityFrequency;
1.303 +
1.304 + TInt nbChunks = trackFileSize/KChunkSize;
1.305 + TInt remainderSize = trackFileSize%KChunkSize;
1.306 +
1.307 + if(remainderSize != 0)
1.308 + {
1.309 + nbChunks++;
1.310 + }
1.311 +
1.312 + TInt iChunk = 0;
1.313 + TInt size = KChunkSize;
1.314 +
1.315 + // create Transfers
1.316 + for(iChunk = 0; iChunk < nbChunks; iChunk++)
1.317 + {
1.318 + RDebug::Printf("iChunk = %d", iChunk);
1.319 +
1.320 + // remainder(last loop)
1.321 + if(remainderSize != 0 && (iChunk == nbChunks-1))
1.322 + {
1.323 + size = remainderSize;
1.324 + }
1.325 + CIsochTransfer* transfer = new (ELeave) CIsochTransfer(iPipeOut,iUsbInterface1,wMaxPacketSizeOut,
1.326 + (size/wMaxPacketSizeOut),*this, iChunk);
1.327 + CHECK(transfer->RegisterTransferDescriptor() == KErrNone);
1.328 + iOutTransfers.AppendL(transfer);
1.329 + iOutTransferBuf.Zero();
1.330 + }
1.331 +
1.332 + // Initialise the descriptors for transfer
1.333 + RDebug::Printf("Initialising the transfer descriptors");
1.334 + CHECK(iUsbInterface1.InitialiseTransferDescriptors() == KErrNone);
1.335 +
1.336 + // prepare & send transfers(TODO streaming algorithm with 3 Transfers only, filling 2 while the 3rd is transferring his data)
1.337 + size = KChunkSize;
1.338 + for(TInt iTransfers = 0; iTransfers < iOutTransfers.Count(); iTransfers++)
1.339 + {
1.340 + RDebug::Printf("iTransfers = %d", iTransfers);
1.341 + // remainder(last loop)
1.342 + if(remainderSize != 0 && (iTransfers == iOutTransfers.Count()-1))
1.343 + {
1.344 + RDebug::Printf("remainderSize = %d", remainderSize);
1.345 + size = remainderSize;
1.346 + }
1.347 + CHECK(trackFile.Read(KChunkSize*iTransfers, iOutTransferBuf, size) == KErrNone);
1.348 + CHECK(iOutTransfers[iTransfers]->PrepareTransfer(iOutTransferBuf) == KErrNone);
1.349 + CHECK(iOutTransfers[iTransfers]->TransferOut() == KErrNone);
1.350 + iOutTransferBuf.Zero();
1.351 + }
1.352 + }
1.353 +
1.354 +TBool CUT_PBASE_T_USBDI_0482::ReplayRecordedData()
1.355 + {
1.356 + LOG_FUNC
1.357 +
1.358 + iOutTransferBuf.Zero();
1.359 +
1.360 + // Transfer OUT
1.361 + TInt nbChunks = iDataPolledBuf.Length()/KChunkSize;
1.362 + TInt remainderSize = iDataPolledBuf.Length()%KChunkSize;
1.363 + RDebug::Printf("nbChunks = %d", nbChunks);
1.364 + RDebug::Printf("remainderSize = %d", remainderSize);
1.365 +
1.366 + if(remainderSize != 0)
1.367 + {
1.368 + nbChunks++;
1.369 + }
1.370 +
1.371 + // prepare transfers
1.372 + for(TInt iTransfers = 0; iTransfers < nbChunks; iTransfers++)
1.373 + {
1.374 + RDebug::Printf("iTransfers = %d", iTransfers);
1.375 + // remainder(last loop)
1.376 + if(remainderSize != 0 && (iTransfers == nbChunks-1))
1.377 + {
1.378 + RDebug::Printf("remainderSize = %d", remainderSize);
1.379 + }
1.380 + CHECK_RET_BOOL(iOutTransfers[iTransfers]->PrepareTransfer(iDataPolledBuf) == KErrNone); // TODO retrieve relevant part of iDataPolledBuf if several chunks
1.381 + CHECK_RET_BOOL(iOutTransfers[iTransfers]->TransferOut() == KErrNone);
1.382 + iOutTransferBuf.Zero();
1.383 + }
1.384 + return ETrue;
1.385 + }
1.386 +
1.387 +void CUT_PBASE_T_USBDI_0482::TransferCompleteL(TInt aTransferId,TInt aCompletionCode)
1.388 + {
1.389 + LOG_FUNC
1.390 + RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d",aTransferId, aCompletionCode);
1.391 + Cancel();
1.392 +
1.393 + if(aCompletionCode != KErrNone)
1.394 + {
1.395 + RDebug::Printf("<Error %d> Transfer %d not successful",aCompletionCode,aTransferId);
1.396 + TestFailed(aCompletionCode);
1.397 + return;
1.398 + }
1.399 +
1.400 + if(aTransferId == KRecordedDataId)
1.401 + {
1.402 + // data successfully recorded
1.403 + // 1. save data recorded
1.404 + CHECK(iIsochInTransfer->DataPolled(KRecordedPacketsExpected, iDataPolledBuf));
1.405 + // 2. waiting now for the end of the music track
1.406 + return;
1.407 + }
1.408 +
1.409 + switch(iCaseStep)
1.410 + {
1.411 + case EWaitEndOfMusicTrack:
1.412 + {
1.413 + if(aTransferId != iExpectedTransferId)
1.414 + {
1.415 + RDebug::Printf("unexpected transfer!");
1.416 + TestFailed(KErrCorrupt);
1.417 + }
1.418 + iExpectedTransferId++;
1.419 + // is it the last transfer?
1.420 + if(iExpectedTransferId == iOutTransfers.Count())
1.421 + {
1.422 + RDebug::Printf("last transfer successful! lets replay recorded data");
1.423 +
1.424 + iCaseStep = EReplayRecordedData; // assuming that recording is finished
1.425 + TSetCurRequest request(KLowSamplingRate ,iEndpointAddressOut);
1.426 + iControlEp0->SendRequest(request,this);
1.427 + }
1.428 + }
1.429 + break;
1.430 +
1.431 + case EReplayRecordedData:
1.432 + {
1.433 + TestPassed(); // TODO only one transfer used in this case(few data recorded), cope with several ones
1.434 + }
1.435 + break;
1.436 +
1.437 + default:
1.438 + TestFailed(KErrDisconnected);
1.439 + break;
1.440 + }
1.441 + }
1.442 +
1.443 +void CUT_PBASE_T_USBDI_0482::Ep0TransferCompleteL(TInt aCompletionCode)
1.444 + {
1.445 + LOG_FUNC
1.446 + RDebug::Printf("Transfer EP0 completed aCompletionCode = %d", aCompletionCode);
1.447 +
1.448 + if(aCompletionCode != KErrNone)
1.449 + {
1.450 + TBuf<256> msg;
1.451 + msg.Format(_L("<Error %d> Transfer to control endpoint 0 was not successful"),aCompletionCode);
1.452 + RDebug::Print(msg);
1.453 + return;
1.454 + }
1.455 + switch(iCaseStep)
1.456 + {
1.457 + case EWaitEndOfMusicTrack:
1.458 + break;
1.459 +
1.460 + case EReplayRecordedData:
1.461 + {
1.462 + CHECK(ReplayRecordedData());
1.463 + }
1.464 + break;
1.465 +
1.466 + default:
1.467 + RDebug::Printf("<Error> Unknown test step");
1.468 + TestFailed(KErrUnknown);
1.469 + break;
1.470 + }
1.471 + }
1.472 +
1.473 +
1.474 +void CUT_PBASE_T_USBDI_0482::DeviceRemovedL(TUint aDeviceHandle)
1.475 + {
1.476 + LOG_FUNC
1.477 +
1.478 + // Manual test over
1.479 + switch(iCaseStep)
1.480 + {
1.481 + case EFailed:
1.482 + TestFailed(KErrCompletion);
1.483 + break;
1.484 +
1.485 + case EInProgress:
1.486 + default:
1.487 + TestFailed(KErrDisconnected);
1.488 + break;
1.489 + }
1.490 + }
1.491 +
1.492 +
1.493 +void CUT_PBASE_T_USBDI_0482::BusErrorL(TInt aError)
1.494 + {
1.495 + LOG_FUNC
1.496 + // This test case handles no failiures on the bus
1.497 + TestFailed(KErrCompletion);
1.498 + }
1.499 +
1.500 +
1.501 +void CUT_PBASE_T_USBDI_0482::HostRunL()
1.502 + {
1.503 + LOG_FUNC
1.504 +
1.505 + // Obtain the completion code
1.506 + TInt completionCode(iStatus.Int());
1.507 +
1.508 + if(completionCode == KErrNone)
1.509 + {
1.510 + // Action timeout
1.511 + RDebug::Printf("<Error> Action timeout");
1.512 + TestFailed(KErrTimedOut);
1.513 + }
1.514 + else
1.515 + {
1.516 + RDebug::Printf("<Error %d> Timeout timer could not complete",completionCode);
1.517 + TestFailed(completionCode);
1.518 + }
1.519 + }
1.520 +
1.521 +void CUT_PBASE_T_USBDI_0482::DeviceRunL()
1.522 + {
1.523 + }
1.524 +
1.525 + }