python-libusb1
python-libusb1 copied to clipboard
Do the bulk transfer APIs handle fragmentation?
I cannot find a direct answer or documentation on this issue but When doing USB bulk transfers (see this link) bulk transfers the buffer to be read or written is usually done in 64 byte chunks. It is very rare that USB devices support larger transfer sizes. When working with libusb in C (some time ago - 2008) I had to handle this 64-byte fragmentation at the application level, including the 0-byte end indicator when the data buffer happened to be an even multiple of 64.
It appears the the bulk transfers provided by usb1 DO handle the fragmentation but that does not follow libusb as I remember it....unless libusb has now handled that fragmentation,
The USB device I am working with has a max bulk transfer size of 64 bytes according to the endpoint descriptors. Do I need to handle that fragmentation at the application level?
You should not have to handle fragmentation at the application level. Checking the Linux kernel source, I am seeing the HCD drivers check the endpoint's max packet size (with the usb_maxpacket
function) when submitting an URB to the hardware.
For zero-length packets, there is a section on the libusb caveat documentation page about them: on Linux you can set a flag so they get automatically emitted after a transfer of a multiple of the endpoint's max packet size, but this is not portable. My understanding is that ZLP are usually not necessary from the host side, because the device can tell the difference between the data stage and the status stage of a transaction: the data token direction gets reversed. The host has full control on this token. Where this is more important is on the device side, so as to tell the host that it may progress to the status stage during IN transactions.
Of course, this all relies on the device being honest in its descriptors...
Thanks for that info. At low levels a packet size of 0 and one that is less than the bulk size (usually 64) indicates that no more data is to come. Usually higher level APIs hide this. At the Python level, I will not be sending 0 length packets since all that is handled down in the bowels of USB.
I do remember back in the past that I did have to do that low level handling with libusb (in C); at least with the windows version of it.
Seeing there was no follow-up questions or issues, I mark this ticket as resolved.