kerneltest/e32test/usbho/t_usbdi/src/TestInterfaceBase.cpp
changeset 0 a41df078684a
child 43 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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