mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbepbase.cpp
changeset 0 d0791faffa3f
child 12 523717cdb0ad
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2006-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 "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 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "cmtpusbconnection.h"
       
    22 #include "cmtpusbepbase.h"
       
    23 #include "mtpusbpanic.h"
       
    24 #include "cmtpusbcontainer.h"
       
    25 #include "mtpbuildoptions.hrh"
       
    26 #include "mtpusbprotocolconstants.h"
       
    27 #include <e32debug.h>
       
    28 
       
    29 const TUint KUSBHeaderSize = 12;
       
    30 #define UNUSED_VAR(a) (a)=(a)
       
    31 
       
    32 /**
       
    33 Destructor
       
    34 */
       
    35 CMTPUsbEpBase::~CMTPUsbEpBase()
       
    36     {
       
    37     __FLOG(_L8("CMTPUsbEpBase::~CMTPUsbEpBase - Entry"));
       
    38     Cancel();
       
    39     iPacketBuffer.Close();
       
    40     __FLOG(_L8("CMTPUsbEpBase::~CMTPUsbEpBase - Exit"));
       
    41     __FLOG_CLOSE;
       
    42     }
       
    43     
       
    44 /**
       
    45 Provides the logical endpoint number of the endpoint.
       
    46 @return The logical endpoint number. 
       
    47 */
       
    48 TEndpointNumber CMTPUsbEpBase::EndpointNumber() const
       
    49     {
       
    50     return iConnection.EndpointNumber(iId);
       
    51     }
       
    52     
       
    53 /**
       
    54 Provides the internal endpoint identifier of the endpoint.
       
    55 @return The internal endpoint identifier. 
       
    56 */
       
    57 TUint CMTPUsbEpBase::Id() const
       
    58     {
       
    59     return iId;
       
    60     }
       
    61 
       
    62 /**
       
    63 Constructor
       
    64 @param aId The internal endpoint identifier of the endpoint.
       
    65 @param aPriority the priority of the active object assigned. 
       
    66 @param aConnection MTP USB device class transport connection which controls 
       
    67 the endpoint.
       
    68 */
       
    69 CMTPUsbEpBase::CMTPUsbEpBase(TUint aId, TPriority aPriority, CMTPUsbConnection& aConnection) :
       
    70     CActive(aPriority),
       
    71     iId(aId),
       
    72     iReceiveChunkData(NULL, 0),
       
    73     iReceiveData(NULL, 0),
       
    74     iSendChunkData(NULL, 0),
       
    75     iSendData(NULL, 0),
       
    76     iIsFirstChunk(EFalse), 
       
    77     iConnection(aConnection)
       
    78     {
       
    79     CActiveScheduler::Add(this);
       
    80     }
       
    81     
       
    82 /**
       
    83 Second phase constructor.
       
    84 */
       
    85 #ifdef __FLOG_ACTIVE    
       
    86 void CMTPUsbEpBase::ConstructL(const TDesC8& aComponentName)
       
    87 #else
       
    88 void CMTPUsbEpBase::ConstructL()
       
    89 #endif
       
    90     {
       
    91     __FLOG_OPEN(KMTPSubsystem, aComponentName);
       
    92     __FLOG(_L8("CMTPUsbEpBase::ConstructL - Entry"));
       
    93     __FLOG(_L8("CMTPUsbEpBase::ConstructL - Exit"));
       
    94     }
       
    95     
       
    96 /**
       
    97 Sets the MaxPacketSize for the endpoint.
       
    98 @param aSize The maximum packet size.
       
    99 @leave One of the system wide error codes, if a processing failure occurs.
       
   100 */
       
   101 void CMTPUsbEpBase::SetMaxPacketSizeL(TUint aSize)
       
   102 	{
       
   103 	__FLOG(_L8("CMTPUsbEpBase::SetMaxPacketSizeL - Entry"));
       
   104 	iPacketSizeMax = aSize;
       
   105 	__FLOG_VA((_L8("Endpoint %d maximum packetsize = %u"), iId, iPacketSizeMax));
       
   106 	// Allocate the packet buffer.
       
   107     iPacketBuffer.ReAllocL(iPacketSizeMax);
       
   108     __FLOG(_L8("CMTPUsbEpBase::SetMaxPacketSizeL - Exit"));
       
   109 	}    
       
   110 
       
   111 /**
       
   112 Creates a stall condition on the endpoint.
       
   113 */  
       
   114 void CMTPUsbEpBase::Stall()
       
   115     {
       
   116     __FLOG(_L8("CMTPUsbEpBase::Stall - Entry"));
       
   117     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   118     Cancel();
       
   119     RDevUsbcClient& ldd(Connection().Ldd());
       
   120     const TEndpointNumber number(EndpointNumber());
       
   121     TEndpointState state;
       
   122     ldd.EndpointStatus(number, state);
       
   123     __FLOG_VA((_L8("EndpointStatus = %d"), state));
       
   124     if (state != EEndpointStateStalled)
       
   125         {
       
   126         __FLOG_VA((_L8("Halting endpoint = %d"), number));
       
   127         ldd.HaltEndpoint(number);
       
   128         }
       
   129     SetStreamState(EStalled);
       
   130     __FLOG(_L8("CMTPUsbEpBase::Stall - Exit"));
       
   131     }
       
   132 
       
   133 /**
       
   134 Clears a stall condition on the endpoint.
       
   135 */    
       
   136 void CMTPUsbEpBase::StallClear()
       
   137     {
       
   138     __FLOG(_L8("CMTPUsbEpBase::StallClear - Entry"));
       
   139     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   140     RDevUsbcClient& ldd(Connection().Ldd());
       
   141     const TEndpointNumber number(EndpointNumber());
       
   142     TEndpointState state;
       
   143     ldd.EndpointStatus(number, state);
       
   144     __FLOG_VA((_L8("EndpointStatus = %d"), state));
       
   145     if (state != EEndpointStateNotStalled)
       
   146         {
       
   147         __FLOG_VA((_L8("Clearing halt on endpoint = %d"), number));
       
   148         Connection().Ldd().ClearHaltEndpoint(number);
       
   149         }
       
   150     SetStreamState(EIdle);
       
   151     __FLOG(_L8("CMTPUsbEpBase::StallClear - Exit"));
       
   152     }
       
   153 
       
   154 /**
       
   155 Indicates whether the endpoint is currently in a stalled condition.
       
   156 @return ETrue if the endpoint is in a stalled condition, otherwise EFalse.
       
   157 */
       
   158 TBool CMTPUsbEpBase::Stalled() const
       
   159     {
       
   160     return (iState == EStalled);
       
   161     }
       
   162 
       
   163 /**
       
   164 Determines the relative order of the two endpoints based on their IDs. 
       
   165 @return Zero, if the two objects are equal; a negative value, if the first 
       
   166 endpoint's ID is less than the second, or; a positive value, if the first 
       
   167 endpoint's ID is greater than the second.
       
   168 */    
       
   169 TInt CMTPUsbEpBase::LinearOrder(const CMTPUsbEpBase& aL, const CMTPUsbEpBase& aR)
       
   170     {
       
   171     return (aL.iId - aR.iId);
       
   172     }
       
   173     
       
   174 /**
       
   175 Provides the MTP USB device class transport connection which controls the 
       
   176 endpoint.
       
   177 @return The MTP USB device class transport connection. 
       
   178 */
       
   179 CMTPUsbConnection& CMTPUsbEpBase::Connection() const
       
   180     {
       
   181     return iConnection;
       
   182     }
       
   183 
       
   184 /**
       
   185 Forces the completion of a transfer in progress. This will
       
   186 reset the data streams without having to stall the endpoints.
       
   187 
       
   188 This is needed because Windows does not expect endpoints to 
       
   189 stall on error conditions.
       
   190 
       
   191 @param aReason error code describing the reason for cancelling.
       
   192 @leave Any of the system wide error codes.
       
   193 */
       
   194 
       
   195 void CMTPUsbEpBase::CancelReceiveL(TInt aReason)
       
   196 	{
       
   197 	__FLOG(_L8("CMTPUsbEpBase::CancelReceiveL - Entry"));
       
   198      
       
   199     if (DataStreamDirection() == EReceivingState)
       
   200 	    {
       
   201 		__FLOG(_L8("Cancel in EReceivingState"));            
       
   202 	    // Cancel any outstanding request.
       
   203     	Cancel();  
       
   204 
       
   205         // Notify the connection and reset the receive data stream.
       
   206         ResetReceiveDataStream();
       
   207         ReceiveDataCompleteL(aReason, *iReceiveDataSink);
       
   208         // Flush incoming data, otherwise device and PC may get out of sync
       
   209         FlushRxDataL();
       
   210 	    }
       
   211 	    
       
   212     __FLOG(_L8("CMTPUsbEpBase::CancelReceiveL - Exit"));	
       
   213 	}
       
   214 
       
   215 /**
       
   216 Forces the completion of a transfer in progress. This will
       
   217 reset the data streams without having to stall the endpoints.
       
   218 
       
   219 This is needed because Windows does not expect endpoints to 
       
   220 stall on error conditions.
       
   221 
       
   222 @param aReason error code describing the reason for cancelling.
       
   223 @leave Any of the system wide error codes.
       
   224 */
       
   225 
       
   226 void CMTPUsbEpBase::CancelSendL(TInt aReason)
       
   227 	{
       
   228 	__FLOG(_L8("CMTPUsbEpBase::CancelSendL - Entry"));
       
   229     
       
   230 	if (DataStreamDirection() == ESendingState)
       
   231 		{
       
   232  		__FLOG(_L8("Cancel in ESendingState"));
       
   233  		// Cancel any outstanding request.
       
   234     	Cancel();  
       
   235         // Notify the connection and reset the send data stream.
       
   236         ResetSendDataStream();
       
   237         SendDataCompleteL(aReason, *iSendDataSource);
       
   238 		}
       
   239 		
       
   240 	__FLOG(_L8("CMTPUsbEpBase::CancelSendL - Exit"));
       
   241 	}
       
   242 
       
   243 /**
       
   244 Initiates an asynchronous data receive sequence. 
       
   245 @param aSink The receive data sink buffer.
       
   246 @leave One of the system wide error codes, if a processing failure occurs.
       
   247 */
       
   248 void CMTPUsbEpBase::ReceiveDataL(MMTPType& aSink)
       
   249     {
       
   250     __FLOG(_L8("CMTPUsbEpBase::ReceiveDataL - Entry"));
       
   251     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   252     if(iState != EIdle)
       
   253       {
       
   254     	Cancel();
       
   255       }
       
   256     
       
   257 
       
   258     __ASSERT_DEBUG(iState == EIdle, Panic(EMTPUsbBadState));
       
   259     
       
   260     iReceiveDataSink    = &aSink;
       
   261     iReceiveDataCommit  = iReceiveDataSink->CommitRequired();
       
   262     SetStreamState(EReceiveInitialising);
       
   263     InitiateFirstChunkReceiveL(); 
       
   264         
       
   265     __FLOG_VA((_L8("CMTPUsbEpBase state on exit = 0x%08X"), iState));
       
   266     __FLOG(_L8("CMTPUsbEpBase::ReceiveDataL - Exit")); 
       
   267     }
       
   268 
       
   269 /**
       
   270 Resumes a halted data receive sequence.
       
   271 @param aSink The receive data sink buffer.
       
   272 @leave One of the system wide error codes, if a processing failure occurs.
       
   273 */
       
   274 
       
   275 void CMTPUsbEpBase::ResumeReceiveDataL(MMTPType& aSink)
       
   276 	{
       
   277 	__FLOG(_L8("CMTPUsbEpBase::ResumeReceiveDataL - Entry"));
       
   278     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   279     __ASSERT_DEBUG(iState == EIdle, Panic(EMTPUsbBadState));
       
   280     
       
   281     iReceiveDataSink    = &aSink;
       
   282     iReceiveDataCommit  = iReceiveDataSink->CommitRequired();
       
   283     
       
   284     iChunkStatus = iReceiveDataSink->NextWriteChunk(iReceiveChunkData);
       
   285     // The first chunk is going to be read.
       
   286     iReceiveData.Set(iReceiveChunkData);
       
   287     __FLOG_VA((_L8("Issuing ReadUntilShort request on endpoint %d"), EndpointNumber()));
       
   288     __FLOG_VA((_L8("Receive chunk capacity = %d bytes, length = %d bytes"), iReceiveChunkData.MaxLength(), iReceiveChunkData.Length()));
       
   289     __FLOG_VA((_L8("Chunk status = %d"), iChunkStatus)); 
       
   290     Connection().Ldd().ReadUntilShort(iStatus, EndpointNumber(), iReceiveData);
       
   291     SetStreamState(EReceiveInProgress);
       
   292     SetActive();
       
   293     __FLOG(_L8("CMTPUsbEpBase::ResumeReceiveDataL - Exit")); 
       
   294 	}
       
   295 
       
   296 /**
       
   297 Signals the data transfer controller that an asynchronous data receive 
       
   298 sequence has completed.
       
   299 @leave One of the system wide error codes, if a processing failure occurs.
       
   300 @panic MTPUsb 2 In debug builds only, if the derived class has not fully 
       
   301 implemented the receive data path.
       
   302 */
       
   303 void CMTPUsbEpBase::ReceiveDataCompleteL(TInt /*aError*/, MMTPType& /*aSink*/)
       
   304     {
       
   305     __FLOG(_L8("CMTPUsbEpBase::ReceiveDataCompleteL - Entry"));
       
   306     __DEBUG_ONLY(Panic(EMTPUsbNotSupported));
       
   307     __FLOG(_L8("CMTPUsbEpBase::ReceiveDataCompleteL - Exit"));
       
   308     }
       
   309 
       
   310 /**
       
   311 Initiates an asynchronous data send sequence. 
       
   312 @param aSource The send data source buffer.
       
   313 @leave One of the system wide error codes, if a processing failure occurs.
       
   314 */
       
   315 void CMTPUsbEpBase::SendDataL(const MMTPType& aSource)
       
   316     {
       
   317     __FLOG(_L8("CMTPUsbEpBase::SendDataL - Entry"));
       
   318     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   319     __ASSERT_DEBUG(iState == EIdle, Panic(EMTPUsbBadState));
       
   320     
       
   321     iSendDataSource = &aSource;
       
   322     SetStreamState(ESendInitialising);
       
   323     ProcessSendDataStreamL();
       
   324         
       
   325     __FLOG_VA((_L8("CMTPUsbEpBase state on exit = 0x%08X"), iState));
       
   326     __FLOG(_L8("CMTPUsbEpBase::SendDataL - Exit"));
       
   327     }
       
   328 
       
   329 /**
       
   330 Signals tthe data transfer controller that an asynchronous data send sequence 
       
   331 has completed.
       
   332 @leave One of the system wide error codes, if a processing failure occurs.
       
   333 @panic MTPUsb 2 In debug builds only, if the derived class has not fully 
       
   334 implemented the send data path.
       
   335 */
       
   336 void CMTPUsbEpBase::SendDataCompleteL(TInt /*aError*/, const MMTPType& /*aSource*/)
       
   337     {
       
   338     __FLOG(_L8("CMTPUsbEpBase::SendDataCompleteL - Entry"));
       
   339     __DEBUG_ONLY(Panic(EMTPUsbNotSupported));
       
   340     __FLOG(_L8("CMTPUsbEpBase::SendDataCompleteL - Exit"));
       
   341     }
       
   342 
       
   343 void CMTPUsbEpBase::DoCancel()
       
   344     {
       
   345     __FLOG(_L8("CMTPUsbEpBase::DoCancel - Entry"));
       
   346     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   347     switch (iState & EStateDirection)
       
   348         {
       
   349     case EReceivingState:
       
   350         __FLOG_VA((_L8("Issuing ReadCancel on endpoint %d"), EndpointNumber()));
       
   351         Connection().Ldd().ReadCancel(EndpointNumber());
       
   352         ResetReceiveDataStream();
       
   353         break;
       
   354 
       
   355     case ESendingState:    
       
   356         __FLOG_VA((_L8("Issuing WriteCancel on endpoint %d"), EndpointNumber()));
       
   357         Connection().Ldd().WriteCancel(EndpointNumber());
       
   358         ResetSendDataStream();
       
   359         break;
       
   360 
       
   361     default:
       
   362         break;
       
   363         }
       
   364     __FLOG(_L8("CMTPUsbEpBase::DoCancel - Exit"));
       
   365     }
       
   366     
       
   367 TInt CMTPUsbEpBase::RunError(TInt aError)
       
   368     {
       
   369     __FLOG(_L8("CMTPUsbEpBase::RunError - Entry"));
       
   370     __FLOG_VA((_L8("Error = %d"), aError));  
       
   371     
       
   372     // Cancel any outstanding request.
       
   373     Cancel();  
       
   374     
       
   375     // Notify the protocol layer of the error.
       
   376     TInt32 streamDirection = DataStreamDirection();
       
   377     if (streamDirection == EReceivingState)
       
   378 	    {
       
   379 		__FLOG(_L8("Error in EReceivingState"));            
       
   380         // Notify the connection and reset the receive data stream.
       
   381         MMTPType& data(*iReceiveDataSink);
       
   382         ResetReceiveDataStream();
       
   383         TRAPD(err, ReceiveDataCompleteL(aError, data));
       
   384         UNUSED_VAR(err);
       
   385 	    }
       
   386 	else if (streamDirection == ESendingState)
       
   387 		{
       
   388 		__FLOG(_L8("Error in ESendingState"));
       
   389         // Notify the connection and reset the send data stream.
       
   390         const MMTPType& data(*iSendDataSource);
       
   391         ResetSendDataStream();
       
   392         TRAPD(err, SendDataCompleteL(aError, data));
       
   393         UNUSED_VAR(err);
       
   394 		}
       
   395 	    
       
   396     __FLOG(_L8("CMTPUsbEpBase::RunError - Exit"));
       
   397     return KErrNone;
       
   398     }
       
   399 
       
   400 void CMTPUsbEpBase::RunL()
       
   401     {
       
   402     __FLOG(_L8("CMTPUsbEpBase::RunL - Entry"));
       
   403     __FLOG_VA((_L8("Current endpoint is %d"), EndpointNumber()));
       
   404     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   405     
       
   406     switch (DataStreamDirection())
       
   407         {
       
   408     case EReceivingState:
       
   409         __FLOG_VA((_L8("Receive data completion status = %d"), iStatus.Int()));
       
   410         if (iStatus != KErrNone)
       
   411             {
       
   412             // Abnormal completion.
       
   413             SetStreamState(EReceiveComplete);
       
   414             }
       
   415         else
       
   416             {
       
   417             // Reissue the request if we got a null packet because the upper layers are not 
       
   418         	// interested in null packets.
       
   419         	if ((iReceiveData.Length() == 0) && (iReceiveData.MaxLength() > 0))
       
   420         		{
       
   421         		Connection().Ldd().ReadUntilShort(iStatus, EndpointNumber(), iReceiveData);
       
   422         		SetActive();
       
   423         		return;
       
   424         		}  
       
   425             // Update the chunk data length.
       
   426             iReceiveChunkData.SetLength(iReceiveChunkData.Length() + iReceiveData.Length());
       
   427             if (iIsFirstChunk)
       
   428 	            {
       
   429 	            // process the first chunk.
       
   430 	            ProcessFirstReceivedChunkL();  
       
   431 	            }
       
   432 	        else
       
   433 		        {
       
   434 		        ResumeReceiveDataStreamL(); 
       
   435 		        }
       
   436             }
       
   437             
       
   438         if (iState == EReceiveComplete)
       
   439             {
       
   440             // Reset the receive data stream and notify the connection.
       
   441             MMTPType& data(*iReceiveDataSink);
       
   442             ResetReceiveDataStream();
       
   443             ReceiveDataCompleteL(iStatus.Int(), data);
       
   444             }
       
   445         break;
       
   446         
       
   447     case ESendingState:   
       
   448         __FLOG_VA((_L8("Send data stream completion status = %d"), iStatus.Int())); 
       
   449         if (iStatus != KErrNone)
       
   450             {
       
   451             // Abnormal completion.
       
   452             SetStreamState(ESendComplete);
       
   453             }
       
   454         else
       
   455             {
       
   456             ProcessSendDataStreamL(); 
       
   457             }
       
   458             
       
   459         if (iState == ESendComplete)
       
   460             {
       
   461             // Reset the send data stream and notify the connection.
       
   462             const MMTPType& data(*iSendDataSource);
       
   463             ResetSendDataStream();
       
   464             SendDataCompleteL(iStatus.Int(), data);
       
   465             }
       
   466         break;
       
   467         
       
   468     default:
       
   469         __FLOG_VA((_L8("Invalid data stream state, status = %d"), iStatus.Int())); 
       
   470         Panic(EMTPUsbBadState);
       
   471         break;
       
   472         }
       
   473         
       
   474     __FLOG_VA((_L8("IsActive = %d"), IsActive()));
       
   475     __FLOG(_L8("CMTPUsbEpBase::RunL - Exit"));
       
   476     }
       
   477 
       
   478 /**
       
   479 Provides the current data stream direction.
       
   480 @return The current data stream direction (EIdle, EReceivingState, or 
       
   481 ESendingState).
       
   482 @see TState.
       
   483 */
       
   484 TInt32 CMTPUsbEpBase::DataStreamDirection() const
       
   485     {
       
   486     return (iState & EStateDirection);
       
   487     }
       
   488 
       
   489 /**
       
   490 Resets the receive data stream by clearing all receive buffer pointers and
       
   491 setting the stream state to EIdle.
       
   492 */    
       
   493 void CMTPUsbEpBase::ResetReceiveDataStream()
       
   494     {
       
   495 	__FLOG(_L8("CMTPUsbEpBase::ResetReceiveDataStream - Entry"));
       
   496     iReceiveChunkData.Set(NULL, 0, 0);
       
   497     iReceiveData.Set(NULL, 0, 0);
       
   498     iReceiveDataSink = NULL;
       
   499     SetStreamState(EIdle);
       
   500 	__FLOG(_L8("CMTPUsbEpBase::ResetReceiveDataStream - Exit"));
       
   501     }
       
   502 
       
   503 /**
       
   504 Resets the receive data stream by clearing all receive buffer pointers and
       
   505 setting the stream state to EIdle.
       
   506 */    
       
   507 void CMTPUsbEpBase::ResetSendDataStream()
       
   508     {
       
   509 	__FLOG(_L8("CMTPUsbEpBase::ResetSendDataStream - Entry"));
       
   510     iSendChunkData.Set(NULL, 0);
       
   511     iSendData.Set(NULL, 0);
       
   512     iSendDataSource = NULL;
       
   513     SetStreamState(EIdle);
       
   514 	__FLOG(_L8("CMTPUsbEpBase::ResetSendDataStream - Exit"));
       
   515     }
       
   516     
       
   517 /**
       
   518 This method verify if the received first chunk data is a valid
       
   519 USB header for BulkOut EP.
       
   520 @pre this method should only be called after the USB header is received.
       
   521 @return ETrue if the received first chunk data is a vaild USB header, otherwise EFalse.
       
   522 */
       
   523 TBool CMTPUsbEpBase::ValidateUSBHeaderL()
       
   524 	{	
       
   525 	__FLOG(_L8("CMTPUsbEpBase::ValidateUSBHeader - Entry"));
       
   526 	
       
   527 	TBool result(EFalse);
       
   528 	TUint16 containerType(Connection().BulkContainer().Uint16L(CMTPUsbContainer::EContainerType));
       
   529 	iDataLength = Connection().BulkContainer().Uint32L(CMTPUsbContainer::EContainerLength);
       
   530 	
       
   531 	//Due to an issue of Windows OS, the value of CMTPUsbContainer::EContainerLength is incorrect if the
       
   532 	//object >= 4G-12. The value should be KMaxTUint32 in this kind of cases, but in current Windows
       
   533 	//implementation it will be a value between 0 and 11.
       
   534 	//Here we reset the iDateLength to the actual size of iReceiveDataSink as a walkaround.
       
   535 	if(containerType == 2 && (iDataLength <= 11 || iDataLength == KMaxTUint32))
       
   536 		{
       
   537 		__FLOG(_L8("iDataLength <= 11, change to size of receive data sink"));			
       
   538 		iDataLength = iReceiveDataSink->Size();
       
   539 		}
       
   540 	
       
   541 	__FLOG_VA((_L8("containerType = %u , dataLength = %lu bytes"), containerType, iDataLength));
       
   542 	
       
   543 	if (iDataLength >= KUSBHeaderSize && 
       
   544 		(containerType == EMTPUsbContainerTypeCommandBlock || containerType == EMTPUsbContainerTypeDataBlock))
       
   545 		{
       
   546 		result = ETrue;
       
   547 		iDataCounter = 0;
       
   548 #ifdef _DEBUG
       
   549  		RDebug::Print(_L("Find the valid usb header------------------------------------------------------\n"));
       
   550  		TUint16 code(Connection().BulkContainer().Uint16L(CMTPUsbContainer::ECode));
       
   551  		TUint32 transactionID(Connection().BulkContainer().Uint32L(CMTPUsbContainer::ETransactionID));
       
   552  		RDebug::Print(_L("ContainerLength = 0x%x, containerType = 0x%x , code = 0x%x , transactionID = 0x%x "),  iDataLength, containerType, code, transactionID);
       
   553  		}
       
   554  	else
       
   555  		{
       
   556  		RDebug::Print(_L("inValid usb Header read..........................................................."));
       
   557 #endif
       
   558  		}
       
   559 	__FLOG(_L8("CMTPUsbEpBase::ValidateUSBHeader - Exit"));
       
   560 	return result;
       
   561 	}
       
   562 
       
   563 /**
       
   564 Initiates the first chunk received data.
       
   565 */
       
   566 void CMTPUsbEpBase::InitiateFirstChunkReceiveL()
       
   567 	{
       
   568 	__FLOG(_L8("CMTPUsbEpBase::InitiateFirstChunkReceiveL - Entry"));
       
   569 	
       
   570 	__FLOG(_L8("Fetching first write data chunk"));
       
   571     iChunkStatus = iReceiveDataSink->FirstWriteChunk(iReceiveChunkData);
       
   572     // The first chunk is going to be read.
       
   573     iIsFirstChunk = ETrue;
       
   574     iReceiveData.Set(iReceiveChunkData);
       
   575     __FLOG_VA((_L8("Issuing ReadUntilShort request on endpoint %d"), EndpointNumber()));
       
   576     __FLOG_VA((_L8("Receive chunk capacity = %d bytes, length = %d bytes"), iReceiveChunkData.MaxLength(), iReceiveChunkData.Length()));
       
   577     __FLOG_VA((_L8("Chunk status = %d"), iChunkStatus)); 
       
   578     Connection().Ldd().ReadUntilShort(iStatus, EndpointNumber(), iReceiveData);
       
   579     SetStreamState(EReceiveInProgress);
       
   580     SetActive();
       
   581     
       
   582     __FLOG(_L8("Request issued"));
       
   583 	__FLOG(_L8("CMTPUsbEpBase::InitiateFirstChunkReceiveL - Exit"));
       
   584 	}
       
   585 	
       
   586 /**
       
   587 Processes the first received chunk data.
       
   588 */
       
   589 void CMTPUsbEpBase::ProcessFirstReceivedChunkL()
       
   590 	{
       
   591 	__FLOG(_L8("CMTPUsbEpBase::ProcessFirstReceivedChunkL - Entry"));	
       
   592 	    
       
   593     // Reset it back.
       
   594     iIsFirstChunk = EFalse;
       
   595         
       
   596     if (iReceiveChunkData.MaxLength() == KUSBHeaderSize
       
   597       && iReceiveChunkData.Length() == KUSBHeaderSize)
       
   598 	    {
       
   599 	    // USB header received from BulkOut EP.
       
   600 	    // USB Header validation
       
   601 	    if (!ValidateUSBHeaderL())
       
   602 		    {
       
   603 			// If device has received trash data, flush the rest of the packet and try again.
       
   604   	  	 	// This will occur when cancelling a transfer and the PC sends buffered data after 
       
   605   	  	 	// the cancellation.
       
   606 		    TRequestStatus status;
       
   607   	  		do
       
   608 				{
       
   609 				// Keep looking for headers.
       
   610 				// The case we are trying to catch is when we have 12 garbage bytes followed by 12 good bytes.
       
   611 				// In this case the ReadOneOrMore is acting on the next packet rather than the current packet.
       
   612 				// If the garbage data is a multiple of 12 bytes, we should still be able to catch the next good
       
   613 				// header. Otherwise the ReadOneOrMore will return will <12 bytes and we will fall through
       
   614 				// to the retry code below. 
       
   615 				iReceiveData.Zero();
       
   616 				Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), iReceiveData, KUSBHeaderSize);
       
   617 				User::WaitForRequest(status);
       
   618 				} while (iReceiveData.Length()==KUSBHeaderSize && !ValidateUSBHeaderL());
       
   619 
       
   620 			if(!ValidateUSBHeaderL())
       
   621 				{ 
       
   622 				InitiateFirstChunkReceiveL();  
       
   623 				return;
       
   624 				}
       
   625 			}
       
   626 			
       
   627 		if ((iDataLength - KUSBHeaderSize) == 0)
       
   628 			{
       
   629 			// only USB header.
       
   630 			SetStreamState(EReceiveComplete);
       
   631 			}	        
       
   632 	    }
       
   633      else if (iReceiveChunkData.MaxLength() == iReceiveChunkData.Length())
       
   634 		{
       
   635 		// USB Control request setup or data packet is received from Control EP.		    		    		    
       
   636 	    // All the desired data should be received. 
       
   637 		SetStreamState(EReceiveComplete);			
       
   638 		}
       
   639 		
       
   640 	__FLOG_VA((_L8("CMTPUsbEpBase state = 0x%08X"), iState));
       
   641 	
       
   642 	if (iState == EReceiveComplete)
       
   643 		{
       
   644 		// All data is received just using the first chunk. It could be a USB Command block without parameters
       
   645 		// or USB control request setup or data. 
       
   646 		__FLOG_VA((_L8("Received = %d bytes, write data chunk capacity = %d bytes"), iReceiveChunkData.Length(), iReceiveChunkData.MaxLength()));
       
   647 		
       
   648 #ifdef MTP_DEBUG_FLOG_HEX_DUMP 
       
   649         __FLOG_HEXDUMP((iReceiveChunkData, _L8("Received data ")));
       
   650 #endif
       
   651 
       
   652 		// Commit the received data if required.
       
   653         if (iReceiveDataCommit)
       
   654 		    {
       
   655 		 	__FLOG(_L8("Commiting write data chunk"));
       
   656 	        iReceiveDataSink->CommitChunkL(iReceiveChunkData);       
       
   657 		    }
       
   658 		}
       
   659 	// Receive more data.
       
   660 	else
       
   661 		{
       
   662 		ResumeReceiveDataStreamL();
       
   663 		}
       
   664 	
       
   665 	__FLOG(_L8("CMTPUsbEpBase::ProcessFirstReceivedChunkL - Exit"));
       
   666 	}
       
   667 
       
   668 /**
       
   669 Implements the receive data streaming algorithm. It is called after the first chunk data is received provided
       
   670 there is still more data to be received. 
       
   671 */
       
   672 void CMTPUsbEpBase::ResumeReceiveDataStreamL()
       
   673     {
       
   674     __FLOG(_L8("CMTPUsbEpBase::ResumeReceiveDataStreamL - Entry"));
       
   675     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   676     TBool endStream(EFalse);
       
   677 	TBool lastChunkCommited(EFalse);
       
   678 	TBool nullPacketReceived(EFalse);
       
   679 	MMTPType *needCommit = NULL;
       
   680     // Process the received chunk (if any).
       
   681    	iDataCounter += iReceiveData.Length();
       
   682    	__FLOG_VA((_L8("iDataLength = %lu bytes"), iDataLength));
       
   683    	__FLOG_VA((_L8("iDataCounter = %lu bytes"), iDataCounter));   	
       
   684    	
       
   685    	if (iDataCounter == iDataLength)
       
   686 	   	{
       
   687 	   	endStream = ETrue;
       
   688         nullPacketReceived = ((iState == EReceiveCompleting) && (iReceiveData.Length() == 0));
       
   689 	   	}
       
   690 
       
   691     __FLOG_VA((_L8("Received = %d bytes, write data chunk capacity = %d bytes"), iReceiveChunkData.Length(), iReceiveChunkData.MaxLength()));		   
       
   692 #ifdef MTP_DEBUG_FLOG_HEX_DUMP 
       
   693     __FLOG_HEXDUMP((iReceiveChunkData, _L8("Received data ")));
       
   694 #endif
       
   695     __FLOG_VA((_L8("End of stream = %d"), endStream)); 		   
       
   696         
       
   697       // Commit the received data if required.
       
   698 	if (iReceiveDataCommit)
       
   699          {
       
   700          if ((iChunkStatus != KMTPChunkSequenceCompletion)
       
   701        		&& !endStream
       
   702           	&& (iReceiveChunkData.Length() == iReceiveChunkData.MaxLength()))
       
   703 	           {
       
   704 	           	// Two cases are covered here:
       
   705 	           	// 1. MTP file receiving: MTP type file never returns KMTPChunkSequenceCompletion,It can be received        
       
   706           		//    one part after another. Also it can be commited mutiple times.
       
   707             	// 2. Other MTP datatype receiving during the middle of data stream
       
   708 	           __FLOG(_L8("Commiting write data chunk"));
       
   709 	           needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData);
       
   710 	           lastChunkCommited = ETrue;   
       
   711 	           }
       
   712 		else if ((iChunkStatus != KMTPChunkSequenceCompletion)
       
   713 	        	&& endStream
       
   714 	        	&& !nullPacketReceived)
       
   715 		      {
       
   716 		      // It should be the end of MTP type file receiving since it never returns KMTPChunkSequenceCompletion.
       
   717 	 	      // it can be commited mutiple times.
       
   718 		      __FLOG(_L8("Commiting write data chunk"));
       
   719 		      needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData);
       
   720 		      }
       
   721 		else if ((iChunkStatus == KMTPChunkSequenceCompletion)
       
   722 	        	&& endStream
       
   723 	        	&& !nullPacketReceived)
       
   724 		      {
       
   725 		      // The last chunk data which type is any other MTP data type than MTP file type. 
       
   726 		      // It will not be commited until all the chunk data is received.
       
   727 		      __FLOG(_L8("Commiting write data chunk"));
       
   728 		      needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); 
       
   729 		      }          
       
   730          }  
       
   731 
       
   732     // Fetch the next read data chunk.  
       
   733     switch (iState)
       
   734         {
       
   735     case EReceiveInProgress:
       
   736     	if (iReceiveDataCommit) // Commiting the received data is required 
       
   737 		    {
       
   738 		    if (lastChunkCommited)
       
   739 			    {
       
   740 			    __FLOG(_L8("Fetching next write data chunk"));
       
   741 	    	 	iChunkStatus = iReceiveDataSink->NextWriteChunk(iReceiveChunkData, iDataLength - KUSBHeaderSize);
       
   742 			    }
       
   743 		    }
       
   744 		else
       
   745 			{
       
   746 			__FLOG(_L8("Fetching next write data chunk"));
       
   747     	 	iChunkStatus = iReceiveDataSink->NextWriteChunk(iReceiveChunkData, iDataLength - KUSBHeaderSize);	
       
   748 			}	         		    					      
       
   749         break;
       
   750         
       
   751     case EReceiveCompleting:
       
   752         __FLOG(_L8("Write data chunk sequence completing"));
       
   753         __FLOG_VA((_L8("Null packet received = %d"), nullPacketReceived)); 
       
   754         break;
       
   755                   
       
   756     case EIdle:
       
   757     default:
       
   758         __FLOG(_L8("Invalid receive data stream state"));
       
   759         Panic(EMTPUsbBadState);
       
   760         break;
       
   761         }
       
   762     __FLOG_VA((_L8("Chunk status = %d"), iChunkStatus)); 
       
   763         
       
   764     // Update the data stream state.
       
   765     switch (iChunkStatus)
       
   766         {
       
   767     case KErrNone:
       
   768         if (endStream)
       
   769             {
       
   770             __FLOG(_L8("Terminating packet received."));
       
   771             SetStreamState(EReceiveComplete);
       
   772             }
       
   773         else
       
   774             {
       
   775             // Full (intermediate) packet data received.
       
   776             SetStreamState(EReceiveInProgress);
       
   777             }
       
   778         break;
       
   779         
       
   780     case KMTPChunkSequenceCompletion:
       
   781 
       
   782         if (endStream)
       
   783             {
       
   784             __FLOG(_L8("Terminating packet received."));
       
   785             SetStreamState(EReceiveComplete);
       
   786             }
       
   787         else
       
   788             {           
       
   789             // Processing the last received data chunk.
       
   790             // It will be processed once or mutiple times. 
       
   791             SetStreamState(EReceiveCompleting);            
       
   792             }
       
   793         break;
       
   794         
       
   795     default:
       
   796         User::Leave(iChunkStatus);
       
   797         break;
       
   798         } 
       
   799         
       
   800     // If necessary, process the next chunk. 
       
   801     if (iState != EReceiveComplete)
       
   802         {
       
   803         __FLOG_VA((_L8("Issuing ReadUntilShort request on endpoint %d"), EndpointNumber()));
       
   804         __FLOG_VA((_L8("Receive chunk capacity = %d bytes, length = %d bytes"), iReceiveChunkData.MaxLength(), iReceiveChunkData.Length()));
       
   805         __FLOG_VA((_L8("iReceiveChunkData pointer address is %08x"), iReceiveChunkData.Ptr()));
       
   806         // TDesC8's Right() method is not used here, because the parameter passed in like iReceiveChunkData.MaxLength() - iReceiveChunkData.Length()is greater than 
       
   807         // the length of the descriptor, the function extracts the whole of the descriptor.
       
   808         if(iDataLength-iDataCounter < iReceiveChunkData.MaxLength() - iReceiveChunkData.Length())
       
   809 			{
       
   810 			iReceiveData.Set(const_cast<TUint8*>(iReceiveChunkData.Ptr() + iReceiveChunkData.Length()), 0, iDataLength - iDataCounter);
       
   811 			}
       
   812 		else
       
   813 			{
       
   814 			iReceiveData.Set(const_cast<TUint8*>(iReceiveChunkData.Ptr() + iReceiveChunkData.Length()), 0, iReceiveChunkData.MaxLength() - iReceiveChunkData.Length());
       
   815 			}  
       
   816         Connection().Ldd().ReadUntilShort(iStatus, EndpointNumber(), iReceiveData);
       
   817         SetActive();
       
   818         if(needCommit != NULL)
       
   819         	{
       
   820         	TPtr8 tmp(NULL, 0, 0);
       
   821         	needCommit->CommitChunkL(tmp);
       
   822         	}
       
   823         __FLOG(_L8("Request issued"));
       
   824         }
       
   825         
       
   826     __FLOG_VA((_L8("CMTPUsbEpBase state on exit = 0x%08X"), iState));
       
   827     __FLOG(_L8("CMTPUsbEpBase::ResumeReceiveDataStreamL - Exit"));
       
   828     }
       
   829     
       
   830 /**
       
   831 Implements the send data streaming algorithm. This algorithm regulates the 
       
   832 sequence of data chunks making up the send data stream to ensure that data is
       
   833 passed to the USB device interface in units of wMaxPacketSize integral length. 
       
   834 The algorithm attempts to avoid re-buffering unless absolutely necessary, as 
       
   835 follows:
       
   836     1.  If the data chunk size is greater than or equal to the endpoint's 
       
   837         wMaxPacketSize, then the maximum wMaxPacketSize integral data portion 
       
   838         is sent directly. Any residual data is buffered in a wMaxPacketSize 
       
   839         packet buffer.
       
   840     2.  If the data chunk size is less than the endpoint's wMaxPacketSize, then
       
   841         the data is buffered in the packet buffer. As soon as the packet buffer 
       
   842         is filled it is sent.
       
   843 @leave One of the system wide error codes, if a processing failure occurs.
       
   844 */
       
   845 void CMTPUsbEpBase::ProcessSendDataStreamL()
       
   846     {
       
   847     __FLOG(_L8("CMTPUsbEpBase::ProcessSendDataStreamL - Entry"));
       
   848     __FLOG_VA((_L8("CMTPUsbEpBase state on entry = 0x%08X"), iState));
       
   849     
       
   850     // Clear the send data stream data pointer.
       
   851     iSendData.Set(KNullDesC8);
       
   852     
       
   853     TUint chunkAvailableLen(iSendChunkData.Length());
       
   854     if (!chunkAvailableLen)
       
   855         {    
       
   856         // Fetch the next read data chunk. 
       
   857         switch (iState)
       
   858             {
       
   859         case ESendInitialising:
       
   860             __FLOG(_L8("Fetching first read data chunk"));
       
   861             iChunkStatus = iSendDataSource->FirstReadChunk(iSendChunkData);
       
   862             iPacketBuffer.Zero();
       
   863             break;
       
   864             
       
   865         case ESendInProgress:
       
   866             __FLOG(_L8("Fetching next read data chunk"));
       
   867             iChunkStatus = iSendDataSource->NextReadChunk(iSendChunkData);
       
   868             break;
       
   869             
       
   870         case ESendCompleting:
       
   871             break;
       
   872             
       
   873         case EIdle:
       
   874         default:
       
   875             __FLOG(_L8("Invalid send data stream state"));
       
   876             Panic(EMTPUsbBadState);
       
   877             break;
       
   878             }
       
   879         
       
   880         // Fetch the new chunk data size available.
       
   881         chunkAvailableLen = iSendChunkData.Length();
       
   882         
       
   883         // Update data stream state.
       
   884         switch (iChunkStatus)
       
   885             {
       
   886         case KErrNone:
       
   887             SetStreamState(ESendInProgress);
       
   888             break;
       
   889             
       
   890         case KMTPChunkSequenceCompletion:
       
   891             if (iState == ESendCompleting)
       
   892                 {
       
   893                 SetStreamState(ESendComplete);
       
   894                 }
       
   895             else
       
   896                 {
       
   897                 SetStreamState(ESendCompleting);
       
   898                 }
       
   899             break;
       
   900             
       
   901         default:
       
   902             User::Leave(iChunkStatus);
       
   903             break;
       
   904             }          
       
   905         }
       
   906         
       
   907     __FLOG_VA((_L8("Chunk status = %d"), iChunkStatus));
       
   908     
       
   909     // Process the buffered residual and/or available chunk data.
       
   910     TUint bufferedLen(iPacketBuffer.Length());
       
   911     TUint chunkIntegralLen((chunkAvailableLen / iPacketSizeMax) * iPacketSizeMax);
       
   912     TUint chunkResidualLen(chunkAvailableLen % iPacketSizeMax);
       
   913     TBool zlp(EFalse);
       
   914     __FLOG_VA((_L8("Buffered residual data = %u bytes"), bufferedLen));
       
   915     __FLOG_VA((_L8("Chunk data available = %u bytes"), chunkAvailableLen));
       
   916     __FLOG_VA((_L8("Chunk data packet integral portion = %u bytes"), chunkIntegralLen));
       
   917     __FLOG_VA((_L8("Chunk data packet residual portion = %u bytes"), chunkResidualLen));
       
   918     
       
   919     if (bufferedLen)
       
   920         {
       
   921         // Data is buffered in the packet buffer. Fill the available packet buffer space.
       
   922         if (chunkAvailableLen)
       
   923             {
       
   924             // Fill the packet buffer.
       
   925             TUint consumedLen(0);
       
   926             TUint unconsumedLen(0);
       
   927             TUint capacity(iPacketBuffer.MaxLength() - iPacketBuffer.Length());
       
   928             if (chunkAvailableLen > capacity)
       
   929                 {
       
   930                 consumedLen     = capacity;
       
   931                 unconsumedLen   = (chunkAvailableLen - consumedLen);              
       
   932                 }
       
   933             else
       
   934                 {
       
   935                 consumedLen = chunkAvailableLen;
       
   936                 }
       
   937             __FLOG_VA((_L8("Buffering %u bytes"), consumedLen));
       
   938             iPacketBuffer.Append(iSendChunkData.Left(consumedLen));
       
   939             
       
   940             // Update the available chunk data to reflect only the unconsumed portion.
       
   941             __FLOG_VA((_L8("Residual chunk data = %u bytes"), unconsumedLen));
       
   942             if (unconsumedLen)
       
   943                 {
       
   944                 iSendChunkData.Set(iSendChunkData.Right(unconsumedLen));
       
   945                 }
       
   946             else
       
   947                 {
       
   948                 iSendChunkData.Set(NULL, 0);                    
       
   949                 }
       
   950             }
       
   951         
       
   952         // Send the packet buffer when full.
       
   953         if ((iState == ESendCompleting) || (iPacketBuffer.Size() == iPacketBuffer.MaxSize()))
       
   954             {
       
   955             iSendData.Set(iPacketBuffer);
       
   956             iPacketBuffer.Zero();
       
   957             }
       
   958         
       
   959         // Set the end of stream flag.
       
   960         zlp = ((iState == ESendCompleting) && (iSendChunkData.Length() == 0));
       
   961         }
       
   962     else if (iState == ESendInProgress)
       
   963         {
       
   964         // Send the chunk data packet integral portion.
       
   965         if (chunkIntegralLen)
       
   966             {
       
   967             iSendData.Set(iSendChunkData.Left(chunkIntegralLen));   
       
   968             }
       
   969     
       
   970         // Buffer the chunk data packet residual portion.
       
   971         if (chunkResidualLen)
       
   972             {
       
   973             __FLOG_VA((_L8("Buffering %u bytes"), chunkResidualLen));
       
   974             iPacketBuffer.Append(iSendChunkData.Right(chunkResidualLen));  
       
   975             }
       
   976             
       
   977         // All data has been consumed and/or buffered.
       
   978         iSendChunkData.Set(NULL, 0);
       
   979         }
       
   980     else if (iState == ESendCompleting)
       
   981         {
       
   982         // Send all available chunk data.
       
   983         iSendData.Set(iSendChunkData);
       
   984         zlp = ETrue;
       
   985             
       
   986         // All data has been consumed.
       
   987         iSendChunkData.Set(NULL, 0);
       
   988         }
       
   989 
       
   990     // Send the available data or reschedule to process the next chunk.
       
   991     TUint sendBytes(iSendData.Length());
       
   992     if ( sendBytes||zlp )
       
   993         {
       
   994         __FLOG_VA((_L8("Issuing Write request on endpoint %d, Zlp = %d"), EndpointNumber(), zlp));
       
   995         __FLOG_VA((_L8("Send data length = %d bytes"), iSendData.Length()));
       
   996         Connection().Ldd().Write(iStatus, EndpointNumber(), iSendData, sendBytes, zlp);
       
   997         SetActive(); 
       
   998         __FLOG(_L8("Request issued"));
       
   999         }
       
  1000     else if (iState != ESendComplete)
       
  1001         {    
       
  1002         iStatus = KRequestPending;
       
  1003         TRequestStatus* status = &iStatus;
       
  1004         SetActive();
       
  1005         User::RequestComplete(status, KErrNone);
       
  1006         }
       
  1007 
       
  1008     __FLOG_VA((_L8("CMTPUsbEpBase state on exit = 0x%08X"), iState));
       
  1009     __FLOG(_L8("CMTPUsbEpBase::ProcessSendDataStreamL - Exit"));   
       
  1010     }
       
  1011 
       
  1012 /**
       
  1013 Sets the data stream state variable.
       
  1014 @param aState The new data stream state.
       
  1015 */
       
  1016 void CMTPUsbEpBase::SetStreamState(TInt aState)
       
  1017     {
       
  1018     __FLOG(_L8("SetStreamState - Entry"));
       
  1019     iState = aState;
       
  1020     __FLOG_VA((_L8("Stream state set to 0x%08X"), iState));
       
  1021     __FLOG(_L8("SetStreamState - Exit"));
       
  1022     }
       
  1023 
       
  1024 // Fix so that cancelling works.
       
  1025 /*
       
  1026  * Flush USB driver received data
       
  1027  * 
       
  1028  */
       
  1029 const TInt KFlushBufferMaxLen = 50*1024; // 50K bytes
       
  1030 #define INTERVAL_FOR_READ_TRASH_DATA   (1000*50)  // 50 Miliseconds
       
  1031 #define INTERVAL_FOR_FLUSH_TRASH_DATA  (9*INTERVAL_FOR_READ_TRASH_DATA)  // 450 Miliseconds
       
  1032 // if there is no data read in flushRxData, wait for 1.5 second at most in case forever waiting
       
  1033 #define INTERVAL_FOR_FLUSH_TRASH_DATA_IF_NO_DATA_READ  (30*INTERVAL_FOR_READ_TRASH_DATA) //1.5 SECOND 
       
  1034 
       
  1035 void CMTPUsbEpBase::FlushRxDataL()
       
  1036     {
       
  1037     				  
       
  1038     // create the read buff
       
  1039     RBuf8 readBuf;
       
  1040     readBuf.CreateL(KFlushBufferMaxLen);
       
  1041 		      
       
  1042     TUint32 uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA_IF_NO_DATA_READ;
       
  1043  			      
       
  1044     do{
       
  1045  			    	
       
  1046       // get the data size in the receive buffer ready to read
       
  1047       TInt nbytes = 0;
       
  1048       TInt err = Connection().Ldd().QueryReceiveBuffer(EndpointNumber(), nbytes);
       
  1049 #ifdef _DEBUG
       
  1050       RDebug::Print(_L("FlushRxDataL()--1---err is %d , nbytes is %d"), err, nbytes);	  
       
  1051 #endif
       
  1052  					  
       
  1053       // has data, read it
       
  1054       if( (err == KErrNone) && (nbytes > 0) )
       
  1055          {
       
  1056    
       
  1057          // synchronously read the data
       
  1058          TRequestStatus status;
       
  1059          Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf);
       
  1060          User::WaitForRequest(status);
       
  1061 	 		 
       
  1062          if(status.Int() != KErrNone)  break;
       
  1063          			               
       
  1064          // whenever some data read, reset the rest wait time .
       
  1065          uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA;
       
  1066  			               
       
  1067 #ifdef _DEBUG 			               
       
  1068          RDebug::Print(_L("FlushRxDataL()---Reset the rest wait time"));	  
       
  1069 #endif             
       
  1070          }
       
  1071        else 
       
  1072          {	
       
  1073          // wait for the data from the usb channel.
       
  1074          User::After(INTERVAL_FOR_READ_TRASH_DATA);
       
  1075          // reduce the rest time to wait 
       
  1076          uRestTimeToWait -=  INTERVAL_FOR_READ_TRASH_DATA ;
       
  1077          }	
       
  1078  	  
       
  1079 #ifdef _DEBUG 	  
       
  1080        RDebug::Print(_L("FlushRxDataL()---uRestTimeToWait is %d"), uRestTimeToWait);	  
       
  1081 #endif
       
  1082  			    	
       
  1083     }while( uRestTimeToWait > 0);
       
  1084 			    	
       
  1085     readBuf.Close();
       
  1086  
       
  1087 }