os/kernelhwsrv/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-0482.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // @file PBASE-T_USBDI-0482.cpp
    15 // @internalComponent
    16 // 
    17 //
    18 
    19 #include "PBASE-T_USBDI-0482.h"
    20 #include "tada22.h"
    21 #include <d32usbdescriptors.h>
    22 
    23 
    24 namespace NUnitTesting_USBDI
    25 	{
    26 	
    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
    31 
    32 _LIT(KTrackFileName, "Z:\\scripts\\track.dat");
    33 
    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
    42 
    43 
    44 TInt CUT_PBASE_T_USBDI_0482::iExpectedTransferId = 0;
    45 
    46 CUT_PBASE_T_USBDI_0482* CUT_PBASE_T_USBDI_0482::NewL(TBool aHostRole)
    47 	{
    48 	CUT_PBASE_T_USBDI_0482* self = new (ELeave) CUT_PBASE_T_USBDI_0482(aHostRole);
    49 	CleanupStack::PushL(self);
    50 	self->ConstructL();
    51 	CleanupStack::Pop(self);
    52 	return self;
    53 	}
    54 	
    55 
    56 CUT_PBASE_T_USBDI_0482::CUT_PBASE_T_USBDI_0482(TBool aHostRole)
    57 :	CBaseTestCase(KTestCaseId,aHostRole),
    58 	iCaseStep(EInProgress)
    59 	{
    60 	iEndpointAddressIn = 0x84;
    61 	iEndpointAddressOut = 0x01;
    62 	iOutTransferBuf.CreateL(KChunkSize);
    63 	} 
    64 
    65 
    66 void CUT_PBASE_T_USBDI_0482::ConstructL()
    67 	{
    68 	BaseConstructL();
    69 	}
    70 
    71 
    72 CUT_PBASE_T_USBDI_0482::~CUT_PBASE_T_USBDI_0482()
    73 	{
    74 	LOG_FUNC
    75 	
    76 	Cancel();
    77 		
    78 	// Close pipes before interfaces	
    79 	iPipeOut.Close();
    80 	iPipeIn.Close();
    81 	
    82 	iUsbInterface0.Close();
    83 	iUsbInterface1.Close();
    84 	iUsbInterface2.Close();
    85 
    86 	// Destroy transfers
    87 	iOutTransfers.ResetAndDestroy();
    88 	
    89 	iOutTransferBuf.Close();
    90 	iDataPolledBuf.Close();
    91 	
    92 	delete iIsochInTransfer;
    93 	delete iControlEp0;
    94 	delete iActorFDF;
    95 	}
    96 	
    97 void CUT_PBASE_T_USBDI_0482::ExecuteHostTestCaseL()	
    98 	{
    99 	LOG_FUNC
   100 	
   101 	iActorFDF = CActorFDF::NewL(*this);
   102 	iControlEp0 = new (ELeave) CEp0Transfer(iUsbInterface0);
   103 	iActorFDF->Monitor();
   104 	
   105 	// Wait for the usb headset to be connected	
   106 	TimeoutIn(30);
   107 	}
   108 
   109 		
   110 void CUT_PBASE_T_USBDI_0482::HostDoCancel()
   111 	{
   112 	LOG_FUNC	
   113 	}	
   114 	
   115 
   116 void CUT_PBASE_T_USBDI_0482::ExecuteDeviceTestCaseL()	
   117 	{
   118 	LOG_FUNC
   119 	}
   120 		
   121 	
   122 void CUT_PBASE_T_USBDI_0482::DeviceDoCancel()
   123 	{
   124 	LOG_FUNC
   125 	}
   126 	
   127 	
   128 void CUT_PBASE_T_USBDI_0482::DeviceStateChangeL(RUsbDevice::TDeviceState aPreviousState,RUsbDevice::TDeviceState aNewState,
   129 		TInt aCompletionCode)
   130 	{
   131 	LOG_FUNC	
   132 	}
   133 	
   134 
   135 TInt CUT_PBASE_T_USBDI_0482::FindOUTIsochronousEndpoint(TUsbGenericDescriptor*& aDescriptor)
   136 	{
   137 	LOG_FUNC	
   138 	aDescriptor = NULL;
   139 
   140 	TUsbInterfaceDescriptor alternate;
   141 	TInt err = iUsbInterface1.GetAlternateInterfaceDescriptor(1, alternate);
   142 	if(err)
   143 		{
   144 		RDebug::Printf("iUsbInterface1.GetAlternateInterfaceDescriptor error = %d",err);
   145 		return err;
   146 		} 
   147 
   148 	TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
   149 	while(descriptor)
   150 		{
   151 		RDebug::Printf("ibDescriptorType = %d", descriptor->ibDescriptorType);
   152 		if(descriptor->ibDescriptorType == EEndpoint)
   153 			{
   154 			aDescriptor = descriptor;
   155 			RDebug::Printf("found descriptor return KErrNone");
   156 			return KErrNone;
   157 			}	
   158 		descriptor = descriptor->iNextPeer;
   159 		}
   160 
   161 	return KErrNotFound;	
   162 	}
   163 
   164 	
   165 TInt CUT_PBASE_T_USBDI_0482::FindINIsochronousEndpoint(TUsbGenericDescriptor*& aDescriptor)
   166 	{
   167 	LOG_FUNC	
   168 	aDescriptor = NULL;
   169 
   170 	TUsbInterfaceDescriptor alternate;
   171 	TInt err = iUsbInterface2.GetAlternateInterfaceDescriptor(1, alternate);
   172 	if(err)
   173 		{
   174 		RDebug::Printf("iUsbInterface2.GetAlternateInterfaceDescriptor error = %d",err);
   175 		return err;
   176 		} 
   177 
   178 	TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
   179 	while(descriptor)
   180 		{
   181 		RDebug::Printf("ibDescriptorType = %d", descriptor->ibDescriptorType);
   182 		if(descriptor->ibDescriptorType == EEndpoint)
   183 			{
   184 			aDescriptor = descriptor;
   185 			RDebug::Printf("found descriptor return KErrNone");
   186 			return KErrNone;
   187 			}
   188 		descriptor = descriptor->iNextPeer;
   189 		}
   190 
   191 	return KErrNotFound;	
   192 	}	
   193 	
   194 		
   195 	
   196 void CUT_PBASE_T_USBDI_0482::DeviceInsertedL(TUint aDeviceHandle)
   197 	{
   198 	LOG_FUNC
   199 	
   200 	Cancel();
   201 	CUsbTestDevice& testDevice = iActorFDF->DeviceL(aDeviceHandle);
   202 	
   203 	CHECK(CheckTreeAfterDeviceInsertion(testDevice, _L("RLogitechHeadSet")) == KErrNone);
   204 	
   205 	TUint32 token0, token1, token2;
   206 	CHECK(testDevice.Device().GetTokenForInterface(0,token0) == KErrNone);
   207 
   208 	CHECK(iUsbInterface0.Open(token0) == KErrNone); // Default interface setting 0
   209 	
   210 	
   211 	// open interface 1, alt. sett. 1
   212 	CHECK(testDevice.Device().GetTokenForInterface(1,token1) == KErrNone);
   213 	
   214 	CHECK(iUsbInterface1.Open(token1) == KErrNone); // Default interface setting 0
   215 	
   216 	RDebug::Printf("Selecting alternate interface setting 1");		
   217 	CHECK(iUsbInterface1.SelectAlternateInterface(1) == KErrNone);
   218 
   219 	
   220 	// open interface 2, alt. sett. 1
   221 	CHECK(testDevice.Device().GetTokenForInterface(2,token2) == KErrNone);
   222 
   223 	CHECK(iUsbInterface2.Open(token2) == KErrNone); // Default interface setting 0
   224 
   225 	
   226 	RDebug::Printf("Selecting alternate interface setting 1");		
   227 	CHECK(iUsbInterface2.SelectAlternateInterface(1) == KErrNone);
   228 
   229 																
   230 	iCaseStep = EWaitEndOfMusicTrack;
   231 												
   232 	// Open a pipe for endpoint (Isoch out)		
   233 	RDebug::Printf("Finding address for an out isoch endpoint on interface 1 setting 1");
   234 	// Isochronous OUT	
   235 	TUsbGenericDescriptor* isochEpDescriptorOut;
   236 	CHECK(KErrNone == FindOUTIsochronousEndpoint(isochEpDescriptorOut));
   237 	
   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); 
   242 	
   243 	// Isochronous IN		
   244 	TUsbGenericDescriptor* isochEpDescriptorIn;
   245 	CHECK(KErrNone == FindINIsochronousEndpoint(isochEpDescriptorIn));
   246 	
   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); 
   251 		
   252 	
   253 	// open pipes now.
   254 	// Out
   255 	RDebug::Printf("Opening a pipe to %08x",iEndpointAddressOut);
   256 	CHECK(iUsbInterface1.OpenPipeForEndpoint(iPipeOut,iEndpointAddressOut,EFalse) == KErrNone);
   257 		
   258 	RDebug::Printf("Opened pipe to endpoint address %08x for isochronous transfer to device",iEndpointAddressOut);
   259 				
   260 	// In
   261 	RDebug::Printf("Opening a pipe to %08x",iEndpointAddressIn);		
   262 	CHECK(iUsbInterface2.OpenPipeForEndpoint(iPipeIn,iEndpointAddressIn,EFalse) == KErrNone);
   263 		
   264 	RDebug::Printf("Opened pipe to endpoint address %08x for isochronous transfer to device",iEndpointAddressIn);
   265 	
   266 	// SET_CUR class specific command
   267 	TSetCurRequest request(KHighRecordSamplingRate ,iEndpointAddressIn);
   268 	iControlEp0->SendRequest(request,this);
   269 	
   270 	// Que transfers now		
   271 	// Transfer IN	
   272 	 iIsochInTransfer = new (ELeave) CIsochTransfer(iPipeIn,iUsbInterface2,wMaxPacketSizeIn,
   273 					KIsochInMaxNumPackets ,*this, KRecordedDataId);
   274 	
   275 	CHECK(iIsochInTransfer->RegisterTransferDescriptor() == KErrNone);
   276 			
   277 	// Initialise the descriptors for transfer	
   278 	RDebug::Printf("Initialising the transfer descriptors interface 2"); 
   279 	CHECK(iUsbInterface2.InitialiseTransferDescriptors() == KErrNone);
   280 
   281 				
   282 	// que interrupt transfer
   283 	CHECK(iIsochInTransfer->TransferInL(KRecordedPacketsExpected) == KErrNone);
   284 						
   285 		
   286 	// Transfer OUT
   287 	RFs iFs;
   288 	TInt ret = KErrNone; 
   289 	ret = iFs.Connect();
   290 	CHECK(ret==KErrNone || ret==KErrAlreadyExists);
   291 	RFile trackFile;
   292 	CHECK(trackFile.Open(iFs,KTrackFileName,EFileShareAny|EFileRead) == KErrNone);
   293 		
   294 
   295 	TInt trackFileSize;	
   296 	trackFile.Size(trackFileSize); 
   297 	
   298 		
   299 	wMaxPacketSizeOut = KAudioCDQualityFrequency;  	
   300 	
   301 	TInt nbChunks = trackFileSize/KChunkSize;
   302 	TInt remainderSize = trackFileSize%KChunkSize; 
   303 	
   304 	if(remainderSize != 0)
   305 		{
   306 		nbChunks++;
   307 		}
   308 	
   309 	TInt iChunk = 0;   
   310 	TInt size = KChunkSize;
   311 	              
   312 	// create Transfers
   313 	for(iChunk = 0; iChunk < nbChunks; iChunk++)
   314 		{
   315 		RDebug::Printf("iChunk = %d", iChunk);
   316 		
   317 		// remainder(last loop)
   318 		if(remainderSize != 0 && (iChunk == nbChunks-1))
   319 			{			
   320 			size = remainderSize;
   321 			}	
   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();    							
   327 		}			
   328 	
   329 	// Initialise the descriptors for transfer	
   330 	RDebug::Printf("Initialising the transfer descriptors"); 
   331 	CHECK(iUsbInterface1.InitialiseTransferDescriptors() == KErrNone);
   332 	
   333 	// prepare & send transfers(TODO streaming algorithm with 3 Transfers only, filling 2 while the 3rd is transferring his data)
   334 	size = KChunkSize;
   335 	for(TInt iTransfers = 0; iTransfers < iOutTransfers.Count(); iTransfers++)
   336 		{	
   337 		RDebug::Printf("iTransfers = %d", iTransfers);	
   338 		// remainder(last loop)
   339 		if(remainderSize != 0 && (iTransfers == iOutTransfers.Count()-1))
   340 			{
   341 			RDebug::Printf("remainderSize = %d", remainderSize);
   342 			size = remainderSize;
   343 			}			
   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();		
   348 		}												
   349 	}
   350 	
   351 TBool CUT_PBASE_T_USBDI_0482::ReplayRecordedData()
   352 	{
   353 	LOG_FUNC
   354 		
   355 	iOutTransferBuf.Zero();	
   356 	
   357 	// Transfer OUT						
   358 	TInt nbChunks = iDataPolledBuf.Length()/KChunkSize;
   359 	TInt remainderSize = iDataPolledBuf.Length()%KChunkSize; 
   360 	RDebug::Printf("nbChunks = %d", nbChunks);
   361 	RDebug::Printf("remainderSize = %d", remainderSize);
   362 		
   363 	if(remainderSize != 0) 
   364 		{
   365 		nbChunks++;
   366 		}
   367 	
   368 	// prepare transfers	
   369 	for(TInt iTransfers = 0; iTransfers < nbChunks; iTransfers++)
   370 		{	
   371 		RDebug::Printf("iTransfers = %d", iTransfers);	
   372 		// remainder(last loop)
   373 		if(remainderSize != 0 && (iTransfers == nbChunks-1))
   374 			{
   375 			RDebug::Printf("remainderSize = %d", remainderSize);
   376 			}		
   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();	
   380 		}
   381 	return ETrue;			
   382 	}
   383 		
   384 void CUT_PBASE_T_USBDI_0482::TransferCompleteL(TInt aTransferId,TInt aCompletionCode)
   385 	{
   386 	LOG_FUNC
   387 	RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d",aTransferId, aCompletionCode);
   388 	Cancel();
   389 
   390 	if(aCompletionCode != KErrNone)
   391 		{
   392 		RDebug::Printf("<Error %d> Transfer %d not successful",aCompletionCode,aTransferId);
   393 		TestFailed(aCompletionCode);
   394 		return;
   395 		}
   396 	
   397 	if(aTransferId == KRecordedDataId)
   398 		{
   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
   403 		return;	
   404 		}
   405 				
   406 	switch(iCaseStep)
   407 		{
   408 		case EWaitEndOfMusicTrack:
   409 			{
   410 			if(aTransferId != iExpectedTransferId)
   411 				{
   412 				RDebug::Printf("unexpected transfer!");
   413 				TestFailed(KErrCorrupt);
   414 				}
   415 			iExpectedTransferId++;		
   416 			// is it the last transfer?
   417 			if(iExpectedTransferId == iOutTransfers.Count())
   418 				{
   419 				RDebug::Printf("last transfer successful! lets replay recorded data");
   420 						
   421 				iCaseStep = EReplayRecordedData; // assuming that recording is finished
   422 				TSetCurRequest request(KLowSamplingRate ,iEndpointAddressOut);
   423 				iControlEp0->SendRequest(request,this);		
   424 				}			
   425 			}		
   426 			break;
   427 								
   428 		case EReplayRecordedData:
   429 			{
   430 			TestPassed();	// TODO only one transfer used in this case(few data recorded), cope with several ones	
   431 			}			
   432 			break;
   433 				
   434 		default:
   435 			TestFailed(KErrDisconnected);
   436 			break;
   437 		}			
   438 	}									   
   439 
   440 void CUT_PBASE_T_USBDI_0482::Ep0TransferCompleteL(TInt aCompletionCode)
   441 	{
   442 	LOG_FUNC
   443 	RDebug::Printf("Transfer EP0 completed aCompletionCode = %d", aCompletionCode);
   444 
   445 	if(aCompletionCode != KErrNone)
   446 		{
   447 		TBuf<256> msg;
   448 		msg.Format(_L("<Error %d> Transfer to control endpoint 0 was not successful"),aCompletionCode);
   449 		RDebug::Print(msg);			
   450 		return;			
   451 		}	
   452 	switch(iCaseStep)
   453 		{	
   454 		case EWaitEndOfMusicTrack:	
   455 			break;	
   456 			
   457 		case EReplayRecordedData:	
   458 			{
   459 			CHECK(ReplayRecordedData());		
   460 			}
   461 			break;			
   462 		
   463 		default:
   464 			RDebug::Printf("<Error> Unknown test step");
   465 			TestFailed(KErrUnknown);
   466 			break;
   467 		}
   468 	}	
   469 	 	
   470 	
   471 void CUT_PBASE_T_USBDI_0482::DeviceRemovedL(TUint aDeviceHandle)
   472 	{
   473 	LOG_FUNC
   474 	
   475 	// Manual test over	
   476 	switch(iCaseStep)
   477 		{		
   478 		case EFailed:
   479 			TestFailed(KErrCompletion);
   480 			break;
   481 			
   482 		case EInProgress:
   483 		default:
   484 			TestFailed(KErrDisconnected);
   485 			break;
   486 		}
   487 	}
   488 	
   489 	
   490 void CUT_PBASE_T_USBDI_0482::BusErrorL(TInt aError)
   491 	{
   492 	LOG_FUNC	
   493 	// This test case handles no failiures on the bus	
   494 	TestFailed(KErrCompletion);	
   495 	}
   496 
   497 
   498 void CUT_PBASE_T_USBDI_0482::HostRunL()
   499 	{
   500 	LOG_FUNC
   501 	
   502 	// Obtain the completion code
   503 	TInt completionCode(iStatus.Int());
   504 	
   505 	if(completionCode == KErrNone)
   506 		{
   507 		// Action timeout
   508 		RDebug::Printf("<Error> Action timeout");
   509 		TestFailed(KErrTimedOut);
   510 		}
   511 	else
   512 		{
   513 		RDebug::Printf("<Error %d> Timeout timer could not complete",completionCode);
   514 		TestFailed(completionCode);
   515 		}
   516 	}
   517 
   518 void CUT_PBASE_T_USBDI_0482::DeviceRunL()
   519 	{	
   520 	}
   521 		
   522 	}