mtptransports/mtpusbtransport/usbsic_imp/src/cmtpusbepbase.cpp
branchRCL_3
changeset 24 523717cdb0ad
parent 0 d0791faffa3f
child 32 f85613f12947
equal deleted inserted replaced
23:f5809cfbf6d5 24:523717cdb0ad
    71     iId(aId),
    71     iId(aId),
    72     iReceiveChunkData(NULL, 0),
    72     iReceiveChunkData(NULL, 0),
    73     iReceiveData(NULL, 0),
    73     iReceiveData(NULL, 0),
    74     iSendChunkData(NULL, 0),
    74     iSendChunkData(NULL, 0),
    75     iSendData(NULL, 0),
    75     iSendData(NULL, 0),
    76     iIsFirstChunk(EFalse), 
    76     iIsFirstChunk(EFalse),
    77     iConnection(aConnection)
    77     iConnection(aConnection)
    78     {
    78     {
    79     CActiveScheduler::Add(this);
    79     CActiveScheduler::Add(this);
    80     }
    80     }
    81     
    81     
   252     if(iState != EIdle)
   252     if(iState != EIdle)
   253       {
   253       {
   254     	Cancel();
   254     	Cancel();
   255       }
   255       }
   256     
   256     
   257 
       
   258     __ASSERT_DEBUG(iState == EIdle, Panic(EMTPUsbBadState));
   257     __ASSERT_DEBUG(iState == EIdle, Panic(EMTPUsbBadState));
   259     
   258     
   260     iReceiveDataSink    = &aSink;
   259     iReceiveDataSink    = &aSink;
   261     iReceiveDataCommit  = iReceiveDataSink->CommitRequired();
   260     iReceiveDataCommit  = iReceiveDataSink->CommitRequired();
   262     SetStreamState(EReceiveInitialising);
   261     SetStreamState(EReceiveInitialising);
   526 	
   525 	
   527 	TBool result(EFalse);
   526 	TBool result(EFalse);
   528 	TUint16 containerType(Connection().BulkContainer().Uint16L(CMTPUsbContainer::EContainerType));
   527 	TUint16 containerType(Connection().BulkContainer().Uint16L(CMTPUsbContainer::EContainerType));
   529 	iDataLength = Connection().BulkContainer().Uint32L(CMTPUsbContainer::EContainerLength);
   528 	iDataLength = Connection().BulkContainer().Uint32L(CMTPUsbContainer::EContainerLength);
   530 	
   529 	
       
   530 #ifdef __FLOG_ACTIVE
       
   531     TUint32 transactionId(Connection().BulkContainer().Uint32L(CMTPUsbContainer::ETransactionID));
       
   532 	TUint16 code(Connection().BulkContainer().Uint16L(CMTPUsbContainer::ECode));
       
   533     __FLOG_VA((_L8("ContainerLength = %lu, containerType = 0x%x, code = 0x%x, transactionID = 0x%x"), iDataLength, containerType, code, transactionId));
       
   534 #endif
       
   535 	
   531 	//Due to an issue of Windows OS, the value of CMTPUsbContainer::EContainerLength is incorrect if the
   536 	//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
   537 	//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.
   538 	//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.
   539 	//Here we reset the iDateLength to the actual size of iReceiveDataSink as a walkaround.
   535 	if(containerType == 2 && (iDataLength <= 11 || iDataLength == KMaxTUint32))
   540 	if(containerType == 2 && (iDataLength <= 11 || iDataLength == KMaxTUint32))
   538 		iDataLength = iReceiveDataSink->Size();
   543 		iDataLength = iReceiveDataSink->Size();
   539 		}
   544 		}
   540 	
   545 	
   541 	__FLOG_VA((_L8("containerType = %u , dataLength = %lu bytes"), containerType, iDataLength));
   546 	__FLOG_VA((_L8("containerType = %u , dataLength = %lu bytes"), containerType, iDataLength));
   542 	
   547 	
   543 	if (iDataLength >= KUSBHeaderSize && 
   548     if (iDataLength >= KUSBHeaderSize && 
   544 		(containerType == EMTPUsbContainerTypeCommandBlock || containerType == EMTPUsbContainerTypeDataBlock))
   549         (containerType == EMTPUsbContainerTypeCommandBlock || containerType == EMTPUsbContainerTypeDataBlock))
   545 		{
   550         {	
   546 		result = ETrue;
   551         result = ETrue;
   547 		iDataCounter = 0;
   552         iDataCounter = 0;
   548 #ifdef _DEBUG
   553         }
   549  		RDebug::Print(_L("Find the valid usb header------------------------------------------------------\n"));
   554 	
   550  		TUint16 code(Connection().BulkContainer().Uint16L(CMTPUsbContainer::ECode));
   555 	__FLOG_VA((_L8("CMTPUsbEpBase::ValidateUSBHeader - Exit with the result of %d"), result));
   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;
   556 	return result;
   561 	}
   557 	}
   562 
   558 
   563 /**
   559 /**
   564 Initiates the first chunk received data.
   560 Initiates the first chunk received data.
   598 	    {
   594 	    {
   599 	    // USB header received from BulkOut EP.
   595 	    // USB header received from BulkOut EP.
   600 	    // USB Header validation
   596 	    // USB Header validation
   601 	    if (!ValidateUSBHeaderL())
   597 	    if (!ValidateUSBHeaderL())
   602 		    {
   598 		    {
   603 			// If device has received trash data, flush the rest of the packet and try again.
   599             //trash data, continue to flush.
   604   	  	 	// This will occur when cancelling a transfer and the PC sends buffered data after 
   600             TRequestStatus status;
   605   	  	 	// the cancellation.
   601             RBuf8 readBuf;
   606 		    TRequestStatus status;
   602             readBuf.CreateL(KMaxPacketTypeBulkHS);
   607   	  		do
   603             Connection().Ldd().ReadPacket(status, EndpointNumber(), readBuf, KMaxPacketTypeBulkHS);
   608 				{
   604             User::WaitForRequest(status);    
   609 				// Keep looking for headers.
   605             RDebug::Print(_L("CMTPUsbEpBase::ProcessFirstReceivedChunkL(), trash data length = %d"), readBuf.Length());
   610 				// The case we are trying to catch is when we have 12 garbage bytes followed by 12 good bytes.
   606             readBuf.Close();
   611 				// In this case the ReadOneOrMore is acting on the next packet rather than the current packet.
   607             
   612 				// If the garbage data is a multiple of 12 bytes, we should still be able to catch the next good
   608             InitiateFirstChunkReceiveL();  
   613 				// header. Otherwise the ReadOneOrMore will return will <12 bytes and we will fall through
   609             return;
   614 				// to the retry code below. 
   610             
   615 				iReceiveData.Zero();
   611 
   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 			}
   612 			}
   626 			
   613 			
   627 		if ((iDataLength - KUSBHeaderSize) == 0)
   614 		if ((iDataLength - KUSBHeaderSize) == 0)
   628 			{
   615 			{
   629 			// only USB header.
   616 			// only USB header.
  1032 // if there is no data read in flushRxData, wait for 1.5 second at most in case forever waiting
  1019 // 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 
  1020 #define INTERVAL_FOR_FLUSH_TRASH_DATA_IF_NO_DATA_READ  (30*INTERVAL_FOR_READ_TRASH_DATA) //1.5 SECOND 
  1034 
  1021 
  1035 void CMTPUsbEpBase::FlushRxDataL()
  1022 void CMTPUsbEpBase::FlushRxDataL()
  1036     {
  1023     {
  1037     				  
  1024     __FLOG(_L8("FlushRxDataL - Entry"));    				  
  1038     // create the read buff
  1025     // create the read buff
  1039     RBuf8 readBuf;
  1026     RBuf8 readBuf;
  1040     readBuf.CreateL(KFlushBufferMaxLen);
  1027     readBuf.CreateL(KFlushBufferMaxLen);
  1041 		      
  1028 		      
  1042     TUint32 uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA_IF_NO_DATA_READ;
  1029     TUint32 uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA_IF_NO_DATA_READ;
  1044     do{
  1031     do{
  1045  			    	
  1032  			    	
  1046       // get the data size in the receive buffer ready to read
  1033       // get the data size in the receive buffer ready to read
  1047       TInt nbytes = 0;
  1034       TInt nbytes = 0;
  1048       TInt err = Connection().Ldd().QueryReceiveBuffer(EndpointNumber(), nbytes);
  1035       TInt err = Connection().Ldd().QueryReceiveBuffer(EndpointNumber(), nbytes);
  1049 #ifdef _DEBUG
  1036 
  1050       RDebug::Print(_L("FlushRxDataL()--1---err is %d , nbytes is %d"), err, nbytes);	  
  1037       __FLOG_VA((_L8("FlushRxDataL()--1---err is %d , nbytes is %d"), err, nbytes));	  
  1051 #endif
       
  1052  					  
  1038  					  
  1053       // has data, read it
  1039       // has data, read it
  1054       if( (err == KErrNone) && (nbytes > 0) )
  1040       if( (err == KErrNone) && (nbytes > 0) )
  1055          {
  1041          {   
  1056    
       
  1057          // synchronously read the data
  1042          // synchronously read the data
  1058          TRequestStatus status;
  1043          TRequestStatus status;
  1059          Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf);
  1044          Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf);
  1060          User::WaitForRequest(status);
  1045          User::WaitForRequest(status);
  1061 	 		 
  1046 	 		 
  1062          if(status.Int() != KErrNone)  break;
  1047          if(status.Int() != KErrNone)  break;
  1063          			               
  1048 
  1064          // whenever some data read, reset the rest wait time .
  1049 #ifdef __FLOG_ACTIVE
       
  1050          TInt length =  readBuf.Length();
       
  1051          __FLOG_VA((_L8("The length of trash data is %d"), length));
       
  1052          
       
  1053          __FLOG(_L8("Begining of trash data"));       
       
  1054          for (int i=0; i<4&&(i*4+4)<=length; i++)
       
  1055              {
       
  1056              __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]));            
       
  1057              }
       
  1058          
       
  1059          __FLOG(_L8("Residual of trash data if any"));          
       
  1060          TInt residualLength = length%512;
       
  1061          for (int i=0; i<4&&(i*4+4)<=residualLength; i++)
       
  1062              {
       
  1063              TInt beginIndex = length - residualLength;
       
  1064              __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]));            
       
  1065              }
       
  1066 #endif
       
  1067          
       
  1068          // whenever some data read, reset the rest wait time.
  1065          uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA;
  1069          uRestTimeToWait = INTERVAL_FOR_FLUSH_TRASH_DATA;
  1066  			               
  1070  			                          
  1067 #ifdef _DEBUG 			               
  1071          __FLOG(_L8("FlushRxDataL()---Reset the rest wait time"));	          
  1068          RDebug::Print(_L("FlushRxDataL()---Reset the rest wait time"));	  
       
  1069 #endif             
       
  1070          }
  1072          }
  1071        else 
  1073        else 
  1072          {	
  1074          {	
  1073          // wait for the data from the usb channel.
  1075          // wait for the data from the usb channel.
  1074          User::After(INTERVAL_FOR_READ_TRASH_DATA);
  1076          User::After(INTERVAL_FOR_READ_TRASH_DATA);
  1075          // reduce the rest time to wait 
  1077          // reduce the rest time to wait 
  1076          uRestTimeToWait -=  INTERVAL_FOR_READ_TRASH_DATA ;
  1078          uRestTimeToWait -=  INTERVAL_FOR_READ_TRASH_DATA ;
  1077          }	
  1079          }	
  1078  	  
  1080  	    
  1079 #ifdef _DEBUG 	  
  1081       __FLOG_VA((_L8("FlushRxDataL()---uRestTimeToWait is %d"), uRestTimeToWait));
  1080        RDebug::Print(_L("FlushRxDataL()---uRestTimeToWait is %d"), uRestTimeToWait);	  
       
  1081 #endif
       
  1082  			    	
  1082  			    	
  1083     }while( uRestTimeToWait > 0);
  1083     }while( uRestTimeToWait > 0);
  1084 			    	
  1084 			    	
  1085     readBuf.Close();
  1085     readBuf.Close();
  1086  
  1086     __FLOG(_L8("FlushRxDataL - Exit"));    
  1087 }
  1087 }