usb1: Expose and give control of transfer flags
diff --git a/README.rst b/README.rst index 409dd3b..c97675b 100644 --- a/README.rst +++ b/README.rst
@@ -574,6 +574,7 @@ - libusb_set_log_cb - libusb_setlocale + libusb_strerror - libusb_wrap_sys_device +- transfer flags LIBUSB_TRANSFER_SHORT_NOT_OK and LIBUSB_TRANSFER_ADD_ZERO_PACKET As a result, python-libusb1 should now be usable on Android.
diff --git a/usb1/__init__.py b/usb1/__init__.py index 4492237..d7cb605 100644 --- a/usb1/__init__.py +++ b/usb1/__init__.py
@@ -221,6 +221,8 @@ after_completion, registerFinalizer, unregisterFinalizer, + short_is_error, + add_zero_packet, ): """ You should not instanciate this class directly. @@ -241,6 +243,8 @@ raise USBErrorNoMem # pylint: enable=undefined-variable self.__transfer = transfer + self.setShortIsError(short_is_error) + self.setAddZeroPacket(add_zero_packet) finalizer_handle = id(self) self.__close = weakref.finalize( self, @@ -720,6 +724,44 @@ transfer.buffer = cast(buff, c_void_p) transfer.length = sizeof(buff) + def isShortAnError(self): + """ + Returns whether the LIBUSB_TRANSFER_SHORT_NOT_OK flag is set on this + transfer. + """ + return bool(self.__transfer.contents.flags & libusb1.LIBUSB_TRANSFER_SHORT_NOT_OK) + + def setShortIsError(self, state): + """ + state (bool) + When true, LIBUSB_TRANSFER_SHORT_NOT_OK flag is set on this + transfer. + Otherwise, it is cleared. + """ + if state: + self.__transfer.contents.flags |= libusb1.LIBUSB_TRANSFER_SHORT_NOT_OK + else: + self.__transfer.contents.flags &= ~libusb1.LIBUSB_TRANSFER_SHORT_NOT_OK + + def isZeroPacketAdded(self): + """ + Returns whether the LIBUSB_TRANSFER_ADD_ZERO_PACKET flag is set on this + transfer. + """ + return bool(self.__transfer.contents.flags & libusb1.LIBUSB_TRANSFER_ADD_ZERO_PACKET) + + def setAddZeroPacket(self, state): + """ + state (bool) + When true, LIBUSB_TRANSFER_ADD_ZERO_PACKET flag is set on this + transfer. + Otherwise, it is cleared. + """ + if state: + self.__transfer.contents.flags |= libusb1.LIBUSB_TRANSFER_ADD_ZERO_PACKET + else: + self.__transfer.contents.flags &= ~libusb1.LIBUSB_TRANSFER_ADD_ZERO_PACKET + def isSubmitted(self): """ Tells if this transfer is submitted and still pending. @@ -1508,11 +1550,14 @@ raise return data_buffer[:transferred] - def getTransfer(self, iso_packets=0): + def getTransfer(self, iso_packets=0, short_is_error=False, add_zero_packet=False): """ Get an USBTransfer instance for asynchronous use. iso_packets: the number of isochronous transfer descriptors to allocate. + short_is_error: When true, short frames are reported as errors. + add_zero_packet: When true, transfers of a multiple of the endpoint + size are followed by a zero-length packet. """ return USBTransfer( context=self.__context, @@ -1522,6 +1567,8 @@ after_completion=self.__inflight_remove, registerFinalizer=self.__registerFinalizer, unregisterFinalizer=self.__unregisterFinalizer, + short_is_error=short_is_error, + add_zero_packet=add_zero_packet, ) class USBConfiguration:
diff --git a/usb1/testUSB1.py b/usb1/testUSB1.py index 76e25a4..420e597 100644 --- a/usb1/testUSB1.py +++ b/usb1/testUSB1.py
@@ -85,7 +85,7 @@ return pointer(transfer) @staticmethod - def getTransfer(iso_packets=0): + def getTransfer(iso_packets=0, short_is_error=False, add_zero_packet=False): # Dummy handle return usb1.USBTransfer( context=None, @@ -95,6 +95,8 @@ after_completion=lambda x: None, registerFinalizer=lambda handle, finalizer: None, unregisterFinalizer=lambda handle: None, + short_is_error=short_is_error, + add_zero_packet=add_zero_packet, ) @staticmethod @@ -145,6 +147,20 @@ request_type, request, value, index, buff, callback=callback) # No callback transfer.setControl(request_type, request, value, index, buff) + self.assertFalse(transfer.isShortAnError()) + self.assertFalse(transfer.isZeroPacketAdded()) + transfer.setShortIsError(True) + self.assertTrue(transfer.isShortAnError()) + self.assertFalse(transfer.isZeroPacketAdded()) + transfer.setAddZeroPacket(True) + self.assertTrue(transfer.isShortAnError()) + self.assertTrue(transfer.isZeroPacketAdded()) + transfer.setShortIsError(False) + self.assertFalse(transfer.isShortAnError()) + self.assertTrue(transfer.isZeroPacketAdded()) + transfer.setAddZeroPacket(False) + self.assertFalse(transfer.isShortAnError()) + self.assertFalse(transfer.isZeroPacketAdded()) def _testTransferSetter(self, transfer, setter_id): endpoint = 0x81