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 |
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 } |