diff -r 000000000000 -r a41df078684a kerneltest/e32test/usbho/t_usbdi/src/endpointwriter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/usbho/t_usbdi/src/endpointwriter.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,322 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// @file endpointwriter.cpp +// @internalComponent +// +// + +#include +#include +#include +#include "endpointwriter.h" +#include "testdebug.h" + +namespace NUnitTesting_USBDI + { +const TUint KMaxTransferBuffer = 0x1000; + + +CEndpointWriter::CEndpointWriter(RDevUsbcClient& aClientDriver,TEndpointNumber aEndpoint) +: CActive(EPriorityStandard), + iClientDriver(aClientDriver), + iEndpoint(aEndpoint), + iBufPtr(NULL,0) + { + CActiveScheduler::Add(this); + } + + +CEndpointWriter::~CEndpointWriter() + { + LOG_FUNC + + Cancel(); + if(iBuffer) + { + RDebug::Printf("Freeing %d bytes", iBuffer->Size()); + } + delete iBuffer; + } + + +void CEndpointWriter::DoCancel() + { + LOG_FUNC + + // Cancel the write to the endpoint + + iClientDriver.WriteCancel(iEndpoint); + } + + +TUint CEndpointWriter::NumBytesWrittenSoFar() + { + return iNumBytesWritten; + } + +void CEndpointWriter::RunL() + { + LOG_FUNC + + TInt completionCode(iStatus.Int()); + RDebug::Printf("Write completed, err=%d",completionCode); + + iNumBytesWritten += iNumBytesOnCurrentWrite; // all zero if not a repeated write + if(iNumBytesWritten < iTotalNumBytes) + //This conditional will not be entered for non-repeat cases because then + //'iNumBytesWritten' and 'iTotalNumBytes' will both be zero. + { + TUint totalNumBytesStillToWrite = iTotalNumBytes - iNumBytesWritten; + + //NB iNumBytesOnCurrentWrite should remain at the requested 'bytes per Write' value until the last iteration + iNumBytesOnCurrentWrite = totalNumBytesStillToWrite <= iNumBytesOnCurrentWrite ? totalNumBytesStillToWrite : iNumBytesOnCurrentWrite; + + //Only add a ZLP, if requested and if the last 'Write' + TBool useUsb = totalNumBytesStillToWrite <= iNumBytesOnCurrentWrite ? iUseZLP : EFalse; + TPtrC8 writeDesc = iBufPtr.Mid(iNumBytesWritten%iDataPatternLength, iNumBytesOnCurrentWrite); + RDebug::Printf("Total Bytes To Write = %d, Bytes Still To Write = %d, Bytes Written = %d, Bytes on Current 'Write'", iTotalNumBytes, totalNumBytesStillToWrite, iNumBytesWritten, iNumBytesOnCurrentWrite); + + RDebug::Printf("\n"); + RDebug::Printf("First 256 bytes (or all) of data to write"); + RDebug::RawPrint(writeDesc); + RDebug::Printf("\n"); + + + Write(writeDesc, useUsb, EFalse); + } + else + { + if(iBuffer!=NULL) + { + RDebug::Printf("Freeing %d bytes", iBuffer->Size()); + } + else + { + RDebug::Printf("iBuffer is NULL"); + } + if(iTotalNumBytes != 0) + //if a repeated write + { + RDebug::Printf("Total Bytes = %d, Bytes Written = %d", iTotalNumBytes, iNumBytesWritten); + } + delete iBuffer; + iBuffer = 0; + iNumBytesOnCurrentWrite = 0; + iNumBytesWritten = 0; + iTotalNumBytes = 0; + iDataPatternLength = 0; + iUseZLP = EFalse; + } + } + + +TInt CEndpointWriter::RunError(TInt aError) + { + LOG_FUNC + + aError = KErrNone; + return aError; + } + + +void CEndpointWriter::Write(const TDesC8& aData, TBool aUseZLP, TBool aCreateBuffer) + { + LOG_FUNC + + if(aCreateBuffer == EFalse) + { + RDebug::Printf("Use ZLP %d", aUseZLP?1:0); + iClientDriver.Write(iStatus,iEndpoint,aData,aData.Length(),aUseZLP); + SetActive(); + return; + } + + + //Copy aData to this object's buffer + //'aData' will go out of scope before the USB driver 'Write' completes + delete iBuffer; + iBuffer = NULL; + iBuffer = HBufC8::NewL(aData.Length()); + iBufPtr.Set(iBuffer->Des()); + iBufPtr.Copy(aData); + + // Write the data to the host through the endpoint (host opened pipe) + RDebug::Printf("Write Length = %d", iBufPtr.Length()); + RDebug::RawPrint(iBufPtr); + RDebug::Printf("\n"); + RDebug::Printf("Use ZLP %d", aUseZLP?1:0); + iClientDriver.Write(iStatus,iEndpoint,iBufPtr,iBufPtr.Length(),aUseZLP); + SetActive(); + } + +TInt CEndpointWriter::WriteSynchronous(const TDesC8& aData, TBool aUseZLP) + { + LOG_FUNC + + TRequestStatus status = KRequestPending; + RDebug::Printf("Write Length = %d", aData.Length()); + RDebug::RawPrint(aData); + RDebug::Printf("\n"); + RDebug::Printf("Use ZLP %d", aUseZLP?1:0); + iClientDriver.Write(status,iEndpoint,aData,aData.Length(),aUseZLP); + User::WaitForRequest(status); + RDebug::Printf("Write has completed with error %d", status.Int()); + return status.Int(); + } + +void CEndpointWriter::WriteSynchronousUsingPatternL(const TDesC8& aData, const TUint aNumBytes, const TBool aUseZLP) + { + LOG_FUNC + + TBool useZLP = EFalse; //only want this if you are making the last call to client Write (=WriteSynchronous) + if(aNumBytes <= aData.Length()) + //Don't need to allocate a buffer and copy to it - write will be done synchronously + { + if(aUseZLP) + { + useZLP = ETrue; + } + WriteSynchronous(aData.Left(aNumBytes),useZLP); + } + + else if(aNumBytes <= KMaxTransferBuffer) + //Create a buffer based on the data pattern sent and use just one 'Synchronous Write' + { + if(aUseZLP) + { + useZLP = ETrue; + } + TInt repeats = aNumBytes/aData.Length(); + TInt extraBytes = aNumBytes%aData.Length(); + delete iBuffer; + iBuffer = NULL; + iBuffer = HBufC8::NewL(aNumBytes); + TPtr8 ptr = iBuffer->Des(); + ptr.Zero(); + for(TUint i =0; iDes()); + iBufPtr.Zero(); + TInt repeats = aNumBytes/aData.Length(); + for(TUint i =0; iDes()); + iBufPtr.Zero(); + for(TUint i =0; i