diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveWriter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveWriter.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,182 @@ +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: +* +*/ + +#include +#include +#include "ActiveWriter.h" +#include "AcmConstants.h" +#include "AcmPanic.h" +#include "WriteObserver.h" +#include "AcmUtils.h" +#include + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "ECACM"); +#endif + +CActiveWriter::CActiveWriter(MWriteObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint) + : CActive(KEcacmAOPriority), + iParent(aParent), + iLdd(aLdd), + iEndpoint(aEndpoint), + iFirstPortion(NULL, 0), + iSecondPortion(NULL, 0) +/** + * Constructor. + * + * @param aParent The object that will be notified when write requests + * complete. + * @param aLdd The LDD handle to be used for posting write requests. + * @param aEndpoint The endpoint to write to. + */ + { + CActiveScheduler::Add(this); + } + +CActiveWriter::~CActiveWriter() +/** + * Destructor. + */ + { + LOG_FUNC + + Cancel(); + } + +CActiveWriter* CActiveWriter::NewL(MWriteObserver& aParent, + RDevUsbcClient& aLdd, + TEndpointNumber aEndpoint) +/** + * Standard two phase constructor. + * + * @param aParent The object that will be notified when write requests + * complete. + * @param aLdd The LDD handle to be used for posting write requests. + * @param aEndpoint The endpoint to write to. + * @return Ownership of a new CActiveWriter object. + */ + { + LOG_STATIC_FUNC_ENTRY + + CActiveWriter* self = new(ELeave) CActiveWriter(aParent, aLdd, aEndpoint); + return self; + } + +void CActiveWriter::Write(const TDesC8& aDes, + TInt aLen, + TBool aZlp) +/** + * Write the given data to the LDD. + * + * @param aDes A descriptor to write. + * @param aLen The length to write. + * @param aZlp Whether ZLP termination may be required. + */ + { + LOGTEXT(_L8(">>CActiveWriter::Write")); + + if ( aZlp ) + { + // the driver can be relied on to correctly handle appended ZLPs + // so use them when necessary.. + iLdd.Write(iStatus, iEndpoint, aDes, aLen, ETrue); + iWritingState = ECompleteMessage; + } + else + { + // do we need to send this descriptor in two portions to + // avoid finishing the last packet on a 64 byte boundary ( avoiding + // expectations of a ZLP by drivers that would handle them ) ? + + // If the write request is for zero bytes a 'split' would be erroneous. + TBool full64BytePacket = ( aLen % KMaxPacketSize ) ? EFalse : ETrue; + + if ( full64BytePacket == EFalse || aLen == 0 ) + { + iLdd.Write(iStatus, iEndpoint, aDes, aLen, EFalse); + iWritingState = ECompleteMessage; + LOGTEXT2(_L8("CActiveWriter::Writing %d bytes"), aLen); + } + else + { + // we do need to split the descriptor, sending aLen-1 bytes now + // and sending a second portion with the remaining 1 byte later + iFirstPortion.Set(aDes.Left(aLen-1)); + + // Use of Left here ensures that if we've been passed a descriptor + // longer than aLen (doesn't *currently* happen), we don't corrupt + // data. + iSecondPortion.Set(aDes.Left(aLen).Right(1)); + + iLdd.Write(iStatus, iEndpoint, iFirstPortion, aLen-1, EFalse); + + iWritingState = EFirstMessagePart; + LOGTEXT3(_L8("CActiveWriter::Writing %d bytes of the %d"), aLen-1, aLen); + } + } + SetActive(); + + LOGTEXT(_L8("<>CActiveWriter::RunL iStatus=%d"), iStatus.Int()); + + if ( iWritingState == EFirstMessagePart ) + { + if ( iStatus.Int() == KErrNone ) + { + // now send the second part.. + iLdd.Write(iStatus, iEndpoint, iSecondPortion, iSecondPortion.Length(), EFalse); + iWritingState = EFinalMessagePart; + LOGTEXT(_L8("CActiveWriter::Writing 1 byte to complete original nx64 byte message")); + + SetActive(); + } + else + { + // the writing of the first part failed + iParent.WriteCompleted(iStatus.Int()); + } + } + else + { + // iWritingState == ECompleteMessage or EFinalMessagePart + iParent.WriteCompleted(iStatus.Int()); + } + + LOGTEXT(_L8("<