594 { |
594 { |
595 // USB header received from BulkOut EP. |
595 // USB header received from BulkOut EP. |
596 // USB Header validation |
596 // USB Header validation |
597 if (!ValidateUSBHeaderL()) |
597 if (!ValidateUSBHeaderL()) |
598 { |
598 { |
599 //trash data, continue to flush. |
599 //trash data, continue to flush by one packet. |
600 TRequestStatus status; |
600 FlushOnePacketL(); |
601 RBuf8 readBuf; |
|
602 readBuf.CreateL(KMaxPacketTypeBulkHS); |
|
603 Connection().Ldd().ReadPacket(status, EndpointNumber(), readBuf, KMaxPacketTypeBulkHS); |
|
604 User::WaitForRequest(status); |
|
605 RDebug::Print(_L("CMTPUsbEpBase::ProcessFirstReceivedChunkL(), trash data length = %d"), readBuf.Length()); |
|
606 readBuf.Close(); |
|
607 |
601 |
608 InitiateFirstChunkReceiveL(); |
602 InitiateFirstChunkReceiveL(); |
609 return; |
603 return; |
610 |
|
611 |
|
612 } |
604 } |
613 |
605 |
614 if ((iDataLength - KUSBHeaderSize) == 0) |
606 if ((iDataLength - KUSBHeaderSize) == 0) |
615 { |
607 { |
616 // only USB header. |
608 // only USB header. |
617 SetStreamState(EReceiveComplete); |
609 SetStreamState(EReceiveComplete); |
618 } |
610 } |
619 } |
611 } |
620 else if (iReceiveChunkData.MaxLength() == iReceiveChunkData.Length()) |
612 else if (iReceiveChunkData.MaxLength() == KUSBHeaderSize |
|
613 && iReceiveChunkData.Length() < KUSBHeaderSize) |
|
614 { |
|
615 //trash data received, just diacard it and initiate next receiving |
|
616 InitiateFirstChunkReceiveL(); |
|
617 return; |
|
618 } |
|
619 else if (iReceiveChunkData.MaxLength() == iReceiveChunkData.Length()) |
621 { |
620 { |
622 // USB Control request setup or data packet is received from Control EP. |
621 // USB Control request setup or data packet is received from Control EP. |
623 // All the desired data should be received. |
622 // All the desired data should be received. |
624 SetStreamState(EReceiveComplete); |
623 SetStreamState(EReceiveComplete); |
625 } |
624 } |
690 { |
689 { |
691 // Two cases are covered here: |
690 // Two cases are covered here: |
692 // 1. MTP file receiving: MTP type file never returns KMTPChunkSequenceCompletion,It can be received |
691 // 1. MTP file receiving: MTP type file never returns KMTPChunkSequenceCompletion,It can be received |
693 // one part after another. Also it can be commited mutiple times. |
692 // one part after another. Also it can be commited mutiple times. |
694 // 2. Other MTP datatype receiving during the middle of data stream |
693 // 2. Other MTP datatype receiving during the middle of data stream |
695 __FLOG(_L8("Commiting write data chunk")); |
694 __FLOG(_L8("Commiting write data chunk - 1")); |
696 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
695 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
697 lastChunkCommited = ETrue; |
696 lastChunkCommited = ETrue; |
698 } |
697 } |
699 else if ((iChunkStatus != KMTPChunkSequenceCompletion) |
698 else if ((iChunkStatus != KMTPChunkSequenceCompletion) |
700 && endStream |
699 && endStream |
701 && !nullPacketReceived) |
700 && !nullPacketReceived) |
702 { |
701 { |
703 // It should be the end of MTP type file receiving since it never returns KMTPChunkSequenceCompletion. |
702 // It should be the end of MTP type file receiving since it never returns KMTPChunkSequenceCompletion. |
704 // it can be commited mutiple times. |
703 // it can be commited mutiple times. |
705 __FLOG(_L8("Commiting write data chunk")); |
704 __FLOG(_L8("Commiting write data chunk - 2")); |
706 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
705 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
707 } |
706 } |
708 else if ((iChunkStatus == KMTPChunkSequenceCompletion) |
707 else if ((iChunkStatus == KMTPChunkSequenceCompletion) |
709 && endStream |
708 && endStream |
710 && !nullPacketReceived) |
709 && !nullPacketReceived) |
711 { |
710 { |
712 // The last chunk data which type is any other MTP data type than MTP file type. |
711 // The last chunk data which type is any other MTP data type than MTP file type. |
713 // It will not be commited until all the chunk data is received. |
712 // It will not be commited until all the chunk data is received. |
714 __FLOG(_L8("Commiting write data chunk")); |
713 __FLOG(_L8("Commiting write data chunk - 3")); |
715 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
714 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
716 } |
715 } |
|
716 else if ((iChunkStatus == KMTPChunkSequenceCompletion) |
|
717 && !endStream |
|
718 && (iReceiveChunkData.Length() == iReceiveChunkData.MaxLength())) |
|
719 { |
|
720 // The last chunk data is received and chunk has been filled up: |
|
721 // just flush one packet and set endStream true and commit received data. |
|
722 // This condition tries to make MTP more robust if DP forgets to handle data-out phase. |
|
723 __FLOG(_L8("Commiting write data chunk - 4")); |
|
724 |
|
725 FlushOnePacketL(); |
|
726 endStream = ETrue; |
|
727 needCommit = iReceiveDataSink->CommitChunkL(iReceiveChunkData); |
|
728 } |
717 } |
729 } |
718 |
730 |
719 // Fetch the next read data chunk. |
731 // Fetch the next read data chunk. |
720 switch (iState) |
732 switch (iState) |
721 { |
733 { |
1108 Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf); |
1120 Connection().Ldd().ReadOneOrMore(status, EndpointNumber(), readBuf); |
1109 User::WaitForRequest(status); |
1121 User::WaitForRequest(status); |
1110 readBuf.Close(); |
1122 readBuf.Close(); |
1111 } |
1123 } |
1112 } |
1124 } |
|
1125 |
|
1126 void CMTPUsbEpBase::FlushOnePacketL() |
|
1127 { |
|
1128 //trash data, continue to flush. |
|
1129 TRequestStatus status; |
|
1130 RBuf8 readBuf; |
|
1131 readBuf.CreateL(KMaxPacketTypeBulkHS); |
|
1132 Connection().Ldd().ReadPacket(status, EndpointNumber(), readBuf, KMaxPacketTypeBulkHS); |
|
1133 User::WaitForRequest(status); |
|
1134 RDebug::Print(_L("CMTPUsbEpBase::ProcessFirstReceivedChunkL(), trash data length = %d"), readBuf.Length()); |
|
1135 readBuf.Close(); |
|
1136 } |