usbmgmt/usbmgr/device/classdrivers/acm/classimplementation/ecacm/src/ActiveWriter.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <e32std.h>
       
    19 #include <d32usbc.h>
       
    20 #include "ActiveWriter.h"
       
    21 #include "AcmConstants.h"
       
    22 #include "AcmPanic.h"
       
    23 #include "WriteObserver.h"
       
    24 #include "AcmUtils.h"
       
    25 #include <usb/usblogger.h>
       
    26 
       
    27 #ifdef __FLOG_ACTIVE
       
    28 _LIT8(KLogComponent, "ECACM");
       
    29 #endif
       
    30 
       
    31 CActiveWriter::CActiveWriter(MWriteObserver& aParent, RDevUsbcClient& aLdd, TEndpointNumber aEndpoint)
       
    32  :	CActive(KEcacmAOPriority), 
       
    33 	iParent(aParent),
       
    34 	iLdd(aLdd),
       
    35 	iEndpoint(aEndpoint),
       
    36 	iFirstPortion(NULL, 0),
       
    37 	iSecondPortion(NULL, 0)
       
    38 /**
       
    39  * Constructor.
       
    40  *
       
    41  * @param aParent The object that will be notified when write requests 
       
    42  * complete.
       
    43  * @param aLdd The LDD handle to be used for posting write requests.
       
    44  * @param aEndpoint The endpoint to write to.
       
    45  */
       
    46 	{
       
    47 	CActiveScheduler::Add(this);
       
    48 	}
       
    49 
       
    50 CActiveWriter::~CActiveWriter()
       
    51 /**
       
    52  * Destructor.
       
    53  */
       
    54 	{
       
    55 	LOG_FUNC
       
    56 
       
    57 	Cancel();
       
    58 	}
       
    59 
       
    60 CActiveWriter* CActiveWriter::NewL(MWriteObserver& aParent, 
       
    61 								   RDevUsbcClient& aLdd,
       
    62 								   TEndpointNumber aEndpoint)
       
    63 /**
       
    64  * Standard two phase constructor.
       
    65  *
       
    66  * @param aParent The object that will be notified when write requests 
       
    67  * complete.
       
    68  * @param aLdd The LDD handle to be used for posting write requests.
       
    69  * @param aEndpoint The endpoint to write to.
       
    70  * @return Ownership of a new CActiveWriter object.
       
    71  */
       
    72 	{
       
    73 	LOG_STATIC_FUNC_ENTRY
       
    74 
       
    75 	CActiveWriter* self = new(ELeave) CActiveWriter(aParent, aLdd, aEndpoint);
       
    76 	return self;
       
    77 	}
       
    78 
       
    79 void CActiveWriter::Write(const TDesC8& aDes, 
       
    80 					TInt aLen, 
       
    81 					TBool aZlp)
       
    82 /**
       
    83  * Write the given data to the LDD.
       
    84  *
       
    85  * @param aDes A descriptor to write.
       
    86  * @param aLen The length to write.
       
    87  * @param aZlp Whether ZLP termination may be required.
       
    88  */
       
    89 	{
       
    90 	LOGTEXT(_L8(">>CActiveWriter::Write"));
       
    91 
       
    92 	if ( aZlp )
       
    93 		{
       
    94 		// the driver can be relied on to correctly handle appended ZLPs
       
    95 		// so use them when necessary..
       
    96 		iLdd.Write(iStatus, iEndpoint, aDes, aLen, ETrue);
       
    97 		iWritingState = ECompleteMessage;
       
    98 		}
       
    99 	else
       
   100 		{
       
   101 		// do we need to send this descriptor in two portions to
       
   102 		// avoid finishing the last packet on a 64 byte boundary ( avoiding
       
   103 		// expectations of a ZLP by drivers that would handle them ) ?
       
   104 		
       
   105 		// If the write request is for zero bytes a 'split' would be erroneous.
       
   106 		TBool full64BytePacket = ( aLen % KMaxPacketSize ) ? EFalse : ETrue;
       
   107 		
       
   108 		if ( full64BytePacket == EFalse || aLen == 0 )
       
   109 			{
       
   110 			iLdd.Write(iStatus, iEndpoint, aDes, aLen, EFalse);
       
   111 			iWritingState = ECompleteMessage;
       
   112 			LOGTEXT2(_L8("CActiveWriter::Writing %d bytes"), aLen);
       
   113 			}
       
   114 		else
       
   115 			{
       
   116 			// we do need to split the descriptor, sending aLen-1 bytes now 
       
   117 			// and sending a second portion with the remaining 1 byte later
       
   118 			iFirstPortion.Set(aDes.Left(aLen-1));
       
   119 			
       
   120 			// Use of Left here ensures that if we've been passed a descriptor
       
   121 			// longer than aLen (doesn't *currently* happen), we don't corrupt
       
   122 			// data.
       
   123 			iSecondPortion.Set(aDes.Left(aLen).Right(1));
       
   124 			
       
   125 			iLdd.Write(iStatus, iEndpoint, iFirstPortion, aLen-1, EFalse);
       
   126 			
       
   127 			iWritingState = EFirstMessagePart;
       
   128 			LOGTEXT3(_L8("CActiveWriter::Writing %d bytes of the %d"), aLen-1, aLen);
       
   129 			}
       
   130 		}
       
   131 	SetActive();
       
   132 
       
   133 	LOGTEXT(_L8("<<CActiveWriter::Write"));
       
   134 	}
       
   135 
       
   136 void CActiveWriter::DoCancel()
       
   137 /**
       
   138  * Cancel an outstanding write.
       
   139  */
       
   140 	{
       
   141 	LOG_FUNC
       
   142 
       
   143 	iLdd.WriteCancel(iEndpoint);
       
   144 	}
       
   145 
       
   146 void CActiveWriter::RunL()
       
   147 /**
       
   148  * This function will be called when the write completes. It notifies the 
       
   149  * parent class of the completion.
       
   150  */
       
   151 	{
       
   152 	LOG_LINE
       
   153 	LOGTEXT2(_L8(">>CActiveWriter::RunL iStatus=%d"), iStatus.Int());
       
   154 	
       
   155 	if ( iWritingState == EFirstMessagePart )
       
   156 		{
       
   157 		if ( iStatus.Int() == KErrNone )
       
   158 			{			
       
   159 			// now send the second part..
       
   160 			iLdd.Write(iStatus, iEndpoint, iSecondPortion, iSecondPortion.Length(), EFalse);
       
   161 			iWritingState = EFinalMessagePart;
       
   162 			LOGTEXT(_L8("CActiveWriter::Writing 1 byte to complete original nx64 byte message"));
       
   163 
       
   164 			SetActive();
       
   165 			}
       
   166 		else
       
   167 			{
       
   168 			// the writing of the first part failed
       
   169 			iParent.WriteCompleted(iStatus.Int());
       
   170 			}
       
   171 		}
       
   172 	else 
       
   173 		{
       
   174 		// iWritingState == ECompleteMessage or EFinalMessagePart
       
   175 		iParent.WriteCompleted(iStatus.Int());
       
   176 		}
       
   177 		
       
   178 	LOGTEXT(_L8("<<CActiveWriter::RunL"));
       
   179 	}
       
   180 
       
   181 //
       
   182 // End of file