mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbconnection.cpp
changeset 0 d0791faffa3f
child 1 f8e15b44d440
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbconnection.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,1921 @@
+// Copyright (c) 2006-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:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+#include <mtp/mtpprotocolconstants.h>
+#include <mtp/tmtptyperesponse.h>
+
+#include "cmtpusbepbulkin.h"
+#include "cmtpusbepbulkout.h"
+#include "cmtpusbconnection.h"
+#include "cmtpusbcontainer.h"
+#include "cmtpusbepcontrol.h"
+#include "cmtpusbepinterruptin.h"
+#include "mmtpconnectionmgr.h"
+#include "mmtpconnectionprotocol.h"
+#include "mtpbuildoptions.hrh"
+#include "mtpdebug.h"
+#include "mtpusbpanic.h"
+#include "mtpusbprotocolconstants.h"
+
+#ifdef _DEBUG
+#include <e32debug.h>
+#endif
+
+#define UNUSED_VAR(a) (a)=(a)
+
+
+// File type constants.
+const TInt KMTPNullChunkSize(0x00020000); // 100KB
+const TUint KUSBHeaderSize = 12;
+
+// Class constants.
+__FLOG_STMT(_LIT8(KComponent,"UsbConnection");)
+    
+// Endpoint meta data.
+const CMTPUsbConnection::TEpInfo CMTPUsbConnection::KEndpointMetaData[EMTPUsbEpNumEndpoints] = 
+    {
+        {KMTPUsbControlEpBit,   KMTPUsbControlEpDir,    KMTPUsbControlEpPoll,   KMTPUsbControlEpNAKRate,	KMTPUsbControlEp,   KMTPUsbControlEpType},  // EMTPUsbEpControl
+        {KMTPUsbBulkInEpBit,    KMTPUsbBulkInEpDir,     KMTPUsbBulkInEpPoll,    KMTPUsbBulkInEpNAKRate,		KMTPUsbBulkInEp,    KMTPUsbBulkInEpType},   // EMTPUsbEpBulkIn
+        {KMTPUsbBulkOutEpBit,   KMTPUsbBulkOutEpDir,    KMTPUsbBulkOutEpPoll,   KMTPUsbBulkOutEpNAKRate,	KMTPUsbBulkOutEp,   KMTPUsbBulkOutEpType},  // EMTPUsbEpBulkOut
+        {KMTPUsbInterruptEpBit, KMTPUsbInterruptEpDir,  KMTPUsbInterruptEpPoll, KMTPUsbInterruptEpNAKRate,	KMTPUsbInterruptEp, KMTPUsbInterruptEpType} // EMTPUsbEpInterrupt
+    }; 
+    
+/**
+USB MTP USB device class connection factory method.
+@param aConnectionMgr The MTP connection manager interface.
+@return A pointer to an MTP USB device class connection. Ownership IS 
+transfered.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+CMTPUsbConnection* CMTPUsbConnection::NewL(MMTPConnectionMgr& aConnectionMgr)
+    {
+    CMTPUsbConnection* self = new (ELeave) CMTPUsbConnection(aConnectionMgr);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+Destructor.
+*/
+CMTPUsbConnection::~CMTPUsbConnection()
+    {
+    __FLOG(_L8("~CMTPUsbConnection - Entry"));
+
+    // Terminate all endpoint data transfer activity.
+    StopConnection();
+        
+    // Close the device class endpoints and generic container buffers.
+    iEndpoints.ResetAndDestroy();
+    delete iUsbBulkContainer;
+    delete iUsbEventContainer;
+    
+    // Stop the USB device.
+    StopUsb();
+    
+    iNullBuffer.Close();
+    if (iProtocolLayer)
+	    {    	
+	    iProtocolLayer->Unbind(*this);
+	    }
+
+    __FLOG(_L8("~CMTPUsbConnection - Exit"));
+    __FLOG_CLOSE;
+    }
+
+void CMTPUsbConnection::BindL(MMTPConnectionProtocol& aProtocol)
+    {
+    __FLOG(_L8("BindL - Entry"));
+    __ASSERT_DEBUG(!iProtocolLayer, Panic(EMTPUsbBadState));
+    iProtocolLayer = &aProtocol;
+    __FLOG(_L8("BindL - Exit"));
+    }
+    
+MMTPConnectionProtocol& CMTPUsbConnection::BoundProtocolLayer()
+    {
+    __FLOG(_L8("BoundProtocolLayer - Entry"));
+    __ASSERT_DEBUG(iProtocolLayer, Panic(EMTPUsbBadState));
+    __FLOG(_L8("BoundProtocolLayer - Exit"));
+    return *iProtocolLayer;
+    }
+    
+void CMTPUsbConnection::CloseConnection()
+    {
+    __FLOG(_L8("CloseConnection - Entry"));
+    /* 
+    Terminate all endpoint data transfer activity, stall all but the control 
+    endpoints, and wait for the host to issue a Device Reset Request.
+    */
+    StopConnection();
+    TRAPD(err, BulkEndpointsStallL());
+    UNUSED_VAR(err);
+    __FLOG(_L8("CloseConnection - Exit"));
+    }
+    
+void CMTPUsbConnection::ReceiveDataL(MMTPType& aData, const TMTPTypeRequest& /*aRequest*/)
+    {
+    __FLOG(_L8("ReceiveDataL - Entry"));
+    
+    // Update the transaction state.
+    SetBulkTransactionState(EDataIToRPhase);
+    
+    // Setup the bulk container and initiate the bulk data receive sequence.
+    iUsbBulkContainer->SetPayloadL(&aData);
+    
+    //Expected containerType pre-setup here in case we don't receive IToR dataphase at all so 
+    //Cancel operation can trigger right call inside ReceiveBulkDataCompleteL(). 
+    iUsbBulkContainer->SetUint16L(CMTPUsbContainer::EContainerType, EMTPUsbContainerTypeDataBlock);
+    
+    static_cast<CMTPUsbEpBulkOut*>(iEndpoints[EMTPUsbEpBulkOut])->ReceiveBulkDataL(*iUsbBulkContainer);
+    
+    __FLOG(_L8("ReceiveDataL - Exit"));       
+    }
+
+void CMTPUsbConnection::ReceiveDataCancelL(const TMTPTypeRequest& /*aRequest*/)
+    {
+    __FLOG(_L8("ReceiveDataCancelL - Entry"));
+    
+    // Store the device status code.
+    TUint16 deviceStatus = iDeviceStatusCode;
+    
+    SetDeviceStatus(EMTPUsbDeviceStatusTransactionCancelled);
+   	static_cast<CMTPUsbEpBulkOut*>(iEndpoints[EMTPUsbEpBulkOut])->CancelReceiveL(KErrCancel);
+   	
+   	// Restore it.
+   	SetDeviceStatus(deviceStatus);
+    __FLOG(_L8("ReceiveDataCancelL - Exit"));
+    }
+
+void CMTPUsbConnection::SendDataL(const MMTPType& aData, const TMTPTypeRequest& aRequest)
+    {
+    __FLOG(_L8("SendDataL - Entry"));  
+    ProcessBulkDataInL(aRequest, aData);
+    __FLOG(_L8("SendDataL - Exit"));  
+    }
+
+void CMTPUsbConnection::SendDataCancelL(const TMTPTypeRequest& /*aRequest*/)
+    {
+    __FLOG(_L8("SendDataCancelL - Entry"));
+    // Store the device status code.
+    TUint16 deviceStatus = iDeviceStatusCode;
+    
+    SetDeviceStatus(EMTPUsbDeviceStatusTransactionCancelled);
+ 	static_cast<CMTPUsbEpBulkIn*>(iEndpoints[EMTPUsbEpBulkIn])->CancelSendL(KErrCancel);
+ 	// Restore it.
+   	SetDeviceStatus(deviceStatus);
+    __FLOG(_L8("SendDataCancelL - Exit"));
+    }
+        
+void CMTPUsbConnection::SendEventL(const TMTPTypeEvent& aEvent)
+    {    
+    __FLOG(_L8("SendEventL - Entry"));
+    
+    // Reset the event.
+    iMTPEvent.Reset(); 
+    MMTPType::CopyL(aEvent, iMTPEvent);
+    
+    switch (ConnectionState())
+        {
+    case EIdle:
+    case EStalled:
+        // Drop the event.    
+        __FLOG(_L8("Dropping the event")); 
+        BoundProtocolLayer().SendEventCompleteL(KErrNone, aEvent);
+        break;
+        
+    case EOpen:
+    case EBusy:
+        // Process the event.    
+        switch (SuspendState())
+            {
+        case ENotSuspended:
+            // Only send event if there are no pending events
+            if (!iEventPending)
+            	{
+            	// Send the event data.
+	            __FLOG(_L8("Sending the event"));
+    	        BufferEventDataL(aEvent);
+        	    SendEventDataL(); 	
+            	}
+             break;
+                
+        case ESuspended:
+            /* 
+            If remote wakeup is enabled then signal remote wakeup and buffer 
+            the event. The event will be sent when bus signalling is resumed. 
+            Otherwise the event is dropped, and a PTP UnreportedStatus event 
+            issued when the host resumes the connection.
+            */
+            if (iLdd.SignalRemoteWakeup() == KErrNone)
+                {
+                // Remote wakeup is enabled, buffer the event data.
+                __FLOG(_L8("Buffer event data and signal remote wakeup"));
+                BufferEventDataL(aEvent);
+                }
+            else
+                {
+                // Remote wakeup is not enabled, drop the event.    
+                __FLOG(_L8("Dropping the event")); 
+                BoundProtocolLayer().SendEventCompleteL(KErrNone, aEvent);
+                }
+            
+            /*
+            Update state to trigger the correct processing when the USB connection is resumed.
+            */
+            SetSuspendState(ESuspendedEventsPending);
+            break;
+                
+        case ESuspendedEventsPending:
+            // Drop the event.    
+            __FLOG(_L8("Dropping the event")); 
+            BoundProtocolLayer().SendEventCompleteL(KErrNone, aEvent);
+            break; 
+              
+        default:
+            __FLOG(_L8("Invalid suspend state"));
+            Panic(EMTPUsbBadState);
+            break;
+            }
+        break;
+                
+    default:
+        __FLOG(_L8("Invalid connection state"));
+        Panic(EMTPUsbBadState);
+        break;
+        }
+    
+    __FLOG(_L8("SendEventL - Exit"));
+    }
+    
+void CMTPUsbConnection::SendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest)
+    {
+    __FLOG(_L8("SendResponseL - Entry"));
+    __FLOG_VA((_L8("DeviceState: 0x%x TransactionState: 0x%x Connection: 0x%x"), iDeviceStatusCode, iBulkTransactionState, ConnectionState()));
+    
+    // Update the transaction state.
+	SetBulkTransactionState(EResponsePhase);
+    if (SuspendState() != ESuspended && !iIsCancelReceived)
+    	{  	      
+   		TUint16 opCode(aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode));
+   		TUint16 rspCode(aResponse.Uint16(TMTPTypeResponse::EResponseCode));
+   		__FLOG_VA((_L8("ResponseCode = 0x%04X, Operation Code = 0x%04X"), rspCode, opCode));
+    
+   		if ((opCode == EMTPOpCodeOpenSession) && (rspCode == EMTPRespCodeOK))
+        	{        
+   	    	// An session has been opened. Record the active SessionID.
+       		iMTPSessionId = aRequest.Uint32(TMTPTypeRequest::ERequestParameter1);
+       		__FLOG_VA((_L8("Processing OpenSession response, SessionID = %d"), iMTPSessionId));
+       		}
+   		else if (((opCode == EMTPOpCodeCloseSession) || (opCode == EMTPOpCodeResetDevice))&& (rspCode == EMTPRespCodeOK))
+        	{
+   	    	// An session has been closed. Clear the active SessionID.        
+       		__FLOG_VA((_L8("Processing CloseSession or ResetDevice response, SessionID = %d"), iMTPSessionId));
+       		iMTPSessionId = KMTPSessionNone;
+       		}
+
+   		/* 
+   		Setup the parameter block payload dataset. Note that since this is a 
+   		variable length dataset, it must first be reset.
+   		*/
+   		iUsbBulkParameterBlock.Reset();
+        TBool isNullParamValid = EFalse;
+        TUint numberOfNullParam = 0;    
+        /*
+        A special case: for GetNumObjects the first response parameter can be null, which means 0 objects.
+        */
+        if(opCode == EMTPOpCodeGetNumObjects)
+            {
+            isNullParamValid = ETrue;
+            numberOfNullParam = 1;
+            }
+        iUsbBulkParameterBlock.CopyIn(aResponse, TMTPTypeResponse::EResponseParameter1, TMTPTypeResponse::EResponseParameter5, isNullParamValid, numberOfNullParam);
+
+   		// Setup the bulk container.
+   		iUsbBulkContainer->SetPayloadL(const_cast<TMTPUsbParameterPayloadBlock*>(&iUsbBulkParameterBlock));
+   		iUsbBulkContainer->SetUint32L(CMTPUsbContainer::EContainerLength, static_cast<TUint32>(iUsbBulkContainer->Size()));
+   		iUsbBulkContainer->SetUint16L(CMTPUsbContainer::EContainerType, EMTPUsbContainerTypeResponseBlock);
+   		iUsbBulkContainer->SetUint16L(CMTPUsbContainer::ECode, rspCode);
+   		iUsbBulkContainer->SetUint32L(CMTPUsbContainer::ETransactionID, aRequest.Uint32(TMTPTypeRequest::ERequestTransactionID));
+
+    	// Initiate the bulk data send sequence.
+   		__FLOG_VA((_L8("Sending response 0x%04X (%d bytes)"), iUsbBulkContainer->Uint16L(CMTPUsbContainer::ECode), iUsbBulkContainer->Uint32L(CMTPUsbContainer::EContainerLength)));
+   		static_cast<CMTPUsbEpBulkIn*>(iEndpoints[EMTPUsbEpBulkIn])->SendBulkDataL(*iUsbBulkContainer);
+    	}
+    else
+    	{
+    	BoundProtocolLayer().SendResponseCompleteL(KErrNone, aResponse, aRequest);
+    	}
+    
+    __FLOG(_L8("SendResponseL - Exit"));
+    } 
+    
+void CMTPUsbConnection::TransactionCompleteL(const TMTPTypeRequest& /*aRequest*/)
+    {
+    __FLOG(_L8("TransactionCompleteL - Entry"));
+   
+   	__FLOG_VA((_L8("DeviceState: 0x%x TransactionState: 0x%x"), iDeviceStatusCode, iBulkTransactionState));
+    
+    if (iBulkTransactionState != ERequestPhase)
+    	{
+	    // Update the transaction state.
+    	SetBulkTransactionState(EIdlePhase);
+    	
+   		// Update the device status
+   		SetDeviceStatus(EMTPUsbDeviceStatusOK); 
+   		
+   		// Clear the cancel flag.
+   		iIsCancelReceived = EFalse; 
+   		
+   		// Initiate the next request phase bulk data receive sequence.
+   		InitiateBulkRequestSequenceL();
+    	}
+    
+    __FLOG(_L8("TransactionCompleteL - Exit"));
+    } 
+
+void CMTPUsbConnection::Unbind(MMTPConnectionProtocol& /*aProtocol*/)
+    {
+    __FLOG(_L8("Unbind - Entry"));
+    __ASSERT_DEBUG(iProtocolLayer, Panic(EMTPUsbBadState));
+    iProtocolLayer = NULL;
+    __FLOG(_L8("Unbind - Exit"));
+    } 
+    
+TAny* CMTPUsbConnection::GetExtendedInterface(TUid /*aInterfaceUid*/)
+    {
+    return NULL;    
+    }
+
+TUint CMTPUsbConnection::GetImplementationUid()
+    {
+    return KMTPUsbTransportImplementationUid;
+    }
+
+void CMTPUsbConnection::ReceiveBulkDataCompleteL(TInt aError, MMTPType& /*aData*/)
+    {
+    __FLOG(_L8("ReceiveBulkDataCompleteL - Entry"));  
+    if (!BulkRequestErrorHandled(aError))
+        { 
+        TUint type(iUsbBulkContainer->Uint16L(CMTPUsbContainer::EContainerType));        
+	    __FLOG_VA((_L8("Received container type 0x%04X"), type));
+	    
+	    // The proper behaviour at this point is to stall the end points
+	    // but alas Microsoft does not honor this.
+	    // The solution is to store the error code, consume all the data
+	    // sent and then forward the error code to the upper layers
+	    // which will then go through all the phases
+	    
+	    // Only go here if...
+       	if (aError != KErrNone // there is an error
+       		&& type == EMTPUsbContainerTypeDataBlock // it is a data transfer
+       		&& iDeviceStatusCode != EMTPUsbDeviceStatusTransactionCancelled // we haven't been cancelled by the initiator
+            )
+       		{
+       		__FLOG_VA((_L8("ReceiveBulkDataCompleteL - error: %d"), aError));
+       		iXferError = aError;
+       		
+       		// Update the transaction state.
+    		SetBulkTransactionState(EDataIToRPhase);
+    
+		    // Setup the bulk container and initiate the bulk data receive sequence.
+		    iNullBuffer.Close();
+		    iNullBuffer.CreateL(KMTPNullChunkSize);
+		    iNullBuffer.SetLength(KMTPNullChunkSize);
+		    iNull.SetBuffer(iNullBuffer);
+    		iUsbBulkContainer->SetPayloadL(&iNull);
+    		static_cast<CMTPUsbEpBulkOut*>(iEndpoints[EMTPUsbEpBulkOut])->ResumeReceiveDataL(*iUsbBulkContainer);
+       		}            
+	    else
+	    	{
+	    	if (iXferError != KErrNone)
+	    		{
+	    		aError = iXferError;
+	    		iXferError = KErrNone;
+	    		iNullBuffer.Close();
+	    		}
+	    	
+   	        switch (type)
+	            {
+    	    case EMTPUsbContainerTypeCommandBlock:
+        	    ProcessBulkCommandL(aError);
+           		break;
+            
+        	case EMTPUsbContainerTypeDataBlock:
+            	ProcessBulkDataOutL(aError);
+            	break;
+            
+        	case EMTPUsbContainerTypeResponseBlock:
+        	case EMTPUsbContainerTypeEventBlock:
+        	default:
+            	// Invalid container received, shutdown the bulk data pipe.
+            	__FLOG_VA((_L8("Invalid container type = 0x%04X"), type));
+            	CloseConnection();
+            	}
+	        // Reset the bulk container.
+			/* A special case for handling MTP framework's synchronous error handling during the request phase. 
+				( ie at the beginning of this function, we are in the request phase, the request is sent to the 
+				mtp f/w, which may send a synchronous error response, which will be populated into the usb bulk 
+				container and sent out by the bulk In AO. When this function is completing, the response phase 
+				has already been reached, and the container is in use by the bulk In AO, so the payload is not 
+				reset)*/
+    	    if((iBulkTransactionState != EResponsePhase)&&(!isCommandIgnored))
+	        	{
+				iUsbBulkContainer->SetPayloadL(NULL);
+				}    	    
+			// clear the flag
+			isCommandIgnored = false;
+	    	}         
+        }
+        
+    __FLOG(_L8("ReceiveBulkDataCompleteL - Exit"));
+    }
+    
+void CMTPUsbConnection::ReceiveControlRequestDataCompleteL(TInt aError, MMTPType& /*aData*/)
+    {
+    __FLOG(_L8("ReceiveControlRequestDataCompleteL - Entry"));
+    if (!ControlRequestErrorHandled(aError))
+        {
+        // Complete the control request sequence.
+        static_cast<CMTPUsbEpControl*>(iEndpoints[EMTPUsbEpControl])->SendControlRequestStatus();
+          
+        if (iUsbControlRequestSetup.Uint8(TMTPUsbControlRequestSetup::EbRequest) == EMTPUsbControlRequestCancel)
+            {
+            // Cancel data received.
+            __FLOG(_L8("Cancel request data received."));
+    
+            // Setup the event dataset.
+            __FLOG_VA((_L8("Cancellation Code = 0x%04X"), iUsbControlRequestCancelData.Uint16(TMTPUsbControlRequestCancelData::ECancellationCode)));
+            __FLOG_VA((_L8("Transaction ID = 0x%08X"), iUsbControlRequestCancelData.Uint32(TMTPUsbControlRequestCancelData::ETransactionID)));
+  
+			#ifdef _DEBUG            
+            // print log about the cacel event
+            RDebug::Print(_L("cancel event received!!!!!!!!!!!!!!!!!Transaction phase is %d ----------------\n"), BoundProtocolLayer().TransactionPhaseL(iMTPSessionId));
+            RDebug::Print(_L("The Transaction ID want to canceled is %d -------------"), iUsbControlRequestCancelData.Uint32(TMTPUsbControlRequestCancelData::ETransactionID));
+            RDebug::Print(_L("Current Transaction ID is %d ----------------"),iMTPRequest.Uint32(TMTPTypeRequest::ERequestTransactionID));
+			#endif
+            
+            isResponseTransactionCancelledNeeded = true;
+            if(  BoundProtocolLayer().TransactionPhaseL(iMTPSessionId) > EIdlePhase   ) 
+            	{
+            	
+               	  
+
+	            iMTPEvent.Reset();
+	            iMTPEvent.SetUint16(TMTPTypeEvent::EEventCode, iUsbControlRequestCancelData.Uint16(TMTPUsbControlRequestCancelData::ECancellationCode));
+	            iMTPEvent.SetUint32(TMTPTypeEvent::EEventSessionID, iMTPSessionId);
+	            
+	            // replace the transaction id in the event with the current transaction id
+	            iMTPEvent.SetUint32(TMTPTypeEvent::EEventTransactionID, iMTPRequest.Uint32(TMTPTypeRequest::ERequestTransactionID));
+	            
+	            // Set the cancel flag.
+	            iIsCancelReceived = ETrue;
+	            
+	            // Update the device status.
+	       		SetDeviceStatus(EMTPUsbDeviceStatusBusy);   
+	       		         
+	            // Notify the protocol layer.
+	            if (ConnectionOpen())
+	                {
+	                BoundProtocolLayer().ReceivedEventL(iMTPEvent);
+	                }
+            	}
+            else
+            	{
+
+				#ifdef _DEBUG 
+            	RDebug::Print(_L("cancel evnet received at idle state, stop data EPs, flush rx data, restart data eps,statusOK\n"));
+				#endif
+
+            	// stop data endpoint
+            	DataEndpointsStop();
+      
+            	//flush rx data
+            	TInt  nbytes = 0;
+            	TInt err = iLdd.QueryReceiveBuffer(EndpointNumber(EMTPUsbEpBulkOut), nbytes);
+				#ifdef _DEBUG
+            	RDebug::Print(_L("QueryReceiveBuffer()-----err is %d , nbytes is %d"), err, nbytes);
+				#endif	  
+
+            	// has data, read it
+            	if( (err == KErrNone) && (nbytes > 0) )
+            		{
+            		// create the read buff
+            		RBuf8 readBuf;
+            		readBuf.CreateL(nbytes);
+            		// synchronously read the data
+            		TRequestStatus status;
+            		iLdd.ReadOneOrMore(status, EndpointNumber(EMTPUsbEpBulkOut), readBuf);
+            		User::WaitForRequest(status);
+            		if (KErrNone == status.Int())
+            			{
+	      		 		#ifdef _DEBUG
+            			RDebug::Print(_L("%d bytes is flushed"), nbytes);
+	      		  		#endif
+            			}
+            		readBuf.Close(); 
+            		}
+            	// initiate bulk request sequence.
+            	InitiateBulkRequestSequenceL();
+                       
+            	SetDeviceStatus(EMTPUsbDeviceStatusOK);                   
+            	}
+            }
+
+        // Initiate the next control request sequence.     
+        InitiateControlRequestSequenceL();
+        }
+    __FLOG(_L8("ReceiveControlRequestDataCompleteL - Exit"));
+    }
+   
+void CMTPUsbConnection::ReceiveControlRequestSetupCompleteL(TInt aError, MMTPType& aData)
+    {
+    __FLOG(_L8("ReceiveControlRequestSetupCompleteL - Entry"));
+    if (!ControlRequestErrorHandled(aError))
+        {
+        TMTPUsbControlRequestSetup& data(static_cast<TMTPUsbControlRequestSetup&> (aData));
+        __FLOG_VA((_L8("bRequest = 0x%X"), data.Uint8(TMTPUsbControlRequestSetup::EbRequest)));
+        __FLOG_VA((_L8("wLength = %d bytes"), data.Uint16(TMTPUsbControlRequestSetup::EwLength)));
+        
+        switch (data.Uint8(TMTPUsbControlRequestSetup::EbRequest))
+            {
+        case EMTPUsbControlRequestCancel:
+            ProcessControlRequestCancelL(data);
+            break;
+            
+        case EMTPUsbControlRequestDeviceReset:
+            ProcessControlRequestDeviceResetL(data);
+            break;
+            
+        case EMTPUsbControlRequestDeviceStatus:
+            ProcessControlRequestDeviceStatusL(data);
+            break;
+  
+        default:
+            __FLOG(_L8("Unrecognised class specific request received"));
+            CloseConnection();
+            break;
+            }
+        }
+    __FLOG(_L8("ReceiveControlRequestSetupCompleteL - Exit"));
+    }
+    
+void CMTPUsbConnection::SendBulkDataCompleteL(TInt aError, const MMTPType& /*aData*/)
+    {
+    __FLOG(_L8("SendBulkDataCompleteL - Entry")); 
+
+#ifdef _DEBUG
+    RDebug::Print(_L("\nCMTPUsbConnection::SendBulkDataCompleteL----entry"));
+#endif
+    if (!BulkRequestErrorHandled(aError))
+        {
+        TUint16 containerType(iUsbBulkContainer->Uint16L(CMTPUsbContainer::EContainerType));
+
+#ifdef _DEBUG        
+      
+        TUint16 transactionID(iUsbBulkContainer->Uint32L(CMTPUsbContainer::ETransactionID));
+        RDebug::Print(_L("Time Stamp is :%d"), User::TickCount());
+        RDebug::Print(_L("the container Type is 0x%x, the transaction ID is 0x%x\n"), containerType,transactionID);
+#endif
+        
+        if (containerType == EMTPUsbContainerTypeResponseBlock)
+            {
+            // Response block sent.
+            BoundProtocolLayer().SendResponseCompleteL(aError, *static_cast<TMTPTypeResponse*>(iUsbBulkContainer->Payload()), iMTPRequest);
+    
+            // Update the transaction state.
+            if(ERequestPhase != iBulkTransactionState)
+	            {
+	            SetBulkTransactionState(ECompletingPhase);	
+	            }
+            }
+        else if (containerType == EMTPUsbContainerTypeDataBlock)
+            {
+            // Data block sent.
+            BoundProtocolLayer().SendDataCompleteL(aError, *iUsbBulkContainer->Payload(), iMTPRequest);
+            }
+        else
+	        {
+	        __FLOG(_L8("Invalid container type"));
+            Panic(EMTPUsbBadState);
+	        }
+             
+        // Reset the bulk container.
+        if(ERequestPhase != iBulkTransactionState)
+            {
+    		iUsbBulkContainer->SetPayloadL(NULL);
+            }		     
+        }
+    __FLOG(_L8("SendBulkDataCompleteL - Exit"));
+    }
+    
+void CMTPUsbConnection::SendControlRequestDataCompleteL(TInt aError, const MMTPType& /*aData*/)
+    {
+    __FLOG(_L8("SendControlRequestDataCompleteL - Entry"));
+    if (!ControlRequestErrorHandled(aError))
+        {
+        // Complete the control request sequence.
+        if (iUsbControlRequestSetup.Uint8(TMTPUsbControlRequestSetup::EbRequest) == EMTPUsbControlRequestCancel)
+            {
+            // Cancel request processed, clear the device status.
+            SetDeviceStatus(EMTPUsbDeviceStatusOK);
+            __FLOG(_L8("Cancel Request processed"));
+            }
+        
+        // Initiate the next control request sequence. 
+        InitiateControlRequestSequenceL();            
+        }
+    __FLOG(_L8("SendControlRequestDataCompleteL - Exit"));
+    }
+
+void CMTPUsbConnection::SendInterruptDataCompleteL(TInt aError, const MMTPType& /*aData*/)
+    {
+    __FLOG(_L8("SendInterruptDataCompleteL - Entry"));
+    iEventPending = EFalse;	
+    BoundProtocolLayer().SendEventCompleteL(aError, iMTPEvent);
+    __FLOG(_L8("SendInterruptDataCompleteL - Exit"));
+    }    
+
+/**
+Provides the logical endpoint bit position bits of the specified endpoint.
+@param aId The internal endpoint identifier of the endpoint.
+@return The logical endpoint bit position bits.
+*/
+TUint CMTPUsbConnection::EndpointBitPosition(TUint aId) const
+    {
+    return iEndpointInfo[aId].iBitPosition;
+    }    
+
+/**
+Provides the endpoint direction flag bits of the specified endpoint.
+@param aId The internal endpoint identifier of the endpoint.
+@return The endpoint direction flag bits.
+*/
+TUint CMTPUsbConnection::EndpointDirection(TUint aId) const
+    {
+    return iEndpointInfo[aId].iDirection;      
+    }   
+
+/**
+Provides the capabilities of the specified endpoint.
+@param aId The internal endpoint identifier of the endpoint.
+@leave KErrOverflow, if the USB device does not support the minimum number of 
+endpoints required by the USB MTP device class.
+*/
+const TUsbcEndpointCaps& CMTPUsbConnection::EndpointCapsL(TUint aId)
+    {
+    __FLOG(_L8("EndpointCapsL - Entry"));
+    
+    // Verify the the USB device supports the minimum number of endpoints.
+    TInt totalEndpoints = iDeviceCaps().iTotalEndpoints;
+    
+    __FLOG_VA((_L8("% d endpoints available, %d required"), totalEndpoints, KMTPUsbRequiredNumEndpoints));
+    if (totalEndpoints < KMTPUsbRequiredNumEndpoints)
+        {
+        User::Leave(KErrOverflow);            
+        }      
+        
+    TUint   flags(EndpointDirectionAndType(aId));
+    __FLOG_VA((_L8("Required EP%d iTypesAndDir = 0x%X"), aId, flags));
+	
+    TBool   found(EFalse);
+    for (TUint i(0); ((!found) && (i < totalEndpoints)); i++)
+        {
+        TUsbcEndpointCaps&  caps(iEndpointCapSets[i].iCaps);
+        
+        if ((caps.iTypesAndDir & flags) == flags)
+            {
+            found           = ETrue;
+            iEndpointCaps   = caps;
+			
+            __FLOG_VA((_L8("Matched EP%d iTypesAndDir = 0x%X"), i, caps.iTypesAndDir));
+            __FLOG_VA((_L8("Matched EP%d MaxPacketSize = %d"), i, caps.MaxPacketSize()));
+            __FLOG_VA((_L8("Matched EP%d MinPacketSize = %d"), i, caps.MinPacketSize()));
+            }
+        }
+        
+    if (!found)    
+        {
+        User::Leave(KErrHardwareNotAvailable);
+        }
+                
+    __FLOG(_L8("EndpointCapsL - Exit"));
+    return iEndpointCaps; 
+    }   
+
+/**
+Provides the endpoint direction and type flag bits of the specified endpoint.
+@param aId The internal endpoint identifier of the endpoint.
+@return The logical endpoint number.
+*/
+TUint CMTPUsbConnection::EndpointDirectionAndType(TUint aId) const
+    {
+    return (EndpointDirection(aId) | EndpointType(aId));      
+    } 
+
+/**
+Provides the logical endpoint number of the specified endpoint.
+@param aId The internal endpoint identifier of the endpoint.
+@return The logical endpoint number.
+*/
+TEndpointNumber CMTPUsbConnection::EndpointNumber(TUint aId) const
+    {
+    return iEndpointInfo[aId].iNumber;     
+    }    
+
+/**
+Provides the endpoint type flag bits of the specified endpoint.
+@param aId The internal endpoint identifier of the endpoint.
+@return The endpoint type flag bits.
+*/
+TUint CMTPUsbConnection::EndpointType(TUint aId) const
+    {
+    return iEndpointInfo[aId].iType;      
+    } 
+    
+/**
+Provides the USB device client interface.
+@return The USB device client interface.
+*/
+RDevUsbcClient& CMTPUsbConnection::Ldd()
+    {
+    return iLdd;
+    }
+    
+void CMTPUsbConnection::DoCancel()
+    {
+    __FLOG(_L8("DoCancel - Entry"));    
+    iLdd.AlternateDeviceStatusNotifyCancel();
+    __FLOG(_L8("DoCancel - Exit"));  
+    }
+    
+#ifdef __FLOG_ACTIVE
+TInt CMTPUsbConnection::RunError(TInt aError)
+#else
+TInt CMTPUsbConnection::RunError(TInt /*aError*/)
+#endif
+    {
+    __FLOG(_L8("RunError - Entry"));
+    __FLOG_VA((_L8("Error = %d"), aError));
+    
+    // Cancel all the outstanding requests.
+    Cancel();   
+    
+    // Stop the connection, if necessary.
+    StopConnection(); 
+    
+    // Stop the control end point.
+    ControlEndpointStop();
+    
+    // Issue the notify request again.
+    IssueAlternateDeviceStatusNotifyRequest();
+    
+    __FLOG(_L8("RunError - Exit"));
+    return KErrNone;
+    }
+    
+void CMTPUsbConnection::RunL()
+    {
+    __FLOG(_L8("RunL - Entry"));
+    
+    if (!(iControllerStateCurrent & KUsbAlternateSetting))
+        {
+        // Alternative interface setting has not changed.
+        __FLOG_VA((_L8("Alternate device state changed to %d"), iControllerStateCurrent));
+        
+        if ((SuspendState() & ESuspended) &&
+        	(iControllerStateCurrent != EUsbcDeviceStateSuspended))
+        	{
+		    //  Update state.
+		    SetSuspendState(ENotSuspended);	
+        	}
+        
+        switch (iControllerStateCurrent)
+            {
+            case EUsbcDeviceStateUndefined:
+            case EUsbcDeviceStateAttached:
+            case EUsbcDeviceStatePowered:
+            case EUsbcDeviceStateDefault:
+                StopConnection(); 
+                ControlEndpointStop();
+                break;
+            
+            case EUsbcDeviceStateAddress:
+            	// Set the Endpoint packet sizes.
+            	SetTransportPacketSizeL();
+            	
+            	// Stop the control endpoint first, in case there is still 
+            	// outstanding request.
+            	ControlEndpointStop();
+            	
+                // Initiate control endpoint data transfer activity.
+                ControlEndpointStartL();
+                break;
+            
+            case EUsbcDeviceStateConfigured:
+                {
+				__FLOG(_L8("Device state : EUsbcDeviceStateConfigured"));
+
+                if (iControllerStatePrevious == EUsbcDeviceStateSuspended)
+                    {
+                    // Resume connection data transfer activity.
+                    ResumeConnectionL();
+                    
+                    // Process buffered events.
+                    if (SuspendState() == ESuspendedEventsPending)
+                        {
+                        /* 
+                        If remote wakeup is enabled then signal remote wakeup
+                        before sending the buffered event data. Otherwise issue 
+                        a PTP UnreportedStatus event.
+                        */
+                        
+                        // Don't check for pending events since this
+                        // is after a suspend
+                        if (iRemoteWakeup)
+                            {
+                            // Send the event data.
+                            __FLOG(_L8("Sending buffered event data"));
+                            SendEventDataL();
+                            }
+                        else
+                            {
+                            // Send PTP UnreportedStatus event
+                            __FLOG(_L8("Sending PTP UnreportedStatus event"));
+                            SendUnreportedStatusEventL();
+                            }
+                        } 
+                    }
+                else
+                    {                    
+                    //restart the control endpoint    
+                    ControlEndpointStop(); 
+                    InitiateControlRequestSequenceL(); 
+
+                    //restart the data endpoint
+                    StartConnectionL();
+                    }
+                break;    
+            
+            case EUsbcDeviceStateSuspended:
+                // Suspend connection activity.
+	            SuspendConnectionL();   
+                break;
+                }
+                
+            default:
+                __FLOG(_L8("Invalid alternate device state"));
+                Panic(EMTPUsbBadState);
+                break;
+            }
+        }
+    else
+        {
+        // Alternate interface setting has changed.
+        __FLOG_VA((_L8("Alternate interface setting changed from %d to %d"), iControllerStatePrevious, iControllerStateCurrent));
+        }
+        
+        
+    // Record the controller state and issue the next notification request.
+    iControllerStatePrevious = iControllerStateCurrent;
+    IssueAlternateDeviceStatusNotifyRequest();
+    
+    __FLOG(_L8("RunL - Exit"));
+    }
+    
+/**
+Constructor.
+@param aConnectionMgr The MTP connection manager interface.
+*/
+CMTPUsbConnection::CMTPUsbConnection(MMTPConnectionMgr& aConnectionMgr) :
+    CActive(EPriorityStandard),
+    iEndpointInfo(KEndpointMetaData, EMTPUsbEpNumEndpoints),
+    iConnectionMgr(&aConnectionMgr)
+    {
+    CActiveScheduler::Add(this);
+    }
+    
+/**
+Second phase constructor.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::ConstructL()
+    {
+    __FLOG_OPEN(KMTPSubsystem, KComponent);
+    __FLOG(_L8("ConstructL - Entry"));
+    
+    // Start the USB device.
+    StartUsbL();
+    
+    // Create the device class endpoints.
+    iEndpoints.InsertInOrderL(CMTPUsbEpControl::NewL(EMTPUsbEpControl, *this), CMTPUsbEpBase::LinearOrder);
+    iEndpoints.InsertInOrderL(CMTPUsbEpBulkIn::NewL(EMTPUsbEpBulkIn, *this), CMTPUsbEpBase::LinearOrder);
+    iEndpoints.InsertInOrderL(CMTPUsbEpBulkOut::NewL(EMTPUsbEpBulkOut, *this), CMTPUsbEpBase::LinearOrder);
+    iEndpoints.InsertInOrderL(CMTPUsbEpInterruptIn::NewL(EMTPUsbEpInterrupt, *this), CMTPUsbEpBase::LinearOrder);
+       
+    // Create the generic data container buffers.
+    iUsbBulkContainer   = CMTPUsbContainer::NewL();
+    iUsbEventContainer  = CMTPUsbContainer::NewL();
+    
+    // Initialise the device status.
+    SetDeviceStatus(EMTPUsbDeviceStatusOK);
+    
+    // Fetch the remote wakeup flag.
+    TUsbDeviceCaps dCaps;
+    User::LeaveIfError(iLdd.DeviceCaps(dCaps));
+    iRemoteWakeup = dCaps().iRemoteWakeup;
+    __FLOG_VA((_L8("iRemote = %d"), iRemoteWakeup));
+    
+    // Start monitoring the USB device controller state.
+    IssueAlternateDeviceStatusNotifyRequest();
+    
+    __FLOG(_L8("ConstructL - Exit"));
+    }
+
+/**
+Issues a request for notification of USB device controller state and alternate
+interface setting changes.
+*/
+void CMTPUsbConnection::IssueAlternateDeviceStatusNotifyRequest()
+    {
+    __FLOG(_L8("IssueAlternateDeviceStatusNotifyRequest - Entry"));
+    
+    if (!IsActive())
+        {
+        iLdd.AlternateDeviceStatusNotify(iStatus, iControllerStateCurrent);
+        }
+
+    SetActive();
+    __FLOG(_L8("IssueAlternateDeviceStatusNotifyRequest - Exit"));
+    }
+    
+/**
+Populates the asynchronous event interrupt dataset buffer.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::BufferEventDataL(const TMTPTypeEvent& aEvent)
+    {
+    __FLOG(_L8("BufferEventData - Entry")); 
+    /* 
+    Setup the parameter block payload dataset. Note that since this is a 
+    variable length dataset, it must first be reset.
+    */ 
+    iUsbEventParameterBlock.Reset();
+    iUsbEventParameterBlock.CopyIn(aEvent, TMTPTypeEvent::EEventParameter1, TMTPTypeEvent::EEventParameter3, EFalse, 0);
+    
+    // Setup the bulk container.
+    iUsbEventContainer->SetPayloadL(const_cast<TMTPUsbParameterPayloadBlock*>(&iUsbEventParameterBlock));
+    iUsbEventContainer->SetUint32L(CMTPUsbContainer::EContainerLength, iUsbEventContainer->Size());
+    iUsbEventContainer->SetUint16L(CMTPUsbContainer::EContainerType, EMTPUsbContainerTypeEventBlock);
+    iUsbEventContainer->SetUint16L(CMTPUsbContainer::ECode, aEvent.Uint16(TMTPTypeEvent::EEventCode));
+    iUsbEventContainer->SetUint32L(CMTPUsbContainer::ETransactionID, aEvent.Uint32(TMTPTypeEvent::EEventTransactionID));
+    __FLOG(_L8("BufferEventData - Exit"));
+    }
+    
+/**
+Initiates an interrupt data send sequence.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::SendEventDataL()
+    {
+    __FLOG(_L8("SendEventData - Entry"));
+    __FLOG_VA((_L8("Sending event 0x%4X (%d bytes)"), iUsbEventContainer->Uint16L(CMTPUsbContainer::ECode), iUsbEventContainer->Uint32L(CMTPUsbContainer::EContainerLength)));
+    static_cast<CMTPUsbEpInterruptIn*>(iEndpoints[EMTPUsbEpInterrupt])->SendInterruptDataL(*iUsbEventContainer);
+    iEventPending = ETrue;
+    __FLOG(_L8("SendEventData - Exit"));
+    }
+    
+/**
+Issues a PTP UnreportedStatus event.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::SendUnreportedStatusEventL()
+    {
+    __FLOG(_L8("SendUnreportedStatusEventL - Entry"));
+        
+    // Construct an UnreportedStatus event
+    TMTPTypeEvent mtpEvent;
+    mtpEvent.SetUint16(TMTPTypeEvent::EEventCode, EMTPEventCodeUnreportedStatus);
+    mtpEvent.SetUint32(TMTPTypeEvent::EEventSessionID, KMTPSessionNone);
+    mtpEvent.SetUint32(TMTPTypeEvent::EEventTransactionID, KMTPTransactionIdNone);
+    SendEventL(mtpEvent);
+    
+    __FLOG(_L8("SendUnreportedStatusEventL - Exit"));
+    }
+    
+/**
+Issues a request to the bulk-out endpoint to receive a command block dataset.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::InitiateBulkRequestSequenceL()
+    {
+    __FLOG(_L8("InitiateBulkRequestSequenceL - Entry"));
+    CMTPUsbEpBulkOut& bulkOut(*static_cast<CMTPUsbEpBulkOut*>(iEndpoints[EMTPUsbEpBulkOut]));
+
+        // Update the transaction state.
+        SetBulkTransactionState(ERequestPhase);
+        
+        // Setup the bulk container.
+        iUsbBulkParameterBlock.Reset();
+        iUsbBulkContainer->SetPayloadL(&iUsbBulkParameterBlock);
+        
+        // Initiate the next request phase bulk data receive sequence.
+        bulkOut.ReceiveBulkDataL(*iUsbBulkContainer);
+        
+    __FLOG(_L8("InitiateBulkRequestSequenceL - Exit"));
+    }
+
+/**
+Issues a request to the control endpoint to receive a request setup dataset.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::InitiateControlRequestSequenceL()
+    {
+    __FLOG(_L8("InitiateControlRequestSequenceL - Entry"));
+    CMTPUsbEpControl& ctrl(*static_cast<CMTPUsbEpControl*>(iEndpoints[EMTPUsbEpControl]));
+    if (!ctrl.Stalled())
+        {
+        ctrl.ReceiveControlRequestSetupL(iUsbControlRequestSetup);
+        }
+    __FLOG(_L8("InitiateControlRequestSequenceL - Exit"));        
+    }
+
+/**
+Processes received USB SIC bulk command block containers received from the 
+connected host on the bulk out data pipe.
+@param aError The error completion status of the bulk data receive request.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/         
+#ifdef __FLOG_ACTIVE
+void CMTPUsbConnection::ProcessBulkCommandL(TInt aError)
+#else
+void CMTPUsbConnection::ProcessBulkCommandL(TInt /*aError*/)
+#endif
+    {
+    __FLOG(_L8("ProcessBulkCommandL - Entry"));
+    __FLOG_VA((_L8("aError = %d"), aError));
+    if (BulkRequestTransactionStateValid(ERequestPhase))
+        {
+        // Request block received.
+        TUint16 op(iUsbBulkContainer->Uint16L(CMTPUsbContainer::ECode));
+   	    __FLOG_VA((_L8("Command block 0x%04X received"), op));
+        
+       	// Reset the iMTPRequest.
+       	iMTPRequest.Reset();
+
+       	// Setup the MTP request dataset buffer. Set Operation Code and TransactionID
+       	iMTPRequest.SetUint16(TMTPTypeRequest::ERequestOperationCode, op);
+       	iMTPRequest.SetUint32(TMTPTypeRequest::ERequestTransactionID, iUsbBulkContainer->Uint32L(CMTPUsbContainer::ETransactionID));
+        
+       	// Set SessionID.
+       	if (op == EMTPOpCodeOpenSession)
+           	{
+           	__FLOG(_L8("Processing OpenSession request"));
+           	// Force OpenSession requests to be processed outside an active session.
+           	// It is a known problem for MTP Protocol, it is a workaround here.
+           	iMTPRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, KMTPSessionNone);  
+           	}
+       	else if (op == EMTPOpCodeCloseSession || op == EMTPOpCodeResetDevice)
+           	{
+           	__FLOG(_L8("Processing CloseSession or the ResetDevice request"));
+           	// Force CloseSession requests to be processed outside an active session. 
+           	// ResetDevice currently behaves the same way as CloseSession. 
+           	iMTPRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, KMTPSessionNone); 
+           	iMTPRequest.SetUint32(TMTPTypeRequest::ERequestParameter1, iMTPSessionId); 
+           	}       	
+       	else
+           	{
+           	__FLOG_VA((_L8("Processing general request on session %d"), iMTPSessionId));
+           	// Update the request dataset with the single active session's SessionID.
+           	iMTPRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iMTPSessionId);
+           	}
+       	
+#ifdef _DEBUG
+       	RDebug::Print(_L("The time stamp is: %d"), User::TickCount());
+       	RDebug::Print(_L("New command comes, Operation code is 0x%x, transaction id is %d \n"), op, iUsbBulkContainer->Uint32L(CMTPUsbContainer::ETransactionID));  	
+#endif
+       	
+        TUint  commandTransID(iUsbBulkContainer->Uint32L(CMTPUsbContainer::ETransactionID));
+        	   
+        // process this command as usual
+        // Update the device status.
+        SetDeviceStatus(EMTPUsbDeviceStatusBusy);
+                  
+        // Set Parameter 1 .. Parameter 5.
+        iUsbBulkParameterBlock.CopyOut(iMTPRequest, TMTPTypeRequest::ERequestParameter1, TMTPTypeRequest::ERequestParameter5);
+        iUsbBulkParameterBlock.Reset();
+       
+        // Notify the protocol layer.
+        BoundProtocolLayer().ReceivedRequestL(iMTPRequest);
+        }
+    __FLOG(_L8("ProcessBulkCommandL - Exit"));
+    }
+
+/**
+Processes USB SIC bulk data block containers onto the connected host on the 
+bulk in data pipe.
+@param aRequest The MTP request dataset of the active MTP transaction.
+@param aData The MTP data object source.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/       
+void CMTPUsbConnection::ProcessBulkDataInL(const TMTPTypeRequest& aRequest, const MMTPType& aData)
+    {
+    __FLOG(_L8("ProcessBulkDataInL - Entry"));
+    
+    // Update the transaction state.
+    SetBulkTransactionState(EDataRToIPhase);
+    
+    // Setup the bulk container.
+    iUsbBulkContainer->SetPayloadL(const_cast<MMTPType*>(&aData));
+    
+    TUint64 size(iUsbBulkContainer->Size());
+    TUint32 containerLength((size > KMTPUsbContainerLengthMax) ? KMTPUsbContainerLengthMax : static_cast<TUint32>(size));
+    iUsbBulkContainer->SetUint32L(CMTPUsbContainer::EContainerLength, containerLength);
+    
+    iUsbBulkContainer->SetUint16L(CMTPUsbContainer::EContainerType, EMTPUsbContainerTypeDataBlock);
+    iUsbBulkContainer->SetUint16L(CMTPUsbContainer::ECode, aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode));
+    iUsbBulkContainer->SetUint32L(CMTPUsbContainer::ETransactionID, aRequest.Uint32(TMTPTypeRequest::ERequestTransactionID));
+
+    // Initiate the bulk data send sequence.
+    __FLOG_VA((_L8("Sending %d data bytes"), iUsbBulkContainer->Uint32L(CMTPUsbContainer::EContainerLength)));
+    
+#ifdef _DEBUG
+    RDebug::Print(_L("ProcessBulkDataInL:    iIsCancelReceived = %d, SuspendState() is  %d \n"),iIsCancelReceived,SuspendState());
+#endif
+    
+    // if the cancel event is received before send data. That is, the phase is before DATA R2I, 
+    // Device should not send the transaction  data to the host,just like what sendResponse does.
+    if (SuspendState() != ESuspended && !iIsCancelReceived)
+    	{
+    	TPtr8 headerChunk(NULL, 0);
+    	TBool hasTransportHeader = const_cast<MMTPType&>(aData).ReserveTransportHeader(KUSBHeaderSize, headerChunk);
+        if(hasTransportHeader)
+            {
+            TUint16 containerType = EMTPUsbContainerTypeDataBlock;
+            TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
+            TUint32 transId = aRequest.Uint32(TMTPTypeRequest::ERequestTransactionID);
+            memcpy(const_cast<TUint8*>(headerChunk.Ptr()), &containerLength, sizeof(TUint32));
+            memcpy(const_cast<TUint8*>(headerChunk.Ptr()) + 4, &containerType, sizeof(TUint16));
+            memcpy(const_cast<TUint8*>(headerChunk.Ptr()) + 6, &operationCode, sizeof(TUint16)); 
+            memcpy(const_cast<TUint8*>(headerChunk.Ptr()) + 8, &transId, sizeof(TUint32));
+            static_cast<CMTPUsbEpBulkIn*>(iEndpoints[EMTPUsbEpBulkIn])->SendBulkDataL(aData);
+            }
+        else
+            {
+            static_cast<CMTPUsbEpBulkIn*>(iEndpoints[EMTPUsbEpBulkIn])->SendBulkDataL(*iUsbBulkContainer);
+            }
+        }
+    else
+    	{
+    	
+#ifdef _DEBUG    	
+    	RDebug::Print(_L("the senddata is canceled!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"));
+#endif    	
+    	// by pass the calling to lower level send data
+    	SendBulkDataCompleteL(KErrNone, *iUsbBulkContainer);
+    	
+    	}
+    __FLOG(_L8("ProcessBulkDataInL - Exit"));
+    }
+
+/**
+Processes received USB SIC bulk data block containers received from the 
+connected host on the bulk out data pipe.
+@param aError The error completion status of the bulk data receive request.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/       
+void CMTPUsbConnection::ProcessBulkDataOutL(TInt aError)
+    {
+    __FLOG(_L8("ProcessBulkDataOutL - Entry"));
+    if ((BulkRequestTransactionStateValid(EDataIToRPhase)))
+        {
+        // Data block received, notify the protocol layer.
+        __FLOG_VA((_L8("Data block received (%d bytes)"), iUsbBulkContainer->Uint32L(CMTPUsbContainer::EContainerLength)));
+        BoundProtocolLayer().ReceiveDataCompleteL(aError, *iUsbBulkContainer->Payload(), iMTPRequest);
+        }
+    __FLOG(_L8("ProcessBulkDataOutL - Exit"));
+    }
+
+/**
+Processes received USB SIC class specific Cancel requests
+@param aRequest The USB SIC class specific request setup data.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/   
+void CMTPUsbConnection::ProcessControlRequestCancelL(const TMTPUsbControlRequestSetup& /*aRequest*/)
+    {
+    __FLOG(_L8("ProcessControlRequestCancelL - Entry"));
+    static_cast<CMTPUsbEpControl*>(iEndpoints[EMTPUsbEpControl])->ReceiveControlRequestDataL(iUsbControlRequestCancelData);
+    __FLOG(_L8("Waiting for Cancel Request Data"));
+    __FLOG(_L8("ProcessControlRequestCancelL - Exit"));
+    }
+    
+/**
+Processes received USB SIC class specific Device Reset requests
+@param aRequest The USB SIC class specific request setup data.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/ 
+void CMTPUsbConnection::ProcessControlRequestDeviceResetL(const TMTPUsbControlRequestSetup& /*aRequest*/)
+    {
+    __FLOG(_L8("ProcessControlRequestDeviceResetL - Entry"));
+                
+    // Clear stalled endpoints and re-open connection
+    BulkEndpointsStallClearL();
+    StartConnectionL();
+    
+    /*
+    The Device Reset Request is data-less. Complete the control request
+    sequence and initiate the next control request sequence. 
+    */
+    static_cast<CMTPUsbEpControl*>(iEndpoints[EMTPUsbEpControl])->SendControlRequestStatus();
+    StopConnection();
+    InitiateControlRequestSequenceL();
+    StartConnectionL();
+    __FLOG(_L8("ProcessControlRequestDeviceResetL - Exit"));
+    }
+    
+/**
+Processes received USB SIC class specific Get Device Status requests
+@param aRequest The USB SIC class specific request setup data.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/ 
+void CMTPUsbConnection::ProcessControlRequestDeviceStatusL(const TMTPUsbControlRequestSetup& aRequest)
+    {
+    __FLOG(_L8("ProcessControlRequestDeviceStatusL - Entry"));
+    iUsbControlRequestDeviceStatus.Reset();
+    
+    TUint offset = 0;
+    for(TUint i(EMTPUsbEpControl); i<EMTPUsbEpNumEndpoints; ++i)
+    	{
+        
+        if ( IsEpStalled(i) )
+            {
+            TInt epSize(0);
+            User::LeaveIfError( iLdd.GetEndpointDescriptorSize(KMTPUsbAlternateInterface, i, epSize) );
+            
+            RBuf8 epDesc; //endpoint descriptor, epDesc[2] is the address of endpoint. More info, pls refer to USB Sepc2.0 - 9.6.6
+            epDesc.CreateL(epSize);
+            CleanupClosePushL(epDesc); 
+            User::LeaveIfError( iLdd.GetEndpointDescriptor(KMTPUsbAlternateInterface, i, epDesc) );
+
+            //Maybe here is a little bit confused. Although an endpoint address is a 8-bit byte in Endpoint Descriptor,
+            //but in practice, it's requested by host with a 32-bit value, so we plus offset with 4 to reflect this.
+            TUint32 epAddress = epDesc[KEpAddressOffsetInEpDesc];
+            iUsbControlRequestDeviceStatus.SetUint32((offset + TMTPUsbControlRequestDeviceStatus::EParameter1), epAddress);            
+            CleanupStack::PopAndDestroy(); // calls epDesc.Close()
+            
+            ++offset;
+            }
+        }
+   
+
+  
+   
+    
+    // if the current status is OK and a cancel event has been received but the device has not respond 
+    // transaction_cancelled yet, return transaction_cancelled firstly.
+    TUint16 originalStatus = iDeviceStatusCode;
+    if( (iDeviceStatusCode == EMTPUsbDeviceStatusOK) && isResponseTransactionCancelledNeeded )
+    	{
+    	SetDeviceStatus(EMTPUsbDeviceStatusTransactionCancelled);
+    	  // clear the transaction cancelled flag
+        isResponseTransactionCancelledNeeded = false;
+    	}
+    
+    
+
+    
+    // Set the Code and wLength fields and send the dataset.
+    iUsbControlRequestDeviceStatus.SetUint16(TMTPUsbControlRequestDeviceStatus::ECode, iDeviceStatusCode);
+    iUsbControlRequestDeviceStatus.SetUint16(TMTPUsbControlRequestDeviceStatus::EwLength, iUsbControlRequestDeviceStatus.Size());
+    // send the response
+    static_cast<CMTPUsbEpControl*>(iEndpoints[EMTPUsbEpControl])->SendControlRequestDataL(iUsbControlRequestDeviceStatus);
+      
+    // restore the original device status
+    SetDeviceStatus(originalStatus);
+    
+    __FLOG(_L8("ProcessControlRequestDeviceStatusL - Exit"));
+    }
+
+/**
+Processes bulk transfer request completion error checking. If the completion 
+status is abnormal then the connection is shutdown.
+@param aError bulk transfer request completion error. 
+@return ETrue if the control request completion status was abnormal, otherwise
+EFalse.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+TBool CMTPUsbConnection::BulkRequestErrorHandled(TInt aError)
+    {
+    __FLOG(_L8("BulkRequestErrorHandled - Entry"));
+    __FLOG_VA((_L8("Bulk transfer request completion status = %d"), aError));
+    TBool ret(EFalse);
+    
+    // Only handle USB error codes
+    if (aError <= KErrUsbDriverBase &&
+    	aError >= KErrUsbEpNotReady)
+        {   
+        switch (aError)  
+            {        
+       	case KErrUsbDeviceNotConfigured:
+        case KErrUsbInterfaceChange:
+        case KErrUsbDeviceClosing:
+        case KErrUsbCableDetached:
+        case KErrUsbDeviceBusReset:
+            // Interface state is changing (@see RunL).
+            ret = ETrue;
+            break;
+
+        default:
+            // Unknown error on a bulk endpoint, close the connection.
+            CloseConnection();
+            ret = ETrue;
+            break;            
+            }
+        }
+    __FLOG(_L8("BulkRequestErrorHandled - Exit"));
+    return ret;
+    }
+    
+/**
+Processes bulk transfer request transaction state checking. If the transaction 
+state is invalid, then the connection is shutdown.
+@return ETrue if the control request completion status was abnormal, otherwise
+EFalse.
+*/
+TBool CMTPUsbConnection::BulkRequestTransactionStateValid(TMTPTransactionPhase aExpectedTransactionState)
+    {
+    __FLOG(_L8("BulkRequestTransactionStateValid - Entry"));
+    __FLOG_VA((_L8("Bulk transaction state = %d"), iBulkTransactionState));
+    TBool valid(iBulkTransactionState == aExpectedTransactionState);
+    if (!valid)
+        {
+        // Invalid bulk transaction state, close the connection.
+        __FLOG_VA((_L8("Expected bulk transaction state = %d"), aExpectedTransactionState));
+        CloseConnection();
+        }
+    __FLOG(_L8("BulkRequestTransactionStateValid - Exit"));
+    return valid;
+    }
+    
+/**
+Processes control request completion. If the completion status is abnormal then
+the connection is shutdown.
+@param aError control request completion error code.
+@return ETrue if the control request completion status was abnormal, otherwise
+EFalse.
+*/
+TBool CMTPUsbConnection::ControlRequestErrorHandled(TInt aError)
+    {
+    __FLOG(_L8("ControlRequestErrorHandled - Entry"));
+    __FLOG_VA((_L8("Control request completion status = %d"), aError));
+    TBool ret(EFalse);
+    
+    if (aError != KErrNone)
+        {
+        switch (aError)  
+            {
+        case KErrCancel:
+            // Control request sequence cancelled.
+            break;
+        
+        case KErrUsbDeviceNotConfigured:    
+        case KErrUsbInterfaceChange:
+        case KErrUsbDeviceClosing:
+        case KErrUsbCableDetached:
+        case KErrUsbDeviceBusReset:
+            // Interface state is changing (@see RunL).
+            break;
+
+        default:
+            // Unknown error on the control endpoint, shutdown the connection.
+            CloseConnection();
+            break;            
+            }
+            
+        // Signal abnormal completion.
+        ret = ETrue;
+        }
+    
+    __FLOG(_L8("ControlRequestErrorHandled - Exit"));
+    return ret;
+    }
+
+/**
+Clears the USB MTP device class configuration descriptor.
+*/
+void CMTPUsbConnection::ConfigurationDescriptorClear()
+    {
+    __FLOG(_L8("ConfigurationDescriptorClear - Entry"));
+    const TInt KNumInterfacesOffset(4);
+    
+    TInt descriptorSize(0);
+    iLdd.GetConfigurationDescriptorSize(descriptorSize);
+    
+    if (static_cast<TUint>(descriptorSize) == KUsbDescSize_Config)
+        {
+        TBuf8<KUsbDescSize_Config> descriptor;
+        if (iLdd.GetConfigurationDescriptor(descriptor) == KErrNone)
+            {
+            --descriptor[KNumInterfacesOffset];
+            iLdd.SetConfigurationDescriptor(descriptor);
+            }
+        }
+    
+    __FLOG(_L8("ConfigurationDescriptorClear - Exit"));
+    }
+
+/**
+Sets the USB MTP device class configuration descriptor.
+@leave KErrCorrupt, if the configuration descriptor size is invalid.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::ConfigurationDescriptorSetL()
+    {
+    __FLOG(_L8("SetupConfigurationDescriptorL - Entry"));
+    const TInt KNumInterfacesOffset(4);
+    
+    TInt descriptorSize(0);
+    iLdd.GetConfigurationDescriptorSize(descriptorSize);
+    
+    if (static_cast<TUint>(descriptorSize) != KUsbDescSize_Config)
+        {
+        User::Leave(KErrCorrupt);
+        }
+ 
+    TBuf8<KUsbDescSize_Config> descriptor;
+    User::LeaveIfError(iLdd.GetConfigurationDescriptor(descriptor));
+    ++descriptor[KNumInterfacesOffset];
+    User::LeaveIfError(iLdd.SetConfigurationDescriptor(descriptor));
+    
+    __FLOG(_L8("SetupConfigurationDescriptorL - Exit"));
+    }
+
+/**
+Indicates whether the connection state is closed.
+*/    
+TBool CMTPUsbConnection::ConnectionClosed() const
+    {
+    return (ConnectionState() < EOpen);        
+    }
+
+/**
+Indicates whether the connection state is open.
+*/
+TBool CMTPUsbConnection::ConnectionOpen() const
+    {
+    return (!ConnectionClosed());        
+    }
+    
+/**
+Starts data transfer activity on the control endpoint.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::ControlEndpointStartL()
+    {
+    __FLOG(_L8("StartControlEndpoint - Entry"));
+    InitiateControlRequestSequenceL();
+    __FLOG(_L8("StartControlEndpoint - Exit"));  
+    }
+
+/**
+Stops data transfer activity on the control endpoint.
+*/    
+void CMTPUsbConnection::ControlEndpointStop()
+    {
+    __FLOG(_L8("ControlEndpointStop - Entry"));
+    iEndpoints[EMTPUsbEpControl]->Cancel();
+    __FLOG(_L8("ControlEndpointStop - Exit"));    
+    }
+
+/**
+Stalls all but the control endpoint.
+*/    
+void CMTPUsbConnection::BulkEndpointsStallL()
+    {
+    __FLOG(_L8("BulkEndpointsStallL - Entry"));
+    EndpointStallL(EMTPUsbEpBulkIn);
+    EndpointStallL(EMTPUsbEpBulkOut);
+    SetDeviceStatus(EMTPUsbDeviceStatusTransactionCancelled);
+    __FLOG(_L8("BulkEndpointsStallL - Exit"));
+    }
+
+/**
+Clears stall conditions all but the control endpoint.
+*/
+void CMTPUsbConnection::BulkEndpointsStallClearL()
+    {
+    __FLOG(_L8("BulkEndpointsStallClearL - Entry"));
+    EndpointStallClearL(EMTPUsbEpBulkIn);
+    EndpointStallClearL(EMTPUsbEpBulkOut);
+    SetDeviceStatus(EMTPUsbDeviceStatusOK);
+    __FLOG(_L8("BulkEndpointsStallClearL - Exit"));  
+    }
+
+/**
+Starts data transfer activity on the data endpoints.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/    
+void CMTPUsbConnection::DataEndpointsStartL()
+    {
+    __FLOG(_L8("DataEndpointsStartL - Entry"));
+    InitiateBulkRequestSequenceL();
+    __FLOG(_L8("DataEndpointsStartL - Exit"));
+    }
+
+/**
+Stops data transfer activity on all but the control endpoint.
+*/    
+void CMTPUsbConnection::DataEndpointsStop()
+    {
+    __FLOG(_L8("DataEndpointsStop - Entry"));
+    if (ConnectionOpen() && (!(SuspendState() & ESuspended))&& (iControllerStatePrevious != EUsbcDeviceStateSuspended))
+        {
+        __FLOG(_L8("Stopping active endpoints"));
+        iEndpoints[EMTPUsbEpBulkIn]->Cancel();
+        iEndpoints[EMTPUsbEpBulkOut]->Cancel();
+        iEndpoints[EMTPUsbEpInterrupt]->Cancel();
+        if ((iBulkTransactionState == EDataIToRPhase) && iUsbBulkContainer->Payload())
+            {
+            __FLOG(_L8("Aborting active I to R data phase"));
+            TRAPD(err, BoundProtocolLayer().ReceiveDataCompleteL(KErrAbort, *iUsbBulkContainer->Payload(), iMTPRequest));
+            UNUSED_VAR(err);
+            }
+        else if ((iBulkTransactionState == EDataRToIPhase) && iUsbBulkContainer->Payload())
+            {
+            __FLOG(_L8("Aborting active R to I data phase"));
+            TRAPD(err, BoundProtocolLayer().SendDataCompleteL(KErrAbort, *iUsbBulkContainer->Payload(), iMTPRequest));
+            UNUSED_VAR(err);
+            }
+        }
+#ifdef __FLOG_ACTIVE
+    else
+        {
+        __FLOG(_L8("Endpoints inactive, do nothing"));
+        }
+#endif // __FLOG_ACTIVE
+    __FLOG(_L8("DataEndpointsStop - Exit"));
+    }
+    
+void CMTPUsbConnection::EndpointStallL(TMTPUsbEndpointId aId)
+    {
+    __FLOG(_L8("EndpointStallL - Entry"));
+    __FLOG_VA((_L8("Creating stall condition on endpoint %d"), aId));
+    __ASSERT_DEBUG((aId < EMTPUsbEpNumEndpoints), Panic(EMTPUsbReserved));
+    
+    // Stall the endpoint.
+    CMTPUsbEpBase& ep(*iEndpoints[aId]);
+    ep.Stall();
+    
+    // Stop the connection.
+    StopConnection();
+    
+    // Update the connection state.
+    if (!(ConnectionState() & EStalled))
+        {
+        SetConnectionState(EStalled);
+        }
+    __FLOG(_L8("EndpointStallL - Exit"));
+    }
+    
+void CMTPUsbConnection::EndpointStallClearL(TMTPUsbEndpointId aId)
+    {
+    __FLOG(_L8("EndpointStallClearL - Entry"));
+    __FLOG_VA((_L8("Clearing stall condition on endpoint %d"), aId));
+    __ASSERT_DEBUG((aId < EMTPUsbEpNumEndpoints), Panic(EMTPUsbReserved));
+    
+    // Check the endoints current stall condition.
+    CMTPUsbEpBase& ep(*iEndpoints[aId]);
+    if ( IsEpStalled( aId ) )
+        {
+        // Clear the stalled endpoint.
+        ep.StallClear();
+        
+        // Update the device status.
+        if ((aId == EMTPUsbEpControl) &&
+            ((iControllerStateCurrent == EUsbcDeviceStateAddress) ||
+                (iControllerStateCurrent == EUsbcDeviceStateConfigured)))
+            {
+            // Control endpoint stall cleared on an active connection.    
+            InitiateControlRequestSequenceL();
+            }
+        else if (!IsEpStalled( aId ) )
+            {
+            // All data endpoint stall conditions are clear.
+          	SetConnectionState(EIdlePhase);
+            }
+        }
+    __FLOG(_L8("EndpointStallClearL - Exit"));
+    }
+       
+/**
+Resumes USB MTP device class processing.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/ 
+void CMTPUsbConnection::ResumeConnectionL()
+    {
+    __FLOG(_L8("ResumeConnectionL - Entry"));
+    if (ConnectionOpen())
+        {    
+        // Restart data transfer activity.
+        ControlEndpointStartL();
+        DataEndpointsStartL();
+        }
+    __FLOG(_L8("ResumeConnectionL - Exit"));
+    }
+       
+/**
+Initiates USB MTP device class processing.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/ 
+void CMTPUsbConnection::StartConnectionL()
+    {
+    __FLOG(_L8("StartConnectionL - Entry"));   
+    
+    // Notify the connection manager and update state, if necessary. 
+    if (ConnectionClosed())
+        {
+        __FLOG(_L8("Notifying protocol layer connection opened"));
+        iConnectionMgr->ConnectionOpenedL(*this);  
+        SetConnectionState(EOpen);
+        InitiateBulkRequestSequenceL();
+        }
+    __FLOG(_L8("StartConnectionL - Exit"));
+    }
+       
+/**
+Halts USB MTP device class processing.
+*/ 
+void CMTPUsbConnection::StopConnection()
+    {
+    __FLOG(_L8("StopConnection - Entry"));
+    
+    // Stop all data transfer activity.
+    DataEndpointsStop();    
+    
+    // Notify the connection manager and update state, if necessary.
+    if (ConnectionOpen())
+        {
+        __FLOG(_L8("Notifying protocol layer connection closed"));
+        iConnectionMgr->ConnectionClosed(*this);
+        SetBulkTransactionState(EUndefined);
+        SetConnectionState(EIdle);
+        SetSuspendState(ENotSuspended);
+        }
+    
+    __FLOG(_L8("StopConnection - Exit"));
+    }
+       
+/**
+Suspends USB MTP device class processing.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/ 
+void CMTPUsbConnection::SuspendConnectionL()
+    {
+    __FLOG(_L8("SuspendConnectionL - Entry"));
+    if (ConnectionOpen())
+        {    
+        // Stop all data transfer activity.
+        DataEndpointsStop();
+        }
+    ControlEndpointStop();
+
+    //  Update state.
+    SetSuspendState(ESuspended);
+    __FLOG(_L8("SuspendConnectionL - Exit"));
+    }
+
+/**
+Configures the USB MTP device class.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::StartUsbL()
+    {
+    __FLOG(_L8("StartUsbL - Exit"));
+    
+    // Open the USB device interface.
+    User::LeaveIfError(iLdd.Open(KDefaultUsbClientController));
+    
+    // Configure the class descriptors.
+    ConfigurationDescriptorSetL();
+    SetInterfaceDescriptorL();
+    
+    __FLOG(_L8("StartUsbL - Exit"));
+    }
+    
+/**
+This method stops the end points transfer.
+*/
+void CMTPUsbConnection::StopUsb()
+    {
+    __FLOG(_L8("StopUsb - Entry"));
+    // Stop monitoring the USB device controller state.
+    iLdd.AlternateDeviceStatusNotifyCancel();
+    
+    // Stop monitoring the USB device controller state.
+    Cancel();
+    
+    // Clear the configuration descriptor.
+    ConfigurationDescriptorClear();
+    
+    // Close the USB device interface.
+    iLdd.ReleaseInterface(KMTPUsbAlternateInterface);
+    iLdd.Close();
+    
+    __FLOG(_L8("StopUsb - Exit"));
+    }
+    
+/**
+Provides the USB bulk container. 
+@return The USB bulk container
+*/
+CMTPUsbContainer& CMTPUsbConnection::BulkContainer()
+	{
+	return *iUsbBulkContainer;
+	}
+	
+/**
+Provides the current state of the USB MTP device class connection.
+@return The current USB MTP device class connection state.
+@see TConnectionState
+*/
+TInt32 CMTPUsbConnection::ConnectionState() const
+    {
+    TInt32 state(iState & EConnectionStateMask);
+    __FLOG_VA((_L8("Connection state = 0x%08X"), state));
+    return (state); 
+    }
+
+/**
+Provides the current USB device suspend state..
+@return The current USB device suspend state.
+@see TSuspendState
+*/
+TInt32 CMTPUsbConnection::SuspendState() const
+    {
+    TInt32 state(iState & ESuspendStateMask);
+    __FLOG_VA((_L8("Suspend state = 0x%08X"), state));
+    
+    return (state);
+    }
+
+/**
+Sets the bulk transfer transaction state.
+@param aState The new connectio state bit flags.
+@see TConnectionState
+*/
+void CMTPUsbConnection::SetBulkTransactionState(TMTPTransactionPhase aState)
+    {
+    __FLOG(_L8("SetBulkTransactionState - Entry"));
+    iBulkTransactionState = aState;
+    __FLOG_VA((_L8("SetBulkTransactionState state set to 0x%08X"), iBulkTransactionState));
+    __FLOG(_L8("SetBulkTransactionState - Exit"));
+    }
+
+/**
+Sets the MTP USB device class device status Code value.
+@param aCode The PIMA 15740 Response Code or Vendor Code value.
+*/
+void CMTPUsbConnection::SetDeviceStatus(TUint16 aCode)
+    {
+    __FLOG(_L8("SetDeviceStatus - Entry"));
+    iDeviceStatusCode = aCode;
+    __FLOG_VA((_L8("Device status set to 0x%04X"), iDeviceStatusCode));
+    __FLOG(_L8("SetDeviceStatus - Exit"));
+    }
+
+/**
+Sets the USB MTP device class interface descriptor.
+@leave KErrCorrupt, if the configuration descriptor size is invalid.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPUsbConnection::SetInterfaceDescriptorL()
+    {
+    __FLOG(_L8("SetInterfaceDescriptorL - Entry"));
+    
+    TUsbcInterfaceInfoBuf ifc;
+    // Get device capabilities.
+    User::LeaveIfError(iLdd.DeviceCaps(iDeviceCaps));
+    
+    // Fetch the endpoint capabilities set.
+    TPtr8 capsPtr(reinterpret_cast<TUint8*>(iEndpointCapSets), sizeof(iEndpointCapSets), sizeof(iEndpointCapSets));
+    User::LeaveIfError(iLdd.EndpointCaps(capsPtr));
+    // Set the interface endpoint properties.
+    for (TUint i(EMTPUsbEpBulkIn); (i < EMTPUsbEpNumEndpoints); i++)
+        {
+        // Fetch the endpoint capabilities and meta data.
+        const TUsbcEndpointCaps&    caps(EndpointCapsL(i));
+        const TEpInfo&              info(iEndpointInfo[i]);
+        
+        // Define the endpoint properties.
+        const TUint idx(EndpointNumber(i) - 1);
+        ifc().iEndpointData[idx].iType      	= info.iType;
+        ifc().iEndpointData[idx].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
+        ifc().iEndpointData[idx].iDir       	= info.iDirection;
+
+		//set endpoint maxpacketsize.
+        if (info.iType == KMTPUsbInterruptEpType)
+            {
+            //As default interface, interrupt endpoint maxpacketsize shall be up to 0x40
+            ifc().iEndpointData[idx].iSize      = KMaxPacketTypeInterrupt;
+            }
+        else
+            {
+            ifc().iEndpointData[idx].iSize      = caps.MaxPacketSize();
+            }
+			
+        ifc().iEndpointData[idx].iInterval  	= info.iInterval;
+        ifc().iEndpointData[idx].iInterval_Hs 	= info.iInterval_Hs;
+        }
+        
+    // Set the required interface descriptor values.
+    ifc().iString               = const_cast<TDesC16*>(&KMTPUsbInterfaceString);
+    ifc().iClass.iClassNum      = KMTPUsbInterfaceClassSIC;
+	ifc().iClass.iSubClassNum   = KMTPUsbInterfaceSubClassSIC;
+	ifc().iClass.iProtocolNum   = KMTPUsbInterfaceProtocolSIC;
+    ifc().iTotalEndpointsUsed   = KMTPUsbRequiredNumEndpoints;
+    
+    // Allocate 512KB buffer for OUT EndPoint, and 64KB for IN EndPoint
+    TUint32 bandwidthPriority = EUsbcBandwidthINPlus2 | EUsbcBandwidthOUTMaximum;
+        
+    // Write the active interface descriptor.
+    User::LeaveIfError(iLdd.SetInterface(KMTPUsbAlternateInterface, ifc, bandwidthPriority));
+        
+    __FLOG(_L8("SetInterfaceDescriptorL - Exit"));
+    }
+
+/**
+Sets the USB MTP device class connection state.
+@param aState The new connection state bit flags.
+@see TConnectionState
+*/
+void CMTPUsbConnection::SetConnectionState(TInt32 aState)
+    {
+    __FLOG(_L8("SetConnectionState - Entry"));
+    iState = ((~EConnectionStateMask & iState) | aState);
+    __FLOG_VA((_L8("Connection state set to 0x%08X"), iState));
+    __FLOG(_L8("SetConnectionState - Exit"));
+    }
+
+/**
+Sets the USB device suspend state.
+@param aState The new suspend state bit flags.
+@see TSuspendState
+*/
+void CMTPUsbConnection::SetSuspendState(TInt32 aState)
+    {
+    __FLOG(_L8("SetSuspendState - Entry"));
+    iState = ((~ESuspendStateMask & iState) | aState);
+    __FLOG_VA((_L8("Connection state set to 0x%08X"), iState));
+    __FLOG(_L8("SetSuspendState - Exit"));
+    }
+    
+/**
+This method is called when EUsbcDeviceStateAddress state is reached. 
+It sets the transport packet size based on the host type the device is
+connected to.
+*/
+void CMTPUsbConnection::SetTransportPacketSizeL()
+	{
+	__FLOG(_L8("SetTransportPacketSizeL - Entry"));
+	if(iLdd.CurrentlyUsingHighSpeed())
+		{
+		__FLOG(_L8("HS USB connection"));
+		iEndpoints[EMTPUsbEpControl]->SetMaxPacketSizeL(KMaxPacketTypeControlHS);
+		iEndpoints[EMTPUsbEpBulkIn]->SetMaxPacketSizeL(KMaxPacketTypeBulkHS);
+		iEndpoints[EMTPUsbEpBulkOut]->SetMaxPacketSizeL(KMaxPacketTypeBulkHS);
+		}
+	else
+		{
+		__FLOG(_L8("FS USB connection"));
+		iEndpoints[EMTPUsbEpControl]->SetMaxPacketSizeL(KMaxPacketTypeControlFS);
+		iEndpoints[EMTPUsbEpBulkIn]->SetMaxPacketSizeL(KMaxPacketTypeBulkFS);
+		iEndpoints[EMTPUsbEpBulkOut]->SetMaxPacketSizeL(KMaxPacketTypeBulkFS);
+		}		
+	iEndpoints[EMTPUsbEpInterrupt]->SetMaxPacketSizeL(KMaxPacketTypeInterrupt);
+	
+	__FLOG(_L8("SetTransportPacketSizeL - Exit"));
+	}
+
+TBool CMTPUsbConnection::IsEpStalled(const TUint& aEpNumber)
+    {
+    const TEndpointNumber number( static_cast<TEndpointNumber>(aEpNumber) );
+    TEndpointState state;
+    iLdd.EndpointStatus(number, state);
+    return ( EEndpointStateStalled == state );
+    }