mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbepbase.cpp
changeset 29 3ae5cb0b4c02
parent 0 d0791faffa3f
child 31 a26669f87b46
--- a/mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbepbase.cpp	Mon May 03 13:19:02 2010 +0300
+++ b/mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbepbase.cpp	Fri Jun 25 16:54:01 2010 +0800
@@ -73,7 +73,7 @@
     iReceiveData(NULL, 0),
     iSendChunkData(NULL, 0),
     iSendData(NULL, 0),
-    iIsFirstChunk(EFalse), 
+    iIsFirstChunk(EFalse),
     iConnection(aConnection)
     {
     CActiveScheduler::Add(this);
@@ -254,7 +254,6 @@
     	Cancel();
       }
     
-
     __ASSERT_DEBUG(iState == EIdle, Panic(EMTPUsbBadState));
     
     iReceiveDataSink    = &aSink;
@@ -528,6 +527,12 @@
 	TUint16 containerType(Connection().BulkContainer().Uint16L(CMTPUsbContainer::EContainerType));
 	iDataLength = Connection().BulkContainer().Uint32L(CMTPUsbContainer::EContainerLength);
 	
+#ifdef __FLOG_ACTIVE
+    TUint32 transactionId(Connection().BulkContainer().Uint32L(CMTPUsbContainer::ETransactionID));
+	TUint16 code(Connection().BulkContainer().Uint16L(CMTPUsbContainer::ECode));
+    __FLOG_VA((_L8("ContainerLength = %lu, containerType = 0x%x, code = 0x%x, transactionID = 0x%x"), iDataLength, containerType, code, transactionId));
+#endif
+	
 	//Due to an issue of Windows OS, the value of CMTPUsbContainer::EContainerLength is incorrect if the
 	//object >= 4G-12. The value should be KMaxTUint32 in this kind of cases, but in current Windows
 	//implementation it will be a value between 0 and 11.
@@ -540,23 +545,14 @@
 	
 	__FLOG_VA((_L8("containerType = %u , dataLength = %lu bytes"), containerType, iDataLength));
 	
-	if (iDataLength >= KUSBHeaderSize && 
-		(containerType == EMTPUsbContainerTypeCommandBlock || containerType == EMTPUsbContainerTypeDataBlock))
-		{
-		result = ETrue;
-		iDataCounter = 0;
-#ifdef _DEBUG
- 		RDebug::Print(_L("Find the valid usb header------------------------------------------------------\n"));
- 		TUint16 code(Connection().BulkContainer().Uint16L(CMTPUsbContainer::ECode));
- 		TUint32 transactionID(Connection().BulkContainer().Uint32L(CMTPUsbContainer::ETransactionID));
- 		RDebug::Print(_L("ContainerLength = 0x%x, containerType = 0x%x , code = 0x%x , transactionID = 0x%x "),  iDataLength, containerType, code, transactionID);
- 		}
- 	else
- 		{
- 		RDebug::Print(_L("inValid usb Header read..........................................................."));
-#endif
- 		}
-	__FLOG(_L8("CMTPUsbEpBase::ValidateUSBHeader - Exit"));
+    if (iDataLength >= KUSBHeaderSize && 
+        (containerType == EMTPUsbContainerTypeCommandBlock || containerType == EMTPUsbContainerTypeDataBlock))
+        {	
+        result = ETrue;
+        iDataCounter = 0;
+        }
+	
+	__FLOG_VA((_L8("CMTPUsbEpBase::ValidateUSBHeader - Exit with the result of %d"), result));
 	return result;
 	}
 
@@ -600,28 +596,19 @@
 	    // USB Header validation
 	    if (!ValidateUSBHeaderL())
 		    {
-			// If device has received trash data, flush the rest of the packet and try again.
-  	  	 	// This will occur when cancelling a transfer and the PC sends buffered data after 
-  	  	 	// the cancellation.
-		    TRequestStatus status;
-  	  		do
-				{
-				// Keep looking for headers.
-				// The case we are trying to catch is when we have 12 garbage bytes followed by 12 good bytes.
-				// In this case the ReadOneOrMore is acting on the next packet rather than the current packet.
-				// If the garbage data is a multiple of 12 bytes, we should still be able to catch the next good
-				// header. Otherwise the ReadOneOrMore will return will <12 bytes and we will fall through
-				// to the retry code below. 
-				iReceiveData.Zero();
-				Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), iReceiveData, KUSBHeaderSize);
-				User::WaitForRequest(status);
-				} while (iReceiveData.Length()==KUSBHeaderSize && !ValidateUSBHeaderL());
+            //trash data, continue to flush.
+            TRequestStatus status;
+            RBuf8 readBuf;
+            readBuf.CreateL(KMaxPacketTypeBulkHS);
+            Connection().Ldd().ReadPacket(status, EndpointNumber(), readBuf, KMaxPacketTypeBulkHS);
+            User::WaitForRequest(status);    
+            RDebug::Print(_L("CMTPUsbEpBase::ProcessFirstReceivedChunkL(), trash data length = %d"), readBuf.Length());
+            readBuf.Close();
+            
+            InitiateFirstChunkReceiveL();  
+            return;
+            
 
-			if(!ValidateUSBHeaderL())
-				{ 
-				InitiateFirstChunkReceiveL();  
-				return;
-				}
 			}
 			
 		if ((iDataLength - KUSBHeaderSize) == 0)
@@ -1034,7 +1021,7 @@
 
 void CMTPUsbEpBase::FlushRxDataL()
     {
-    				  
+    __FLOG(_L8("FlushRxDataL - Entry"));    				  
     // create the read buff
     RBuf8 readBuf;
     readBuf.CreateL(KFlushBufferMaxLen);
@@ -1046,27 +1033,42 @@
       // get the data size in the receive buffer ready to read
       TInt nbytes = 0;
       TInt err = Connection().Ldd().QueryReceiveBuffer(EndpointNumber(), nbytes);
-#ifdef _DEBUG
-      RDebug::Print(_L("FlushRxDataL()--1---err is %d , nbytes is %d"), err, nbytes);	  
-#endif
+
+      __FLOG_VA((_L8("FlushRxDataL()--1---err is %d , nbytes is %d"), err, nbytes));	  
  					  
       // has data, read it
       if( (err == KErrNone) && (nbytes > 0) )
-         {
-   
+         {   
          // synchronously read the data
          TRequestStatus status;
          Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf);
          User::WaitForRequest(status);
 	 		 
          if(status.Int() != KErrNone)  break;
-         			               
-         // whenever some data read, reset the rest wait time .
+
+#ifdef __FLOG_ACTIVE
+         TInt length =  readBuf.Length();
+         __FLOG_VA((_L8("The length of trash data is %d"), length));
+         
+         __FLOG(_L8("Begining of trash data"));       
+         for (int i=0; i<4&&(i*4+4)<=length; i++)
+             {
+             __FLOG_VA((_L8("0x%x 0x%x 0x%x 0x%x"), readBuf[i*4], readBuf[i*4+1], readBuf[i*4+2], readBuf[i*4+3]));            
+             }
+         
+         __FLOG(_L8("Residual of trash data if any"));          
+         TInt residualLength = length%512;
+         for (int i=0; i<4&&(i*4+4)<=residualLength; i++)
+             {
+             TInt beginIndex = length - residualLength;
+             __FLOG_VA((_L8("0x%x 0x%x 0x%x 0x%x"), readBuf[beginIndex + i*4], readBuf[beginIndex + i*4+1], readBuf[beginIndex + i*4+2], readBuf[beginIndex + i*4+3]));            
+             }
+#endif
+         
+         // whenever some data read, reset the rest wait time.
          uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA;
- 			               
-#ifdef _DEBUG 			               
-         RDebug::Print(_L("FlushRxDataL()---Reset the rest wait time"));	  
-#endif             
+ 			                          
+         __FLOG(_L8("FlushRxDataL()---Reset the rest wait time"));	          
          }
        else 
          {	
@@ -1075,13 +1077,36 @@
          // reduce the rest time to wait 
          uRestTimeToWait -=  INTERVAL_FOR_READ_TRASH_DATA ;
          }	
- 	  
-#ifdef _DEBUG 	  
-       RDebug::Print(_L("FlushRxDataL()---uRestTimeToWait is %d"), uRestTimeToWait);	  
-#endif
+ 	    
+      __FLOG_VA((_L8("FlushRxDataL()---uRestTimeToWait is %d"), uRestTimeToWait));
  			    	
     }while( uRestTimeToWait > 0);
 			    	
     readBuf.Close();
- 
+    __FLOG(_L8("FlushRxDataL - Exit"));    
 }
+
+/*
+ * The difference with FlushRxDataL() is FlushBufferedRxDataL only flush current buffered trash data
+ * if currently no data is buffered in usb driver, just return rather than wait some time like what 
+ * FlushRxDataL() does
+ */
+void CMTPUsbEpBase::FlushBufferedRxDataL()
+    {
+    //flush buffered rx data
+    TInt  nbytes = 0;
+    TInt err = Connection().Ldd().QueryReceiveBuffer(EndpointNumber(), nbytes);
+
+    // has data, read it
+    if( (err == KErrNone) && (nbytes > 0) )
+        {
+        // create the read buff
+        RBuf8 readBuf;
+        readBuf.CreateL(nbytes);
+        // synchronously read the data
+        TRequestStatus status;
+        Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf);
+        User::WaitForRequest(status);
+        readBuf.Close(); 
+        }
+    }