os/kernelhwsrv/kerneltest/e32test/usbho/t_usbdi/src/TestInterfaceBase.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 testinterfacebase.cpp
    15 // @internalComponent
    16 // 
    17 //
    18 
    19 #include "testdevicebase.h"
    20 #include "testinterfacebase.h"
    21 #include "testinterfacesettingbase.h"
    22 #include "testdebug.h"
    23 #include "controltransferrequests.h"
    24 #include "endpointwriter.h"
    25 
    26 
    27 namespace NUnitTesting_USBDI
    28 	{
    29 
    30 	
    31 CInterfaceBase::CInterfaceBase(RUsbTestDevice& aTestDevice,const TDesC16& aName)
    32 :	iDevice(aTestDevice),
    33 	iInterfaceName(aName),
    34 	iCurrentAlternateInterfaceSetting(0) // The default alternate interface setting will be zero when opened
    35 	{
    36 	}
    37 	
    38 CInterfaceBase::~CInterfaceBase()
    39 	{
    40 	LOG_FUNC
    41 	
    42 	delete iAuxBuffer;
    43 	delete iStallWatcher;
    44 	delete iSelectionWatcher;
    45 		
    46 	// Release all interfaces
    47 	delete iEp0Writer;
    48 	
    49 	// Destroy the endpoint 0 reader
    50 	delete iEp0Reader;
    51 		
    52 	// Destroy interface settings
    53 	iAlternateSettings.ResetAndDestroy();
    54 	
    55 	// Close the channel to the driver
    56 	iClientDriver.Close();
    57 	}
    58 	
    59 	
    60 void CInterfaceBase::BaseConstructL()
    61 	{
    62 	LOG_FUNC
    63 	// Open channel to driver
    64 	TInt err(iClientDriver.Open(0));
    65 	if(err != KErrNone)
    66 		{
    67 		RDebug::Printf("<Error %d> Unable to open a channel to USB client driver",err);
    68 		User::Leave(err);
    69 		}
    70 
    71 	// Start the watcher for host selecting alternate interface settings
    72 	iSelectionWatcher = CAlternateInterfaceSelectionWatcher::NewL(iClientDriver,*this);
    73 	
    74 	//
    75 	iStallWatcher = new (ELeave) CEndpointStallWatcher(iClientDriver);
    76 	
    77 	// Create the Ep0 reader/writer
    78 	iEp0Reader = new (ELeave) CControlEndpointReader(iClientDriver,*this);
    79 	iEp0Writer = new (ELeave) CEndpointWriter(iClientDriver,EEndpoint0);
    80 
    81 	// Hide bus from host while interfaces are being set up
    82 	iClientDriver.DeviceDisconnectFromHost();
    83 	}
    84 
    85 
    86 void CInterfaceBase::AddInterfaceSettingL(CInterfaceSettingBase* aInterfaceSetting)
    87 	{
    88 	LOG_FUNC
    89 	
    90 	// Append to the container
    91 	TInt err(iAlternateSettings.Append(aInterfaceSetting));
    92 	if(err != KErrNone)
    93 		{
    94 		RDebug::Printf("<Error %d> Unable to add interface setting",err);
    95 		User::Leave(err);
    96 		}
    97 	
    98 	// Get the current number of alternate interface settings	
    99 	TInt alternateSettingNumber(iAlternateSettings.Count()-1);
   100 
   101 	TUint endpointSettingCount(aInterfaceSetting->iInterfaceInfo().iTotalEndpointsUsed);
   102 	
   103 	if(endpointSettingCount > 0)
   104 		{
   105 		RDebug::Printf("%u endpoint(s) to configure for this interface setting",endpointSettingCount);
   106 				
   107 		// Device capabilities
   108 		TUsbDeviceCaps devCaps;
   109 		err = iClientDriver.DeviceCaps(devCaps);
   110 		if(err != KErrNone)
   111 			{
   112 			RDebug::Printf("<Error %d> Unable to retrieve device capabilities",err);
   113 			User::Leave(err);
   114 			}
   115 
   116 		// Endpoint capabilities
   117 		TUsbcEndpointData endpointCaps[KUsbcMaxEndpoints];
   118 		TPtr8 dataptr(reinterpret_cast<TUint8*>(endpointCaps), sizeof(endpointCaps), sizeof(endpointCaps));
   119 		err = iClientDriver.EndpointCaps(dataptr);
   120 		if(err != KErrNone)
   121 			{
   122 			RDebug::Printf("<Error %d> Unable to get endpoint capabilities",err);
   123 			User::Leave(err);
   124 			}		
   125 		
   126 		TInt totalEndpoints(devCaps().iTotalEndpoints);
   127 		
   128 		// Loop through available hardware endpoints to find suitable one
   129 		// i.e. endpoints that can be configured
   130 		
   131 		TUint epIndex(0);
   132 		TUint epCount(0);
   133 		
   134 		for(; epIndex<totalEndpoints; epIndex++)
   135 			{
   136 			RDebug::Printf("Examining hardware endpoint %u",epIndex);
   137 			const TUsbcEndpointData ep = endpointCaps[epIndex];
   138 			
   139 			// Check the endpoint index to see if already claimed
   140 			if(!ep.iInUse)
   141 				{			
   142 				RDebug::Printf("...its free");
   143 				const TUsbcEndpointCaps caps(ep.iCaps);
   144 				
   145 				// Information about the endpoint we are looking for	
   146 				TUsbcEndpointInfo& endpointSpec = aInterfaceSetting->iInterfaceInfo().iEndpointData[epCount];
   147 						
   148 				if( (caps.iTypesAndDir & (endpointSpec.iDir | endpointSpec.iType)) == 
   149 					(endpointSpec.iDir | endpointSpec.iType) )
   150 					{
   151 					// Found suitable endpoint
   152 					
   153 					// Create the reader/writer for this endpoint					
   154 					
   155 					if(endpointSpec.iDir == KUsbEpDirIn)
   156 						{
   157 						// Create an endpoint writer for this endpoint
   158 						
   159 						aInterfaceSetting->CreateEndpointWriterL(iClientDriver,(epCount+1));
   160 						RDebug::Printf("Created endpoint writer for endpoint%d",epCount+1);
   161 						}
   162 					else if(endpointSpec.iDir == KUsbEpDirOut)
   163 						{
   164 						// Create an endpoint reader for this endpoint
   165 												
   166 						aInterfaceSetting->CreateEndpointReaderL(iClientDriver,epCount+1);
   167 						RDebug::Printf("Created endpoint reader for endpoint%d",epCount+1);
   168 						}					
   169 					
   170 					epCount++; // Increment to next endpoint spec
   171 					RDebug::Printf("Endpoint %u configured",epCount);
   172 					endpointSpec.iSize = caps.MaxPacketSize();
   173 					
   174 					if(epCount >= endpointSettingCount)
   175 						{
   176 						// Found all desired endpoints
   177 						break;
   178 						}
   179 					}
   180 				}
   181 			else
   182 				{
   183 				RDebug::Printf("...its busy");
   184 				}
   185 			}
   186 		
   187 		RDebug::Printf("Configure %u out of %u endpoints",epCount,endpointSettingCount);			
   188 		
   189 		if(epCount < endpointSettingCount)
   190 			{
   191 			RDebug::Printf("<Error %d> Only managed to configure %u out of %u endpoints",KErrNotFound,epCount,endpointSettingCount);
   192 			User::Leave(KErrNotFound);
   193 			}			
   194 		}
   195 	else
   196 		{
   197 		RDebug::Printf("No endpoints for this interface setting");
   198 		}
   199 	
   200 	// Add the new setting to the device
   201 	err = iClientDriver.SetInterface(alternateSettingNumber,aInterfaceSetting->iInterfaceInfo);
   202 	if(err != KErrNone)
   203 		{
   204 		RDebug::Printf("<Error %d> Unable to set the alternate interface setting %d",err,alternateSettingNumber);
   205 		User::Leave(err);
   206 		}
   207 	
   208 	RDebug::Printf("Alternate interface setting %d set",alternateSettingNumber);
   209 	}
   210 
   211 
   212 TInt CInterfaceBase::StallEndpoint(TUint16 aEndpointNumber)
   213 	{
   214 	LOG_FUNC
   215 	
   216 	RDebug::Printf("Stalling endpoint%d",aEndpointNumber);
   217 	return iClientDriver.HaltEndpoint(static_cast<TEndpointNumber>(aEndpointNumber));
   218 	}
   219 
   220 	
   221 CInterfaceSettingBase& CInterfaceBase::AlternateSetting(TInt aSettingNumber) const
   222 	{
   223 	return *iAlternateSettings[aSettingNumber];
   224 	}
   225 
   226 	
   227 TInt CInterfaceBase::InterfaceSettingCount() const
   228 	{
   229 	return iAlternateSettings.Count();
   230 	}
   231 
   232 
   233 TUint32 CInterfaceBase::ExtractNumberL(const TDesC8& aPayload)
   234 	{
   235 	LOG_FUNC
   236 
   237 	// Read the number of repeats and the data supplied by the host, on the specified endpoint
   238 	TLex8 lex(aPayload.Left(KNumberStringLength));
   239 	TUint32 numBytes;
   240 	User::LeaveIfError(lex.Val(numBytes, EDecimal));
   241 	RDebug::Printf("Writing %d bytes using string pattern below to IN endpoint",numBytes);
   242 	RDebug::RawPrint(aPayload.Mid(KNumberStringLength));
   243 	RDebug::Printf(""); //new line
   244 	return numBytes;
   245 	}
   246 
   247 void CInterfaceBase::ExtractTwoNumbersL(const TDesC8& aPayload, TUint32& aFirstNum, TUint32& aSecondNum)
   248 	{
   249 	LOG_FUNC
   250 
   251 	// Read the number of repeats and the data supplied by the host, on the specified endpoint
   252 	TLex8 lex1(aPayload.Left(KNumberStringLength));
   253 	User::LeaveIfError(lex1.Val(aFirstNum, EDecimal));
   254 	TLex8 lex2(aPayload.Mid(KNumberStringLength, KNumberStringLength));
   255 	User::LeaveIfError(lex2.Val(aSecondNum, EDecimal));
   256 	RDebug::Printf("Writing or Reading a total of %d bytes in repeats of %d bytes using string pattern below to IN endpoint",aFirstNum,aSecondNum);
   257 	RDebug::RawPrint(aPayload.Mid(2*KNumberStringLength));
   258 	RDebug::Printf(""); //new line
   259 	return;
   260 	}
   261 
   262 void CInterfaceBase::AlternateInterfaceSelectedL(TInt aAlternateInterfaceSetting)
   263 	{
   264 	LOG_FUNC
   265 	RDebug::Printf("Interface %S:",&iInterfaceName);	
   266 	iCurrentAlternateInterfaceSetting = aAlternateInterfaceSetting;
   267 	}
   268 
   269 
   270 TInt CInterfaceBase::ProcessRequestL(TUint8 aRequest,TUint16 aValue,TUint16 aIndex,
   271 	TUint16 aDataReqLength,const TDesC8& aPayload)
   272 	{
   273 	LOG_FUNC
   274 	RDebug::Printf("Interface %S:",&iInterfaceName);
   275 	
   276 	switch(aRequest)
   277 		{
   278 		case KVendorEmptyRequest:
   279 			// Acknowledge the request and do nothing
   280 			iEp0Reader->Acknowledge();
   281 			
   282 			RDebug::Printf("Request: Empty");
   283 			break;
   284 			
   285 		case KVendorPutPayloadRequest:
   286 			// Acknowledge the request
   287 			iEp0Reader->Acknowledge();
   288 			
   289 			RDebug::Printf("Put payload");
   290 			if(aPayload.Compare(_L8("DEADBEEF")) != 0)
   291 				{
   292 				RDebug::Printf("<Error %d> Payload not as expected",KErrCorrupt);
   293 				iDevice.ReportError(KErrCorrupt);
   294 				}
   295 			break;
   296 			
   297 		case KVendorGetPayloadRequest:
   298 			{
   299 			RDebug::Printf("Get payload");
   300 			__ASSERT_DEBUG(iAuxBuffer, User::Panic(_L("Trying to write non-allocated buffer"), KErrGeneral));
   301 			RDebug::Printf("iAuxBuffer = ....");
   302 			RDebug::RawPrint(*iAuxBuffer);
   303 			RDebug::Printf("\n");
   304 			
   305 			//Perform synchronous write to EP0
   306 			//This allows the subsequent 'Read' request to
   307 			//take place
   308 			TInt ret = iEp0Writer->WriteSynchronous(*iAuxBuffer, ETrue);
   309 			RDebug::Printf("Write (from interface callback) executed with error %d", ret);
   310 			}
   311 			break;
   312 			
   313 		case KVendorGetRecordedNumBytesReadInPayloadRequest:
   314 			{
   315 			delete iAuxBuffer;
   316 			iAuxBuffer = HBufC8::NewL(KNumberStringLength);
   317 			TPtr8 ptr(iAuxBuffer->Des());
   318 			TInt retValue = 0;
   319 			retValue = AlternateSetting(iCurrentAlternateInterfaceSetting).NumBytesReadSoFarL(aValue);
   320 			ptr.Zero();
   321 			ptr.Format(KNumberFormatString, retValue);
   322 	
   323 			//Perform synchronous write to EP0
   324 			//This allows the subsequent 'Read' request to
   325 			//take place
   326 			TInt ret = iEp0Writer->WriteSynchronous(*iAuxBuffer, ETrue);
   327 			RDebug::Printf("Write (from interface callback) executed with error %d", ret);
   328 			}
   329 			break;
   330 			
   331 		case KVendorGetRecordedNumBytesWrittenInPayloadRequest:
   332 			{
   333 			delete iAuxBuffer;
   334 			iAuxBuffer = HBufC8::NewL(KNumberStringLength);
   335 			TPtr8 ptr(iAuxBuffer->Des());
   336 			TInt retValue = 0;
   337 			retValue = AlternateSetting(iCurrentAlternateInterfaceSetting).NumBytesWrittenSoFarL(aValue);
   338 			ptr.Zero();
   339 			ptr.Format(KNumberFormatString, retValue);
   340 	
   341 			//Perform synchronous write to EP0
   342 			//This allows the subsequent 'Read' request to
   343 			//take place
   344 			TInt ret = iEp0Writer->WriteSynchronous(*iAuxBuffer, ETrue);
   345 			RDebug::Printf("Write (from interface callback) executed with error %d", ret);
   346 			}
   347 			break;
   348 			
   349 		case KVendorWriteToEndpointRequest:
   350 			// Acknowledge the request
   351 			iEp0Reader->Acknowledge();
   352 			
   353 			RDebug::Printf("Writing %d bytes to IN endpoint (index %d)",aPayload.Length(),aValue);
   354 			
   355 			// Write the data supplied by the host, back to the host though the specified endpoint
   356 			
   357 			AlternateSetting(iCurrentAlternateInterfaceSetting).WriteSpecifiedDataToEndpointL(aPayload,aValue);
   358 			break;
   359 			
   360 		case KVendorCancelWriteToEndpointRequest:
   361 			// Acknowledge the request
   362 			iEp0Reader->Acknowledge();
   363 			
   364 			RDebug::Printf("CANCEL Writing to IN endpoint (index %d)",aValue);
   365 			
   366 			// CANCEL writing the data supplied by the host, back to the host though the specified endpoint
   367 			
   368 			AlternateSetting(iCurrentAlternateInterfaceSetting).CancelWriteDataToEndpointL(aValue);
   369 			break;
   370 			
   371 		case KVendorPatternWriteToEndpointRequest:
   372 			{
   373 			// Acknowledge the request
   374 			iEp0Reader->Acknowledge();
   375 			
   376 			// Read the number of repeats and the data supplied by the host, on the specified endpoint
   377 			TUint32 numBytes = ExtractNumberL(aPayload);
   378 			
   379 			// Write the data supplied by the host, back to the host though the specified endpoint
   380 			AlternateSetting(iCurrentAlternateInterfaceSetting).WriteSpecifiedDataToEndpointL(aPayload.Mid(KNumberStringLength),numBytes,aValue);
   381 			}
   382 			break;
   383 			
   384 		case KVendorPatternWriteSynchronousToEndpointRequest:
   385 			{
   386 			// Acknowledge the request
   387 			iEp0Reader->Acknowledge();
   388 			
   389 			// Read the number of repeats and the data supplied by the host, on the specified endpoint
   390 			TUint32 numBytes = ExtractNumberL(aPayload);
   391 			
   392 			// Write the data supplied by the host, back to the host though the specified endpoint
   393 			AlternateSetting(iCurrentAlternateInterfaceSetting).WriteSynchronousSpecifiedDataToEndpointL(aPayload.Mid(KNumberStringLength),numBytes,aValue);
   394 			}
   395 			break;
   396 			
   397 		case KVendorPatternWriteSynchronousToAndHaltEndpointRequest:
   398 			{
   399 			// Acknowledge the request
   400 			iEp0Reader->Acknowledge();
   401 			
   402 			// Read the number of repeats and the data supplied by the host, on the specified endpoint
   403 			TUint32 numBytes = ExtractNumberL(aPayload);
   404 			
   405 			// Write the data supplied by the host, back to the host though the specified endpoint
   406 			AlternateSetting(iCurrentAlternateInterfaceSetting).WriteSynchronousSpecifiedDataToAndHaltEndpointL(aPayload.Mid(KNumberStringLength),numBytes,aValue);
   407 			}
   408 			break;
   409 			
   410 		case KVendorRepeatedReadAndValidateDataRequest:
   411 			{
   412 			// Acknowledge the request
   413 			iEp0Reader->Acknowledge();
   414 			
   415 			// Read the number of bytes to read in total and per individual 'Read' together with the data supplied by the host, on the specified endpoint
   416 			TUint32 numBytesPerRead = 0;
   417 			TUint32 totalNumBytes = 0;
   418 			ExtractTwoNumbersL(aPayload, numBytesPerRead, totalNumBytes);
   419 			RDebug::Printf("Extracted: Number of Bytes per Read = %d, Total Number of Bytes = %d",numBytesPerRead,totalNumBytes);
   420 			
   421 			// Write the data supplied by the host, back to the host though the specified endpoint
   422 			AlternateSetting(iCurrentAlternateInterfaceSetting).RepeatedReadAndValidateFromEndpointL(aPayload.Mid(KTwoNumberStringLength),numBytesPerRead,totalNumBytes,aValue);
   423 			}
   424 			break;
   425 			
   426 		case KVendorRepeatedPatternWriteDataRequest:
   427 			{
   428 			// Acknowledge the request
   429 			iEp0Reader->Acknowledge();
   430 			
   431 			// Read the number of bytes to write in total and per individual 'Write' together with the data supplied by the host, on the specified endpoint
   432 			TUint32 numBytesPerWrite = 0;
   433 			TUint32 totalNumBytes = 0;
   434 			ExtractTwoNumbersL(aPayload, numBytesPerWrite, totalNumBytes);
   435 			RDebug::Printf("Extracted: Number of Bytes per Read = %d, Total Number of Bytes = %d",numBytesPerWrite,totalNumBytes);
   436 			
   437 			// Write the data supplied by the host, back to the host though the specified endpoint
   438 			AlternateSetting(iCurrentAlternateInterfaceSetting).RepeatedWriteSpecifiedDataToEndpointL(aPayload.Mid(KTwoNumberStringLength),numBytesPerWrite,totalNumBytes,aValue);
   439 			}
   440 			break;
   441 			
   442 		case KVendorWriteCachedReadRequest:
   443 			{
   444 			// Acknowledge the request
   445 			iEp0Reader->Acknowledge();
   446 			
   447 			TUint16 readEndpoint = aValue >> 8; //HI 8 buts
   448 			TUint16 writeEndpoint = aValue & 0x00ff; //LO 8 bits
   449 			
   450 			RDebug::Printf("Writing data cached on OUT endpoint (index %d) to IN endpoint (index %d)",readEndpoint,writeEndpoint);
   451 			
   452 			// Write the data supplied by the host, back to the host though the specified endpoint
   453 			
   454 			AlternateSetting(iCurrentAlternateInterfaceSetting).WriteCachedEndpointDataToEndpointL(readEndpoint,writeEndpoint);
   455 			}
   456 			break;
   457 			
   458 		case KVendorWriteSynchronousCachedReadRequest:
   459 			{
   460 			// Acknowledge the request
   461 			iEp0Reader->Acknowledge();
   462 			
   463 			TUint16 readEndpoint = aValue >> 8; //HI 8 buts
   464 			TUint16 writeEndpoint = aValue & 0x00ff; //LO 8 bits
   465 			
   466 			RDebug::Printf("Writing data cached on OUT endpoint (index %d) to IN endpoint (index %d)",readEndpoint,writeEndpoint);
   467 			
   468 			// Write the data supplied by the host, back to the host though the specified endpoint
   469 			
   470 			AlternateSetting(iCurrentAlternateInterfaceSetting).WriteSynchronousCachedEndpointDataToEndpointL(readEndpoint,writeEndpoint);
   471 			}
   472 			break;
   473 			
   474 		case KVendorSplitWriteSynchronousCachedReadRequest:
   475 			{
   476 			// Acknowledge the request
   477 			iEp0Reader->Acknowledge();
   478 			
   479 			TUint16 readEndpoint = aValue >> 8; //HI 8 buts
   480 			TUint16 writeEndpoint = aValue & 0x00ff; //LO 8 bits
   481 			RDebug::Printf("Writing data cached on OUT endpoint (index %d) to IN endpoint (index %d) in sections of....",readEndpoint,writeEndpoint);
   482 			
   483 			// Read the number of bytes to use for each Write
   484 			TUint numBytes[KNumSplitWriteSections];
   485 			TUint numBytesWritten = 0;
   486 			for(TUint i=0; i<KNumSplitWriteSections; ++i)
   487 				{
   488 				TLex8 lex(aPayload.Mid(i*KNumberStringLength, KNumberStringLength));
   489 				User::LeaveIfError(lex.Val(numBytes[i], EDecimal));
   490 				RDebug::Printf("%d bytes", numBytes[i]);
   491 				// Write the data supplied by the host, back to the host though the specified endpoint
   492 				AlternateSetting(iCurrentAlternateInterfaceSetting).WriteSynchronousCachedEndpointDataToEndpointL(readEndpoint,writeEndpoint,numBytesWritten,numBytes[i]);
   493 				// Updates bytes written for next round of 'for'loop
   494 				numBytesWritten += numBytes[i];
   495 				}
   496 			}
   497 			break;
   498 			
   499 		case KVendorReadFromEndpointRequest:
   500 			{
   501 			// Acknowledge the request
   502 			iEp0Reader->Acknowledge();
   503 			
   504 			// Read the amount of data supplied by the host, on the specified endpoint
   505 			TLex8 lex(aPayload);
   506 			TUint32 numBytes;
   507 			User::LeaveIfError(lex.Val(numBytes, EDecimal));
   508 			RDebug::Printf("Reading %d bytes on OUT endpoint (index %d)",numBytes,aValue);
   509 			AlternateSetting(iCurrentAlternateInterfaceSetting).ReadDataFromEndpointL(numBytes,aValue);
   510 			}
   511 			break;
   512 			
   513 		case KVendorReadFromAndHaltEndpointRequest:
   514 			{
   515 			// Acknowledge the request
   516 			iEp0Reader->Acknowledge();
   517 			
   518 			// Read the amount of data supplied by the host, on the specified endpoint
   519 			TLex8 lex(aPayload);
   520 			TUint32 numBytes;
   521 			User::LeaveIfError(lex.Val(numBytes, EDecimal));
   522 			RDebug::Printf("Reading %d bytes on OUT endpoint (index %d) ... then halting endpoint",numBytes,aValue);
   523 			AlternateSetting(iCurrentAlternateInterfaceSetting).ReadDataFromAndHaltEndpointL(numBytes,aValue);
   524 			}
   525 			break;
   526 			
   527 		case KVendorCancelAnyReadFromEndpointRequest:
   528 			{
   529 			// Acknowledge the request
   530 			iEp0Reader->Acknowledge();
   531 			
   532 			RDebug::Printf("CANCEL Reading on OUT endpoint (index %d)",aValue);
   533 			AlternateSetting(iCurrentAlternateInterfaceSetting).CancelAnyReadDataFromEndpointL(aValue);
   534 			}
   535 			break;
   536 			
   537 		case KVendorReadUntilShortFromEndpointRequest:
   538 			{
   539 			// Acknowledge the request
   540 			iEp0Reader->Acknowledge();
   541 			
   542 			// Read the amount of data supplied by the host, on the specified endpoint
   543 			TLex8 lex(aPayload);
   544 			TUint32 numBytes;
   545 			User::LeaveIfError(lex.Val(numBytes, EDecimal));
   546 			RDebug::Printf("Reading %d bytes on OUT endpoint (index %d)",numBytes,aValue);
   547 			AlternateSetting(iCurrentAlternateInterfaceSetting).ReadDataUntilShortFromEndpointL(numBytes,aValue);
   548 			}
   549 			break;
   550 			
   551 		case KVendorStringValidationRequest:
   552 			{
   553 			// Acknowledge the request
   554 			iEp0Reader->Acknowledge();
   555 			
   556 			// Read the number of repeats and the data supplied by the host, on the specified endpoint
   557 			TLex8 lex(aPayload.Left(KNumberStringLength));
   558 			RDebug::Printf("NUMBER STRING LENGTH CALCULATED AS %d",KNumberStringLength);
   559 			TUint32 numBytes;
   560 			User::LeaveIfError(lex.Val(numBytes, EDecimal));
   561 			RDebug::Printf("Validation");
   562 			RDebug::Printf("Checking %d bytes using string pattern below exist in the buffer for endpoint %d",numBytes,aValue);
   563 			RDebug::RawPrint(aPayload.Mid(KNumberStringLength));
   564 			
   565 			delete iAuxBuffer;
   566 			iAuxBuffer = HBufC8::NewL(KPassFailStringLength);
   567 			TPtr8 ptr(iAuxBuffer->Des());
   568 			if(AlternateSetting(iCurrentAlternateInterfaceSetting).ValidateCachedEndpointDataL(aPayload.Mid(KNumberStringLength),numBytes,aValue))
   569 				{
   570 				ptr.Copy(KClientPassString);
   571 				}
   572 			else
   573 				{
   574 				ptr.Copy(KClientFailString);
   575 				}
   576 			}
   577 			break;
   578 			
   579 		case KVendorRecordedValidationResultRequest:
   580 			{
   581 			// Acknowledge the request
   582 			iEp0Reader->Acknowledge();
   583 			
   584 			delete iAuxBuffer;
   585 			iAuxBuffer = HBufC8::NewL(KPassFailStringLength);
   586 			TPtr8 ptr(iAuxBuffer->Des());
   587 			if(AlternateSetting(iCurrentAlternateInterfaceSetting).CachedEndpointResultL(aValue))
   588 				{
   589 				ptr.Copy(KClientPassString);
   590 				}
   591 			else
   592 				{
   593 				ptr.Copy(KClientFailString);
   594 				}
   595 			}
   596 			break;
   597 			
   598 		case KVendorUnrespondRequest:
   599 			// Do not acknowledge this request
   600 			
   601 			RDebug::Printf("Unrespond request: continually NAK the host");
   602 			break;
   603 			
   604 		case KVendorStallRequest:
   605 			{
   606 			// Stall the specified endpoint		
   607 			iEp0Reader->Acknowledge();
   608 			RDebug::Printf("Stalling endpoint%d",aValue);
   609 			TInt err = StallEndpoint(aValue);
   610 			if(err != KErrNone)
   611 				{
   612 				RDebug::Printf("<Error %d> unable to stall endpoint index %d",err,aValue);
   613 				iDevice.ReportError(err);
   614 				}
   615 			}
   616 
   617 		default:
   618 			// Maybe forward to derived classes
   619 			break;
   620 		}
   621 
   622 	return KErrNone;
   623 	}
   624 	
   625 
   626 void CInterfaceBase::StartEp0Reading()
   627 	{
   628 	LOG_FUNC
   629 	
   630 	iEp0Reader->ReadRequestsL();
   631 	}
   632 	
   633 
   634 void CInterfaceBase::StopEp0Reading()
   635 	{
   636 	LOG_FUNC
   637 	
   638 	iEp0Reader->Cancel();		
   639 	}
   640 
   641 	}
   642 
   643