mik3y/usb-serial-for-android — pull request #74 by dengn (2014-08-08 09:03:13+00:00)
Title: Fix the problem of losing data with ”filterStatusBytes“

Hey, I've worked for quite a time with this library. I've found a bug with the "filterStatusBytes" function.
/**
* Filter FTDI status bytes from buffer
* @param src The source buffer (which contains status bytes)
* @param dest The destination buffer to write the status bytes into (can be src)
* @param totalBytesRead Number of bytes read to src
* @param maxPacketSize The USB endpoint max packet size
* @return The number of payload bytes
*/
private final int filterStatusBytes(byte[] src, byte[] dest, int totalBytesRead,
int maxPacketSize) {
final int packetsCount = totalBytesRead / maxPacketSize + 1;
for (int packetIdx = 0; packetIdx < packetsCount; ++packetIdx) {
final int count = (packetIdx == (packetsCount - 1))
? (totalBytesRead % maxPacketSize) - MODEM_STATUS_HEADER_LENGTH
: maxPacketSize - MODEM_STATUS_HEADER_LENGTH;
if (count > 0) {
System.arraycopy(src,
packetIdx * maxPacketSize + MODEM_STATUS_HEADER_LENGTH,
dest,
packetIdx * (maxPacketSize - MODEM_STATUS_HEADER_LENGTH),
count);
}
}

if (totalBytesRead % maxPacketSize == 0) {
System.arraycopy(src,
totalBytesRead - 2,
dest,
totalBytesRead - (packetsCount * 2),
2);
return totalBytesRead - (packetsCount * 2) + 2;
}
else {
return totalBytesRead - (packetsCount * 2);
}

}
As you can see, commonly when “totalBytesRead” is read as a integral multiple of maxPacketSize(which is 64), each packet that we receive at end will lose the last 2 bytes. For that reason, I've modified a little bit your calculation.

Regards,
Nan