Packets that are exactly a multiple of the EP size fail

Chris Chaffey <[email protected]> Thu, 30 Oct 2014 19:59:43 +0000
Newsgroups gmane.comp.lib.libusb.devel.windows
Message-ID <FC59388187B4C84FAD5CDEB19ADA8E5BB20AD2@ord2mbx10c.mex05.mlsrvr.com>
Hi All,

I'm using LibUsb-Win32 version 1.2.6 to communicate with a device that I am trying to reverse engineer.  When the device sends data to me that is not equal to a multiple of the endpoints wMaxPacketSize, I never receive that packet.  I have used a program called freeusbanalyzer that has given me the following output (with some annotations on my part):

<-------------- In the middle of streaming download from device
00000348            30.10.2014 16:24:47.289               +0.094   UP          0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Streaming data
00000350            30.10.2014 16:24:47.392               +0.100   DOWN  0x00000000               URB_FUNCTION_ABORT_PIPE
00000351            30.10.2014 16:24:47.392               +0.0       UP          0xc0010000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Zero byte
00000352            30.10.2014 16:24:47.392               +0.0       UP          0x00000000               URB_FUNCTION_ABORT_PIPE
00000354            30.10.2014 16:24:47.488               +0.094   UP          0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Streaming data
00000356            30.10.2014 16:24:47.591               +0.100   DOWN  0x00000000               URB_FUNCTION_ABORT_PIPE
00000357            30.10.2014 16:24:47.591               +0.0       UP          0xc0010000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Zero byte
00000358            30.10.2014 16:24:47.591               +0.0       UP          0x00000000               URB_FUNCTION_ABORT_PIPE
00000360            30.10.2014 16:24:47.688               +0.095   UP          0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Streaming data
00000362            30.10.2014 16:24:47.791               +0.100   DOWN  0x00000000               URB_FUNCTION_ABORT_PIPE
00000363            30.10.2014 16:24:47.791               +0.0       UP          0xc0010000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Zero byte
00000364            30.10.2014 16:24:47.791               +0.0       UP          0x00000000               URB_FUNCTION_ABORT_PIPE
00000366            30.10.2014 16:24:47.894               +0.100   DOWN  0x00000000               URB_FUNCTION_ABORT_PIPE
00000367            30.10.2014 16:24:47.894               +0.0       UP          0xc0010000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Zero byte
00000368            30.10.2014 16:24:47.894               +0.0       UP          0x00000000               URB_FUNCTION_ABORT_PIPE
00000370            30.10.2014 16:24:47.899               +0.002   DOWN  0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000371            30.10.2014 16:24:47.899               +0.0       UP          0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000372            30.10.2014 16:24:47.900               +0.0       DOWN  0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000373            30.10.2014 16:24:47.900               +0.0       UP          0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000374            30.10.2014 16:24:47.901               +0.0       DOWN  0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000375            30.10.2014 16:24:47.901               +0.0       UP          0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000376            30.10.2014 16:24:47.902               +0.0       DOWN  0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000377            30.10.2014 16:24:47.902               +0.0       UP          0x00000000               URB_FUNCTION_CONTROL_TRANSFER
00000378            30.10.2014 16:24:47.997               +0.094   DOWN  0x00000000               URB_FUNCTION_ABORT_PIPE
00000379            30.10.2014 16:24:47.997               +0.0       UP          0xc0010000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Streaming data; never receive this "chunk"
00000380            30.10.2014 16:24:47.997               +0.0       UP          0x00000000               URB_FUNCTION_ABORT_PIPE
00000382            30.10.2014 16:24:48.099               +0.100   DOWN  0x00000000               URB_FUNCTION_ABORT_PIPE
00000383            30.10.2014 16:24:48.099               +0.0       UP          0xc0010000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Zero byte
00000384            30.10.2014 16:24:48.099               +0.0       UP          0x00000000               URB_FUNCTION_ABORT_PIPE
00000386            30.10.2014 16:24:48.193               +0.091   UP          0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Next block of streaming data.  Fails because previous chunk was not received.
00000388            30.10.2014 16:24:48.197               +0.002   DOWN  0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Stop stream message
00000390            30.10.2014 16:24:48.292               +0.095   UP          0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Stop stream ACK
00000392            30.10.2014 16:24:48.300               +0.005   DOWN  0x00000000               URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER  <-- Restart at failed chunk

The problem pops up at 30.10.2014 16:24:47.997.  This chunk is exactly 64 bytes in length.  It doesn't matter how many times I request that chunk it will always fail.  This happens in other parts of the stream as well, and it only seems to be when the chunk is a multiple of 64 bytes in length.  The only other difference I see between that chunk and all the other chunks that do go through is that it always has a status of USBD_STATUS_CANCELED (0xc0010000).

My code is fairly straight-forward and it is executed in a thread:

        int size = maxInSize * 4;
        uint8_t buf[size];
        int len = 0;
        int r = libusb_bulk_transfer(handle, epIn, buf, size, &len, MAX_RECV_TIMEOUT);
        if ((r != LIBUSB_ERROR_TIMEOUT) && (r != LIBUSB_SUCCESS))
        {
                // This method will timeout every MAX_RECV_TIMEOUT milliseconds when no data is available.  No need to log this condition.
                LogLibUsbReturn(r, "libusb_bulk_transfer");
        }
        if ((r == LIBUSB_SUCCESS) && (len > 0))
        {
                std::lock_guard<std::recursive_mutex> lock(readMutex);
               inData.append((char*)buf, len);
        }

Thanks for your time,

Chris

------------------------------------------------------------------------------

_______________________________________________
Libusb-win32-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libusb-win32-devel