os/kernelhwsrv/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-0473.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-0473.cpp
    15 // @internalComponent
    16 // 
    17 //
    18 
    19 #include "PBASE-T_USBDI-0473.h"
    20 #include <d32usbc.h>
    21 #include "testdebug.h"
    22 #include "modelleddevices.h"
    23 #include "TestPolicy.h"
    24 
    25 namespace NUnitTesting_USBDI
    26 	{
    27 	
    28 _LIT(KTestCaseId,"PBASE-T_USBDI-0473");
    29 const TFunctorTestCase<CUT_PBASE_T_USBDI_0473,TBool> CUT_PBASE_T_USBDI_0473::iFunctor(KTestCaseId);	
    30 
    31 CUT_PBASE_T_USBDI_0473* CUT_PBASE_T_USBDI_0473::NewL(TBool aHostRole)
    32 	{
    33 	CUT_PBASE_T_USBDI_0473* self = new (ELeave) CUT_PBASE_T_USBDI_0473(aHostRole);
    34 	CleanupStack::PushL(self);
    35 	self->ConstructL();
    36 	CleanupStack::Pop(self);
    37 	return self; 
    38 	}
    39 	   
    40 
    41 CUT_PBASE_T_USBDI_0473::CUT_PBASE_T_USBDI_0473(TBool aHostRole)
    42 :	CBaseTestCase(KTestCaseId,aHostRole),
    43 	iSuspendedI0(EFalse),
    44 	iSuspendedI1(EFalse),
    45 	iDeviceNotificationPending(ETrue)
    46 	{
    47 	} 
    48 
    49 
    50 void CUT_PBASE_T_USBDI_0473::ConstructL()
    51 	{
    52 	iTestDevice = new RUsbDeviceA(this);
    53 	BaseConstructL();
    54 	}
    55 
    56 
    57 CUT_PBASE_T_USBDI_0473::~CUT_PBASE_T_USBDI_0473()
    58 	{
    59 	LOG_FUNC
    60 	
    61 	// Cancel any async operations
    62 	
    63 	Cancel(); // Cancel host timer
    64 	
    65 	// Destroy the watchers
    66 	// they still use opened interfaces to cancel the suspend if active
    67 	delete iInterface1Watcher;
    68 	delete iInterface0Watcher;
    69 
    70 	// Close the interfaces
    71 	iUsbInterface1.Close();
    72 	iUsbInterface0.Close();
    73 	
    74 	delete iControlEp0;
    75 	delete iActorFDF;
    76 	if(!IsHost() && iTestDevice)
    77 		{
    78 		iTestDevice->Close();
    79 		}		
    80 	delete iTestDevice;
    81 	}
    82 
    83 
    84 void CUT_PBASE_T_USBDI_0473::ExecuteHostTestCaseL()
    85 	{
    86 	LOG_FUNC
    87 	iCaseStep = EStepSuspend;
    88 	iActorFDF = CActorFDF::NewL(*this);
    89 	iControlEp0 = new (ELeave) CEp0Transfer(iUsbInterface0);
    90 	iInterface0Watcher = new (ELeave) CInterfaceWatcher(iUsbInterface0,TCallBack(CUT_PBASE_T_USBDI_0473::Interface0ResumedL,this));
    91 	iInterface1Watcher = new (ELeave) CInterfaceWatcher(iUsbInterface1,TCallBack(CUT_PBASE_T_USBDI_0473::Interface1ResumedL,this));
    92 	
    93 	// Monitor for device connections
    94 	iActorFDF->Monitor();
    95 
    96 	// Start the connection timeout	
    97 	TimeoutIn(30);
    98 	}
    99 
   100 void CUT_PBASE_T_USBDI_0473::ExecuteDeviceTestCaseL()
   101 	{
   102 	LOG_FUNC
   103 
   104 	// Construct the device for the test case
   105 	iTestDevice->OpenL(TestCaseId());
   106 	iTestDevice->SubscribeToReports(iStatus);
   107 	SetActive();
   108 
   109 	// Connect the test device	
   110 	iTestDevice->SoftwareConnect();
   111 	}
   112 	
   113 	
   114 void CUT_PBASE_T_USBDI_0473::HostDoCancel()
   115 	{
   116 	LOG_FUNC
   117 
   118 	// Cancel the timeout timer
   119 	CancelTimeout();
   120 	}
   121 
   122 
   123 void CUT_PBASE_T_USBDI_0473::DeviceDoCancel()
   124 	{
   125 	LOG_FUNC
   126 	
   127 	// Cancel the device	
   128 	iTestDevice->CancelSubscriptionToReports();
   129 	}
   130 	
   131 void CUT_PBASE_T_USBDI_0473::DeviceInsertedL(TUint aDeviceHandle)
   132 	{
   133 	LOG_FUNC
   134 
   135 	Cancel(); // Cancel the timer
   136 	TInt err(KErrNone);
   137 	iDeviceHandle = aDeviceHandle;
   138 	iActorFDF->Monitor();
   139 	
   140 	// Validate that device is as expected
   141 	CUsbTestDevice& testDevice = iActorFDF->DeviceL(aDeviceHandle);
   142 	if(testDevice.SerialNumber().Compare(TestCaseId()) != 0)
   143 		{
   144 		// Incorrect device for this test case
   145 
   146 		RDebug::Printf("<Warning %d> Incorrect device serial number (%S) connected for this test case (%S)",
   147 			KErrNotFound,&testDevice.SerialNumber(),&TestCaseId());
   148 
   149 		// Start the connection timeout again
   150 		TimeoutIn(30);
   151 		return;
   152 		}	
   153 	// Check tree now	
   154 	CHECK(CheckTreeAfterDeviceInsertion(testDevice, _L("RDeviceA")) == KErrNone);
   155 		
   156 	// Perform the correct test step				
   157 	switch(iCaseStep)
   158 		{
   159 		case EStepSuspend:
   160 			{
   161 			TUint32 token1(0);
   162 			TUint32 token2(0);
   163 	
   164 			RDebug::Printf("Obtaining token for interface 0");
   165 			err = testDevice.Device().GetTokenForInterface(0,token1);
   166 			if(err != KErrNone)
   167 				{
   168 				RDebug::Printf("<Error %d> Token for interface 0 could not be retrieved",err);
   169 				return TestFailed(err);
   170 				}
   171 			RDebug::Printf("Token 1 (%d) retrieved",token1);
   172 			RDebug::Printf("Opening interface 0");
   173 			err = iUsbInterface0.Open(token1); // Alternate interface setting 0
   174 			if(err != KErrNone)
   175 				{
   176 				RDebug::Printf("<Error %d> Interface 0 could not be opened",err);
   177 				return TestFailed(err);
   178 				}
   179 			RDebug::Printf("Interface 0 opened");
   180 		
   181 																
   182 			RDebug::Printf("Obtaining token for interface 1");
   183 			err = testDevice.Device().GetTokenForInterface(1,token2);
   184 			if(err != KErrNone)
   185 				{
   186 				RDebug::Printf("<Error %d> Token for interface 1 could not be retrieved",err);
   187 				return TestFailed(err);			
   188 				}	
   189 			RDebug::Printf("Opening interface 1");
   190 			err = iUsbInterface1.Open(token2); // Alternate interface setting 0
   191 			if(err != KErrNone)
   192 				{
   193 				RDebug::Printf("<Error %d> Interface 1 could not be opened",err);
   194 				return TestFailed(err);
   195 				}
   196 			RDebug::Printf("Interface 1 opened");
   197 	
   198 			// close it
   199 			iUsbInterface1.Close();		
   200 			RDebug::Printf("Interface 1 closed");
   201 	
   202 			//re-open now
   203 			err = iUsbInterface1.Open(token2); // Alternate interface setting 0
   204 			if(err != KErrNone)
   205 				{
   206 				RDebug::Printf("<Error %d> Interface 1 could not be re-opened",err);
   207 				return TestFailed(err);
   208 				}
   209 			RDebug::Printf("Interface 1 re-opened");
   210 			
   211 			
   212 			// Suspend interface 0
   213 			RDebug::Printf("Suspending interface 0");
   214 			iInterface0Watcher->SuspendAndWatch();
   215 			iSuspendedI0 = ETrue;
   216 			
   217 			// Suspend interface 1
   218 			RDebug::Printf("Suspending interface 1");
   219 			iInterface1Watcher->SuspendAndWatch();
   220 			iSuspendedI1 = ETrue;
   221 			
   222 			iCaseStep = EValidateSuspendingInterfaces;
   223 			TimeoutIn(10); // Give 10 seconds for device to suspend
   224 			}
   225 			break;
   226 			
   227 		default:
   228 			TestFailed(KErrCorrupt);
   229 			break;
   230 		}	
   231 	}
   232 
   233 
   234 TInt CUT_PBASE_T_USBDI_0473::Interface0ResumedL(TAny* aPtr)
   235 	{
   236 	LOG_CFUNC
   237 	RDebug::Printf("Interface 0 resumed");
   238 	CUT_PBASE_T_USBDI_0473* self = reinterpret_cast<CUT_PBASE_T_USBDI_0473*>(aPtr);
   239 	RDebug::Printf("watcher 0 iStatus=%d",self->iInterface0Watcher->CompletionCode());
   240 	self->iSuspendedI0 = EFalse;
   241 	return self->CheckForAllResumedNotificationsAndContinueFSM();
   242 	}
   243 	
   244 	
   245 TInt CUT_PBASE_T_USBDI_0473::Interface1ResumedL(TAny* aPtr)
   246 	{
   247 	LOG_CFUNC
   248 	RDebug::Printf("Interface 1 resumed");
   249 	CUT_PBASE_T_USBDI_0473* self = reinterpret_cast<CUT_PBASE_T_USBDI_0473*>(aPtr);
   250 	RDebug::Printf("watcher 1 iStatus=%d",self->iInterface1Watcher->CompletionCode());
   251 	self->iSuspendedI1 = EFalse;
   252 	return self->CheckForAllResumedNotificationsAndContinueFSM();
   253 	}
   254 	
   255 	
   256 void CUT_PBASE_T_USBDI_0473::DeviceRemovedL(TUint aDeviceHandle)
   257 	{
   258 	LOG_FUNC
   259 
   260 	// The test device should not be removed until the test case has passed
   261 	// so this test case has not completed, and state this event as an error
   262 
   263 	TestFailed(KErrDisconnected);
   264 	}
   265 	
   266 	
   267 void CUT_PBASE_T_USBDI_0473::BusErrorL(TInt aError)
   268 	{
   269 	LOG_FUNC
   270 
   271 	// This test case handles no failiures on the bus
   272 
   273 	TestFailed(aError);
   274 	}
   275 
   276 TInt CUT_PBASE_T_USBDI_0473::CheckForAllResumedNotificationsAndContinueFSM()
   277 	{
   278 	LOG_FUNC
   279 	TBool readyToContinueFSM= ETrue;
   280 	if( iInterface0Watcher->IsActive()
   281 	||  iInterface0Watcher->iStatus == KRequestPending)
   282 		{
   283 		RDebug::Printf("Interface 0 watcher still pending");
   284 		readyToContinueFSM= EFalse;
   285 		}
   286 
   287 	if( iInterface1Watcher->IsActive()
   288 	||  iInterface1Watcher->iStatus == KRequestPending)
   289 		{
   290 		RDebug::Printf("Interface 1 watcher still pending");
   291 		readyToContinueFSM= EFalse;
   292 		}
   293 
   294 	if( iDeviceNotificationPending)
   295 		{
   296 		readyToContinueFSM= EFalse;
   297 		}
   298 
   299 	if( readyToContinueFSM)
   300 		{
   301 		return ContinueFSMAfterAllResumedNotifications();
   302 		}
   303 	else
   304 		{
   305 		return KErrNone;
   306 		}
   307 	}
   308 
   309 TInt CUT_PBASE_T_USBDI_0473::ContinueFSMAfterAllResumedNotifications()
   310 	{
   311 	LOG_FUNC
   312 	iDeviceNotificationPending= ETrue;
   313 	if(iSuspendedI0)
   314 		{
   315 		RDebug::Printf("<Error %d> Interface 0 still suspended",KErrCompletion);
   316 		TestFailed(KErrCompletion);
   317 		return KErrCompletion;
   318 		}
   319 
   320 	if(iSuspendedI1)
   321 		{
   322 		RDebug::Printf("<Error %d> Interface 1 still suspended",KErrCompletion);
   323 		TestFailed(KErrCompletion);
   324 		return KErrCompletion;
   325 		}
   326 
   327 	switch(iCaseStep)
   328 		{
   329 		case EValidateResumptionAfterInterfaceSuspension:
   330 			{
   331 			// Device is resumed, send request to client: Remote wake up in 6 secs
   332 			TInt err= iUsbInterface1.PermitRemoteWakeup(ETrue);
   333 			
   334 			if(err != KErrNone)
   335 				{
   336 				RDebug::Printf("<Error %d> Unable to permit remote device wakeup",err);
   337 				iCaseStep = EFailed;
   338 				TTestCaseFailed request(err,_L8("Unable to permit remote device wakeup"));
   339 				iControlEp0->SendRequest(request,this);
   340 				}
   341 			else
   342 				{
   343 				RDebug::Printf("Device is resumed, send request to client: Remote wake up in 6 secs");
   344 				
   345 				TRemoteWakeupRequest request(6);
   346 				iControlEp0->SendRequest(request,this);			
   347 				iCaseStep = ESuspendForRemoteWakeup;		
   348 				}
   349 			}
   350 			break;
   351 
   352 		case EValidateResumptionAfterWakeup:
   353 			{
   354 			if(iStoredNewState == RUsbDevice::EDeviceActive)
   355 				{
   356 				// Now suspend the device again after resumption from remote wakeup
   357 			
   358 				RDebug::Printf("Suspending interface 0");
   359 				iInterface0Watcher->SuspendAndWatch();
   360 				iSuspendedI0 = ETrue;
   361 				
   362 				RDebug::Printf("Suspending interface 1");
   363 				iInterface1Watcher->SuspendAndWatch();
   364 				iSuspendedI1 = ETrue;
   365 				
   366 				iCaseStep = EValidateSuspendAfterWakeup;
   367 				}
   368 			else
   369 				{
   370 				RDebug::Printf("<Error %d> Device is still suspended",KErrCompletion);
   371 				TestFailed(KErrCompletion);
   372 				return KErrCompletion;
   373 				}
   374 			}
   375 			break;
   376 
   377 		default:
   378 			RDebug::Printf("CUT_PBASE_T_USBDI_0473::ContinueFSMAfterAllResumedNotifications: Invalid state %d", iCaseStep);
   379 			TestFailed(KErrCompletion);
   380 			return KErrCompletion;
   381 		}
   382 
   383 	return KErrNone;
   384 	}
   385 
   386 void CUT_PBASE_T_USBDI_0473::DeviceStateChangeL(RUsbDevice::TDeviceState aPreviousState,RUsbDevice::TDeviceState aNewState,TInt aCompletionCode)
   387 	{
   388 	LOG_FUNC
   389 	Cancel();
   390 	
   391 	RDebug::Printf("Device State change from %d to %d err=%d",aPreviousState,aNewState,aCompletionCode);
   392 
   393 	switch(iCaseStep)
   394 		{
   395 	
   396 		// Validate that the device was suspended by individual interface suspension
   397 	
   398 		case EValidateSuspendingInterfaces:
   399 			{
   400 			if(aNewState == RUsbDevice::EDeviceSuspended)
   401 				{
   402 				// Device state is suspended now resume it by resuming one of the interfaces
   403 				
   404 				RDebug::Printf("Device is suspended now resume device by resuming one of the interfaces");
   405 				iUsbInterface0.CancelPermitSuspend();
   406 				iCaseStep = EValidateResumptionAfterInterfaceSuspension;
   407 				}
   408 			else
   409 				{
   410 				RDebug::Printf("<Error %d> State was not suspended",KErrCompletion);
   411 				
   412 				// Since the device is not suspended, send test case failed to the device
   413 	
   414 				iCaseStep = EFailed;
   415 				TTestCaseFailed request(KErrCompletion,_L8("The device was not in the expected suspend state"));
   416 				iControlEp0->SendRequest(request,this);
   417 				}
   418 			}
   419 			break;
   420 			
   421 		// Validate that device is now active after resuming one of the interfaces
   422 	
   423 		case EValidateResumptionAfterInterfaceSuspension:
   424 			{
   425 			iDeviceNotificationPending= EFalse;
   426 
   427 			if(aNewState == RUsbDevice::EDeviceActive)
   428 				{
   429 				CheckForAllResumedNotificationsAndContinueFSM();
   430 				}
   431 			else
   432 				{
   433 				RDebug::Printf("<Error %d> Device is still suspended",KErrCompletion);
   434 				return TestFailed(KErrCompletion);
   435 				}
   436 			}
   437 			break;
   438 			
   439 		// Validate that the device is now suspended for the device to remote-wakeup
   440 		case EValidateSuspendForRemoteWakeup:
   441 			{
   442 			if(aNewState == RUsbDevice::EDeviceSuspended)
   443 				{
   444 				// Now awaiting a remote wake up state change notification
   445 				
   446 				RDebug::Printf("Now awaiting a remote wake up state change notification");
   447 				
   448 				CancelTimeout();
   449 				iTimer.After(iStatus,10000000); // Give 10 seconds for device to signal remote wake-up
   450 				iCaseStep = EValidateResumptionAfterWakeup;
   451 				SetActive();
   452 				}
   453 			else
   454 				{
   455 				RDebug::Printf("<Error %d> State was not suspended",KErrCompletion);
   456 				
   457 				// Since the device is not suspended, send test case failed to the device
   458 	
   459 				iCaseStep = EFailed;
   460 				TTestCaseFailed request(KErrCompletion,_L8("State was not suspended"));
   461 				iControlEp0->SendRequest(request,this);
   462 				}
   463 			}
   464 			break;
   465 			
   466 		// This step should never be reached as ep0 complete traps this step, but if it does test fails.
   467 		case ESuspendForRemoteWakeup:
   468 			{
   469 			RDebug::Printf("Resumed before suspended");	    
   470 		    iCaseStep = EFailed;
   471 		    TTestCaseFailed request(KErrCompletion,_L8("State was not suspended"));
   472 		    iControlEp0->SendRequest(request,this);
   473 		    break;	
   474 			}	    
   475 				
   476 		// Validate that the device is now active from a remote wakeup
   477 		case EValidateResumptionAfterWakeup:
   478 			{
   479 			iDeviceNotificationPending= EFalse;
   480 			iStoredNewState= aNewState;
   481 			CheckForAllResumedNotificationsAndContinueFSM();
   482 			}
   483 			break;
   484 			
   485 		// Validate that the device can be suspended after a remote wakeup
   486 	
   487 		case EValidateSuspendAfterWakeup:
   488 			{
   489 			// Successfully suspended after a remote wake up event
   490 			if(aNewState == RUsbDevice::EDeviceSuspended)
   491 				{
   492 				// Device is now suspended, now activate the device again to send test case
   493 				// completed request to device
   494 	
   495 				RDebug::Printf("Device is now suspended, now activate the device again to send test case completed request to device");
   496 	
   497 				CUsbTestDevice& testDevice = iActorFDF->DeviceL(iDeviceHandle);
   498 	
   499 				RDebug::Printf("Resuming at device level");
   500 				TInt err(testDevice.Device().Resume());
   501 				if(err != KErrNone)
   502 					{
   503 					RDebug::Printf("<Error %d> Unable to suspend the device",err);
   504 					iCaseStep = EFailed;
   505 					TTestCaseFailed request(err,_L8("Unable to suspend the device"));
   506 					iControlEp0->SendRequest(request,this);
   507 					}
   508 				
   509 				iCaseStep = EPassed;
   510 				}
   511 			else
   512 				{
   513 				RDebug::Printf("<Error %d> State was not suspended",KErrCompletion);
   514 				
   515 				// Since the device is not suspended, send test case failed to the device
   516 	
   517 				iCaseStep = EFailed;
   518 				TTestCaseFailed request(KErrCompletion,_L8("State was not suspended"));
   519 				iControlEp0->SendRequest(request,this);
   520 				}
   521 			}
   522 			break;
   523 	
   524 		// Validate that the device is now active again 
   525 	
   526 		case EPassed:
   527 			{
   528 			if(aNewState == RUsbDevice::EDeviceActive)
   529 				{
   530 				RDebug::Printf("Device is active again, test case passed");
   531 				TTestCasePassed request;
   532 				iControlEp0->SendRequest(request,this);
   533 				}
   534 			else
   535 				{
   536 				RDebug::Printf("<Error %d> Device is still suspended",KErrCompletion);
   537 				return TestFailed(KErrCompletion);
   538 				}
   539 			}
   540 			break;
   541 			
   542 		default:
   543 			break;
   544 		}
   545 	}
   546 
   547 
   548 void CUT_PBASE_T_USBDI_0473::Ep0TransferCompleteL(TInt aCompletionCode)
   549 	{
   550 	LOG_FUNC
   551 	RDebug::Printf("Ep0TransferCompleteL with aCompletionCode = %d",aCompletionCode);
   552 	switch(iCaseStep)
   553 		{
   554 		case ESuspendForRemoteWakeup:
   555 			{
   556 			// Suspend device again so a remote wakeup can be achieved
   557 			RDebug::Printf("Suspend device again so a remote wakeup can be achieved");
   558 	
   559 			// Suspend interface 0
   560 			RDebug::Printf("Suspending interface 0");
   561 			iInterface0Watcher->SuspendAndWatch();
   562 			iSuspendedI0 = ETrue;
   563 			
   564 			// Suspend interface 1
   565 			RDebug::Printf("Suspending interface 1");
   566 			iInterface1Watcher->SuspendAndWatch();
   567 			iSuspendedI1 = ETrue;
   568 			
   569 			iCaseStep = EValidateSuspendForRemoteWakeup;
   570 			TimeoutIn(10); // Give 10 seconds for device to suspend	
   571 			}
   572 			break;
   573 	
   574 		// Fail the test case
   575 	
   576 		default:
   577 		case EFailed:
   578 			TestFailed(KErrCompletion);
   579 			break;
   580 	
   581 		// Pass the test case
   582 	
   583 		case EPassed:
   584 			TestPassed();
   585 			break;
   586 			}
   587 	}
   588 
   589 
   590 void CUT_PBASE_T_USBDI_0473::HostRunL()
   591 	{
   592 	LOG_FUNC
   593 	
   594 	// Obtain the completion code
   595 	TInt completionCode(iStatus.Int());
   596 	
   597 	if(completionCode == KErrNone)
   598 		{
   599 		// Action timeout
   600 		RDebug::Printf("<Error> Action timeout");
   601 		TestFailed(KErrTimedOut);
   602 		}
   603 	else
   604 		{
   605 		RDebug::Printf("<Error %d> Timeout timer could not complete",completionCode);
   606 		TestFailed(completionCode);
   607 		}
   608 	}
   609 	
   610 
   611 void CUT_PBASE_T_USBDI_0473::DeviceRunL()
   612 	{
   613 	LOG_FUNC
   614 	
   615 	// Disconnect the device
   616 	
   617 	iTestDevice->SoftwareDisconnect();
   618 	
   619 	// Complete the test case request
   620 	
   621 	TestPolicy().SignalTestComplete(iStatus.Int());
   622 	}
   623 	
   624 	
   625 	}