diff --git a/java/src/ch/ntb/usb/Device.java b/java/src/ch/ntb/usb/Device.java
index db8ee0d..e563190 100644
--- a/java/src/ch/ntb/usb/Device.java
+++ b/java/src/ch/ntb/usb/Device.java
@@ -1,567 +1,525 @@
package ch.ntb.usb;
+
import java.util.logging.Level;
import java.util.logging.Logger;
import ch.ntb.usb.logger.LogUtil;
+
/**
* This class represents an USB device.
* To get an instance of an USB device use USB.getDevice(...).
*
* @author schlaepfer
- *
*/
public class Device {
- private static final Logger logger = LogUtil.getLogger("ch.ntb.usb");
+ private static final Logger logger = LogUtil.getLogger("ch.ntb.usb");
- private static final int TIMEOUT_ERROR_CODE = -116;
+ private static final int TIMEOUT_ERROR_CODE = -116;
- private int maxPacketSize;
+ private int maxPacketSize;
- private int idVendor, idProduct, dev_configuration, dev_interface,
- dev_altinterface;
+ private int idVendor, idProduct, dev_configuration, dev_interface,
+ dev_altinterface;
- private int usbDevHandle;
+ private int usbDevHandle;
- private boolean resetOnFirstOpen, resetDone;
+ private boolean resetOnFirstOpen, resetDone;
- private int resetTimeout = 1000;
+ private int resetTimeout = 1000;
- protected Device(short idVendor, short idProduct) {
- resetOnFirstOpen = false;
- resetDone = false;
- maxPacketSize = -1;
- this.idVendor = idVendor;
- this.idProduct = idProduct;
- }
- /**
- * Opens the device and claims the specified configuration, interface and
- * altinterface.
- * First the bus is enumerated. If the device is found its descriptors are
- * read and the maxPacketSize value is updated. If no
- * endpoints are found in the descriptors an exception is thrown.
- *
- * @param configuration
- * the configuration
- * @param interface_
- * the interface
- * @param altinterface
- * the alternative interface
- * @throws USBException
- */
- public void open(int configuration, int interface_, int altinterface)
- throws USBException {
- this.dev_configuration = configuration;
- this.dev_interface = interface_;
- this.dev_altinterface = altinterface;
+ protected Device(short idVendor, short idProduct) {
+ resetOnFirstOpen = false;
+ resetDone = false;
+ maxPacketSize = -1;
+ this.idVendor = idVendor;
+ this.idProduct = idProduct;
+ }
- Usb_Bus bus;
- if (usbDevHandle > 0) {
- throw new USBException("device opened, close or reset first");
- }
+ /**
+ * Opens the device and claims the specified configuration, interface and
+ * altinterface.
+ * First the bus is enumerated. If the device is found its descriptors are
+ * read and the maxPacketSize value is updated. If no
+ * endpoints are found in the descriptors an exception is thrown.
+ *
+ * @param configuration the configuration
+ * @param interface_ the interface
+ * @param altinterface the alternative interface
+ * @throws USBException
+ */
+ public void open(int configuration, int interface_, int altinterface) throws USBException {
+ this.dev_configuration = configuration;
+ this.dev_interface = interface_;
+ this.dev_altinterface = altinterface;
- // open bus
- LibusbWin.usb_init();
- LibusbWin.usb_find_busses();
- LibusbWin.usb_find_devices();
+ Usb_Bus bus;
- bus = LibusbWin.usb_get_busses();
- if (bus == null) {
- throw new USBException("LibusbWin.usb_get_busses(): "
- + LibusbWin.usb_strerror());
- }
+ if(usbDevHandle > 0) {
+ throw new USBException("device opened, close or reset first");
+ }
- maxPacketSize = -1;
+ // open bus
+ LibusbWin.usb_init();
+ LibusbWin.usb_find_busses();
+ LibusbWin.usb_find_devices();
- // search for device
- while (bus != null) {
- Usb_Device dev = bus.devices;
- while (dev != null) {
- Usb_Device_Descriptor devDesc = dev.descriptor;
- if ((devDesc.idVendor == idVendor)
- && (devDesc.idProduct == idProduct)) {
- logger.info("Open device: " + dev.filename);
- int res = LibusbWin.usb_open(dev);
- if (res <= 0) {
- throw new USBException("LibusbWin.usb_open: "
- + LibusbWin.usb_strerror());
- }
- usbDevHandle = res;
- // get endpoint wMaxPacketSize
- Usb_Config_Descriptor[] confDesc = dev.config;
- for (int i = 0; i < confDesc.length; i++) {
- Usb_Interface[] int_ = confDesc[i].interface_;
- for (int j = 0; j < int_.length; j++) {
- Usb_Interface_Descriptor[] intDesc = int_[j].altsetting;
- for (int k = 0; k < intDesc.length; k++) {
- Usb_Endpoint_Descriptor[] epDesc = intDesc[k].endpoint;
- for (int l = 0; l < epDesc.length; l++) {
- maxPacketSize = Math.max(
- epDesc[l].wMaxPacketSize,
- maxPacketSize);
- }
- }
- }
- }
- if (maxPacketSize <= 0) {
- throw new USBException(
- "No USB endpoints found. Check the device configuration");
- }
- }
- dev = dev.next;
- }
- bus = bus.next;
- }
- if (usbDevHandle <= 0) {
- throw new USBException("USB device with idVendor 0x"
- + Integer.toHexString(idVendor & 0xFFFF)
- + " and idProduct 0x"
- + Integer.toHexString(idProduct & 0xFFFF) + " not found");
- }
- claim_interface(usbDevHandle, configuration, interface_, altinterface);
- if (resetOnFirstOpen & !resetDone) {
- logger.info("reset on first open");
- resetDone = true;
- reset();
- try {
- Thread.sleep(resetTimeout);
- } catch (InterruptedException e) {
- //
- }
- open(configuration, interface_, altinterface);
- }
- }
+ bus = LibusbWin.usb_get_busses();
+ if(bus == null) {
+ throw new USBException("LibusbWin.usb_get_busses(): " + LibusbWin.usb_strerror());
+ }
- /**
- * Release the claimed interface and close the opened device.
- *
- * @throws USBException
- */
- public void close() throws USBException {
- if (usbDevHandle <= 0) {
- throw new USBException("invalid device handle");
- }
- release_interface(usbDevHandle, dev_interface);
- if (LibusbWin.usb_close(usbDevHandle) < 0) {
- usbDevHandle = 0;
- throw new USBException("LibusbWin.usb_close: "
- + LibusbWin.usb_strerror());
- }
- usbDevHandle = 0;
- maxPacketSize = -1;
- logger.info("device closed");
- }
+ maxPacketSize = -1;
- /**
- * Sends an USB reset to the device. The device handle will no longer be
- * valid. To use the device again, {@link #open(int, int, int)} must be
- * called.
- *
- * @throws USBException
- */
- public void reset() throws USBException {
- if (usbDevHandle <= 0) {
- throw new USBException("invalid device handle");
- }
- if (LibusbWin.usb_reset(usbDevHandle) < 0) {
- usbDevHandle = 0;
- throw new USBException("LibusbWin.usb_reset: "
- + LibusbWin.usb_strerror());
- }
- usbDevHandle = 0;
- logger.info("device reset");
- }
+ // search for device
+ while(bus != null) {
+ Usb_Device dev = bus.devices;
+ while(dev != null) {
+ Usb_Device_Descriptor devDesc = dev.descriptor;
+ if((devDesc.idVendor == idVendor) && (devDesc.idProduct == idProduct)) {
+ logger.info("Open device: " + dev.filename);
+ int res = LibusbWin.usb_open(dev);
+ if(res <= 0) {
+ throw new USBException("LibusbWin.usb_open: " + LibusbWin.usb_strerror());
+ }
+ usbDevHandle = res;
+ // get endpoint wMaxPacketSize
+ Usb_Config_Descriptor[] confDesc = dev.config;
+ for(int i = 0; i < confDesc.length; i++) {
+ Usb_Interface[] int_ = confDesc[i].interface_;
+ for(int j = 0; j < int_.length; j++) {
+ Usb_Interface_Descriptor[] intDesc = int_[j].altsetting;
+ for(int k = 0; k < intDesc.length; k++) {
+ Usb_Endpoint_Descriptor[] epDesc = intDesc[k].endpoint;
+ for(int l = 0; l < epDesc.length; l++) {
+ maxPacketSize = Math.max(epDesc[l].wMaxPacketSize, maxPacketSize);
+ }
+ }
+ }
+ }
+ if(maxPacketSize <= 0) {
+ throw new USBException("No USB endpoints found. Check the device configuration");
+ }
+ }
+ dev = dev.next;
+ }
+ bus = bus.next;
+ }
+ if(usbDevHandle <= 0) {
+ throw new USBException("USB device with idVendor 0x" + Integer.toHexString(idVendor & 0xFFFF) + " and idProduct 0x" + Integer.toHexString(idProduct & 0xFFFF) + " not found");
+ }
+ claim_interface(usbDevHandle, configuration, interface_, altinterface);
+ if(resetOnFirstOpen & !resetDone) {
+ logger.info("reset on first open");
+ resetDone = true;
+ reset();
+ try {
+ Thread.sleep(resetTimeout);
+ }
+ catch(InterruptedException e) {
+ //
+ }
+ open(configuration, interface_, altinterface);
+ }
+ }
- /**
- * Write data to the device using a bulk transfer.
- *
- * @param out_ep_address
- * endpoint address to write to
- * @param data
- * data to write to this endpoint
- * @param length
- * length of the data
- * @param timeout
- * amount of time in ms the device will try to send the data
- * until a timeout exception is thrown
- * @param reopenOnTimeout
- * if set to true, the device will try to open the connection and
- * send the data again before a timeout exception is thrown
- * @return the actual number of bytes written
- * @throws USBException
- */
- public int writeBulk(int out_ep_address, byte[] data, int length,
- int timeout, boolean reopenOnTimeout) throws USBException {
- if (usbDevHandle <= 0) {
- throw new USBException("invalid device handle");
- }
- if (data == null) {
- throw new USBException("data must not be null");
- }
- if (length <= 0) {
- throw new USBException("size must be > 0");
- }
- int lenWritten = LibusbWin.usb_bulk_write(usbDevHandle, out_ep_address,
- data, length, timeout);
- if (lenWritten < 0) {
- if (lenWritten == TIMEOUT_ERROR_CODE) {
- // try to reopen the device and send the data again
- if (reopenOnTimeout) {
- logger.info("try to reopen");
- reset();
- open(dev_configuration, dev_interface, dev_altinterface);
- return writeBulk(out_ep_address, data, length, timeout,
- false);
- }
- throw new USBTimeoutException("LibusbWin.usb_bulk_write: "
- + LibusbWin.usb_strerror());
- }
- throw new USBException("LibusbWin.usb_bulk_write: "
- + LibusbWin.usb_strerror());
- }
- logger.info("length written: " + lenWritten);
- if (logger.isLoggable(Level.FINEST)) {
- StringBuffer sb = new StringBuffer("bulkwrite, ep 0x"
- + Integer.toHexString(out_ep_address) + ": " + lenWritten
- + " Bytes sent: ");
- for (int i = 0; i < lenWritten; i++) {
- sb.append("0x" + String.format("%1$02X", data[i]) + " ");
- }
- logger.info(sb.toString());
- }
- return lenWritten;
- }
+ /**
+ * Release the claimed interface and close the opened device.
+ *
+ * @throws USBException
+ */
+ public void close() throws USBException {
+ if(usbDevHandle <= 0) {
+ throw new USBException("invalid device handle");
+ }
+ release_interface(usbDevHandle, dev_interface);
+ if(LibusbWin.usb_close(usbDevHandle) < 0) {
+ usbDevHandle = 0;
+ throw new USBException("LibusbWin.usb_close: " + LibusbWin.usb_strerror());
+ }
+ usbDevHandle = 0;
+ maxPacketSize = -1;
+ logger.info("device closed");
+ }
- /**
- * Read data from the device using a bulk transfer.
- *
- * @param in_ep_address
- * endpoint address to read from
- * @param data
- * data buffer for the data to be read
- * @param size
- * the maximum requested data size
- * @param timeout
- * amount of time in ms the device will try to receive data until
- * a timeout exception is thrown
- * @param reopenOnTimeout
- * if set to true, the device will try to open the connection and
- * receive the data again before a timeout exception is thrown
- * @return the actual number of bytes read
- * @throws USBException
- */
- public int readBulk(int in_ep_address, byte[] data, int size, int timeout,
- boolean reopenOnTimeout) throws USBException {
- if (usbDevHandle <= 0) {
- throw new USBException("invalid device handle");
- }
- if (data == null) {
- throw new USBException("data must not be null");
- }
- if (size <= 0) {
- throw new USBException("size must be > 0");
- }
- int lenRead = LibusbWin.usb_bulk_read(usbDevHandle, in_ep_address,
- data, size, timeout);
- if (lenRead < 0) {
- if (lenRead == TIMEOUT_ERROR_CODE) {
- // try to reopen the device and send the data again
- if (reopenOnTimeout) {
- logger.info("try to reopen");
- reset();
- open(dev_configuration, dev_interface, dev_altinterface);
- return readBulk(in_ep_address, data, size, timeout, false);
- }
- throw new USBTimeoutException("LibusbWin.usb_bulk_read: "
- + LibusbWin.usb_strerror());
- }
- throw new USBException("LibusbWin.usb_bulk_read: "
- + LibusbWin.usb_strerror());
- }
- logger.info("length read: " + lenRead);
- if (logger.isLoggable(Level.FINEST)) {
- StringBuffer sb = new StringBuffer("bulkread, ep 0x"
- + Integer.toHexString(in_ep_address) + ": " + lenRead
- + " Bytes received: ");
- for (int i = 0; i < lenRead; i++) {
- sb.append("0x" + String.format("%1$02X", data[i]) + " ");
- }
- logger.info(sb.toString());
- }
- return lenRead;
- }
+ /**
+ * Sends an USB reset to the device. The device handle will no longer be
+ * valid. To use the device again, {@link #open(int, int, int)} must be
+ * called.
+ *
+ * @throws USBException
+ */
+ public void reset() throws USBException {
+ if(usbDevHandle <= 0) {
+ throw new USBException("invalid device handle");
+ }
+ if(LibusbWin.usb_reset(usbDevHandle) < 0) {
+ usbDevHandle = 0;
+ throw new USBException("LibusbWin.usb_reset: " + LibusbWin.usb_strerror());
+ }
+ usbDevHandle = 0;
+ logger.info("device reset");
+ }
- /**
- * Write data to the device using a interrupt transfer.
- *
- * @param out_ep_address
- * endpoint address to write to
- * @param data
- * data to write to this endpoint
- * @param length
- * length of the data
- * @param timeout
- * amount of time in ms the device will try to send the data
- * until a timeout exception is thrown
- * @param reopenOnTimeout
- * if set to true, the device will try to open the connection and
- * send the data again before a timeout exception is thrown
- * @return the actual number of bytes written
- * @throws USBException
- */
- public int writeInterrupt(int out_ep_address, byte[] data, int length,
- int timeout, boolean reopenOnTimeout) throws USBException {
- if (usbDevHandle <= 0) {
- throw new USBException("invalid device handle");
- }
- if (data == null) {
- throw new USBException("data must not be null");
- }
- if (length <= 0) {
- throw new USBException("size must be > 0");
- }
- int lenWritten = LibusbWin.usb_interrupt_write(usbDevHandle,
- out_ep_address, data, length, timeout);
- if (lenWritten < 0) {
- if (lenWritten == TIMEOUT_ERROR_CODE) {
- // try to reopen the device and send the data again
- if (reopenOnTimeout) {
- logger.info("try to reopen");
- reset();
- open(dev_configuration, dev_interface, dev_altinterface);
- return writeInterrupt(out_ep_address, data, length,
- timeout, false);
- }
- throw new USBTimeoutException("LibusbWin.usb_bulk_write: "
- + LibusbWin.usb_strerror());
- }
- throw new USBException("LibusbWin.usb_bulk_write: "
- + LibusbWin.usb_strerror());
- }
- logger.info("length written: " + lenWritten);
- if (logger.getLevel().intValue() <= Level.FINEST.intValue()) {
- StringBuffer sb = new StringBuffer("bulkwrite, ep 0x"
- + Integer.toHexString(out_ep_address) + ": " + lenWritten
- + " Bytes sent: ");
- for (int i = 0; i < lenWritten; i++) {
- sb.append("0x" + String.format("%1$02X", data[i]) + " ");
- }
- logger.info(sb.toString());
- }
- return lenWritten;
- }
+ /**
+ * Write data to the device using a bulk transfer.
+ *
+ * @param out_ep_address endpoint address to write to
+ * @param data data to write to this endpoint
+ * @param length length of the data
+ * @param timeout amount of time in ms the device will try to send the data
+ * until a timeout exception is thrown
+ * @param reopenOnTimeout if set to true, the device will try to open the
+ * connection and send the data again before a timeout exception
+ * is thrown
+ * @return the actual number of bytes written
+ * @throws USBException
+ */
+ public int writeBulk(int out_ep_address, byte[] data, int length, int timeout, boolean reopenOnTimeout) throws USBException {
+ if(usbDevHandle <= 0) {
+ throw new USBException("invalid device handle");
+ }
+ if(data == null) {
+ throw new USBException("data must not be null");
+ }
+ if(length <= 0) {
+ throw new USBException("size must be > 0");
+ }
+ int lenWritten = LibusbWin.usb_bulk_write(usbDevHandle, out_ep_address, data, length, timeout);
+ if(lenWritten < 0) {
+ if(lenWritten == TIMEOUT_ERROR_CODE) {
+ // try to reopen the device and send the data again
+ if(reopenOnTimeout) {
+ logger.info("try to reopen");
+ reset();
+ open(dev_configuration, dev_interface, dev_altinterface);
+ return writeBulk(out_ep_address, data, length, timeout, false);
+ }
+ throw new USBTimeoutException("LibusbWin.usb_bulk_write: " + LibusbWin.usb_strerror());
+ }
+ throw new USBException("LibusbWin.usb_bulk_write: " + LibusbWin.usb_strerror());
+ }
- /**
- * Read data from the device using a interrupt transfer.
- *
- * @param in_ep_address
- * endpoint address to read from
- * @param data
- * data buffer for the data to be read
- * @param size
- * the maximum requested data size
- * @param timeout
- * amount of time in ms the device will try to receive data until
- * a timeout exception is thrown
- * @param reopenOnTimeout
- * if set to true, the device will try to open the connection and
- * receive the data again before a timeout exception is thrown
- * @return the actual number of bytes read
- * @throws USBException
- */
- public int readInterrupt(int in_ep_address, byte[] data, int size,
- int timeout, boolean reopenOnTimeout) throws USBException {
- if (usbDevHandle <= 0) {
- throw new USBException("invalid device handle");
- }
- if (data == null) {
- throw new USBException("data must not be null");
- }
- if (size <= 0) {
- throw new USBException("size must be > 0");
- }
- int lenRead = LibusbWin.usb_interrupt_read(usbDevHandle, in_ep_address,
- data, size, timeout);
- if (lenRead < 0) {
- if (lenRead == TIMEOUT_ERROR_CODE) {
- // try to reopen the device and send the data again
- if (reopenOnTimeout) {
- logger.info("try to reopen");
- reset();
- open(dev_configuration, dev_interface, dev_altinterface);
- return readInterrupt(in_ep_address, data, size, timeout,
- false);
- }
- throw new USBTimeoutException("LibusbWin.usb_bulk_read: "
- + LibusbWin.usb_strerror());
- }
- throw new USBException("LibusbWin.usb_bulk_read: "
- + LibusbWin.usb_strerror());
- }
+ logger.info("length written: " + lenWritten);
+ if(logger.isLoggable(Level.FINEST)) {
+ StringBuffer sb = new StringBuffer("bulkwrite, ep 0x" + Integer.toHexString(out_ep_address) + ": " + lenWritten + " Bytes sent: ");
+ for(int i = 0; i < lenWritten; i++) {
+ sb.append("0x" + String.format("%1$02X", data[i]) + " ");
+ }
+ logger.info(sb.toString());
+ }
+ return lenWritten;
+ }
- logger.info("length read: " + lenRead);
- if (logger.getLevel().intValue() <= Level.FINEST.intValue()) {
- StringBuffer sb = new StringBuffer("bulkread, ep 0x"
- + Integer.toHexString(in_ep_address) + ": " + lenRead
- + " Bytes received: ");
- for (int i = 0; i < lenRead; i++) {
- sb.append("0x" + String.format("%1$02X", data[i]) + " ");
- }
- logger.info(sb.toString());
- }
- return lenRead;
- }
- /**
- * Claim an interface to send and receive USB data.
- *
- * @param usb_dev_handle
- * the handle of the device (MUST BE VALID)
- * @param configuration
- * the configuration to use
- * @param interface_
- * the interface to claim
- * @param altinterface
- * the alternative interface to use
- * @throws USBException
- * throws an USBException if the action fails
- */
- private void claim_interface(int usb_dev_handle, int configuration,
- int interface_, int altinterface) throws USBException {
- if (LibusbWin.usb_set_configuration(usb_dev_handle, configuration) < 0) {
- throw new USBException("LibusbWin.usb_set_configuration: "
- + LibusbWin.usb_strerror());
- }
- if (LibusbWin.usb_claim_interface(usb_dev_handle, interface_) < 0) {
- throw new USBException("LibusbWin.usb_claim_interface: "
- + LibusbWin.usb_strerror());
- }
- if (LibusbWin.usb_set_altinterface(usb_dev_handle, altinterface) < 0) {
- throw new USBException("LibusbWin.usb_set_altinterface: "
- + LibusbWin.usb_strerror());
- }
- logger.info("interface claimed");
- }
+ /**
+ * Read data from the device using a bulk transfer.
+ *
+ * @param in_ep_address endpoint address to read from
+ * @param data data buffer for the data to be read
+ * @param size the maximum requested data size
+ * @param timeout amount of time in ms the device will try to receive data
+ * until a timeout exception is thrown
+ * @param reopenOnTimeout if set to true, the device will try to open the
+ * connection and receive the data again before a timeout
+ * exception is thrown
+ * @return the actual number of bytes read
+ * @throws USBException
+ */
+ public int readBulk(int in_ep_address, byte[] data, int size, int timeout, boolean reopenOnTimeout) throws USBException {
+ if(usbDevHandle <= 0) {
+ throw new USBException("invalid device handle");
+ }
+ if(data == null) {
+ throw new USBException("data must not be null");
+ }
+ if(size <= 0) {
+ throw new USBException("size must be > 0");
+ }
+ int lenRead = LibusbWin.usb_bulk_read(usbDevHandle, in_ep_address, data, size, timeout);
+ if(lenRead < 0) {
+ if(lenRead == TIMEOUT_ERROR_CODE) {
+ // try to reopen the device and send the data again
+ if(reopenOnTimeout) {
+ logger.info("try to reopen");
+ reset();
+ open(dev_configuration, dev_interface, dev_altinterface);
+ return readBulk(in_ep_address, data, size, timeout, false);
+ }
+ throw new USBTimeoutException("LibusbWin.usb_bulk_read: " + LibusbWin.usb_strerror());
+ }
+ throw new USBException("LibusbWin.usb_bulk_read: " + LibusbWin.usb_strerror());
+ }
- /**
- * Release a previously claimed interface.
- *
- * @param dev_handle
- * the handle of the device (MUST BE VALID)
- * @param interface_
- * the interface to claim
- * @throws USBException
- * throws an USBException if the action fails
- */
- private void release_interface(int dev_handle, int interface_)
- throws USBException {
- if (LibusbWin.usb_release_interface(dev_handle, interface_) < 0) {
- usbDevHandle = 0;
- throw new USBException("LibusbWin.usb_release_interface: "
- + LibusbWin.usb_strerror());
- }
- logger.info("interface released");
- }
+ logger.info("length read: " + lenRead);
+ if(logger.isLoggable(Level.FINEST)) {
+ StringBuffer sb = new StringBuffer("bulkread, ep 0x" + Integer.toHexString(in_ep_address) + ": " + lenRead + " Bytes received: ");
+ for(int i = 0; i < lenRead; i++) {
+ sb.append("0x" + String.format("%1$02X", data[i]) + " ");
+ }
+ logger.info(sb.toString());
+ }
+ return lenRead;
+ }
- /**
- * Returns the product ID of the device.
- *
- * @return the product ID of the device.
- */
- public int getIdProduct() {
- return idProduct;
- }
- /**
- * Returns the vendor ID of the device.
- *
- * @return the vendor ID of the device.
- */
- public int getIdVendor() {
- return idVendor;
- }
+ /**
+ * Write data to the device using a interrupt transfer.
+ *
+ * @param out_ep_address endpoint address to write to
+ * @param data data to write to this endpoint
+ * @param length length of the data
+ * @param timeout amount of time in ms the device will try to send the data
+ * until a timeout exception is thrown
+ * @param reopenOnTimeout if set to true, the device will try to open the
+ * connection and send the data again before a timeout exception
+ * is thrown
+ * @return the actual number of bytes written
+ * @throws USBException
+ */
+ public int writeInterrupt(int out_ep_address, byte[] data, int length, int timeout, boolean reopenOnTimeout) throws USBException {
+ if(usbDevHandle <= 0) {
+ throw new USBException("invalid device handle");
+ }
+ if(data == null) {
+ throw new USBException("data must not be null");
+ }
+ if(length <= 0) {
+ throw new USBException("size must be > 0");
+ }
+ int lenWritten = LibusbWin.usb_interrupt_write(usbDevHandle, out_ep_address, data, length, timeout);
+ if(lenWritten < 0) {
+ if(lenWritten == TIMEOUT_ERROR_CODE) {
+ // try to reopen the device and send the data again
+ if(reopenOnTimeout) {
+ logger.info("try to reopen");
+ reset();
+ open(dev_configuration, dev_interface, dev_altinterface);
+ return writeInterrupt(out_ep_address, data, length, timeout, false);
+ }
+ throw new USBTimeoutException("LibusbWin.usb_bulk_write: " + LibusbWin.usb_strerror());
+ }
+ throw new USBException("LibusbWin.usb_bulk_write: " + LibusbWin.usb_strerror());
+ }
- /**
- * Returns the alternative interface. This value is only valid after opening
- * the device.
- *
- * @return the alternative interface. This value is only valid after opening
- * the device.
- */
- public int getAltinterface() {
- return dev_altinterface;
- }
+ logger.info("length written: " + lenWritten);
+ if(logger.getLevel().intValue() <= Level.FINEST.intValue()) {
+ StringBuffer sb = new StringBuffer("bulkwrite, ep 0x" + Integer.toHexString(out_ep_address) + ": " + lenWritten + " Bytes sent: ");
+ for(int i = 0; i < lenWritten; i++) {
+ sb.append("0x" + String.format("%1$02X", data[i]) + " ");
+ }
+ logger.info(sb.toString());
+ }
+ return lenWritten;
+ }
- /**
- * Returns the current configuration used. This value is only valid after
- * opening the device.
- *
- * @return the current configuration used. This value is only valid after
- * opening the device.
- */
- public int getConfiguration() {
- return dev_configuration;
- }
- /**
- * Returns the current interface. This value is only valid after opening the
- * device.
- *
- * @return the current interface. This value is only valid after opening the
- * device.
- */
- public int getInterface() {
- return dev_interface;
- }
+ /**
+ * Read data from the device using a interrupt transfer.
+ *
+ * @param in_ep_address endpoint address to read from
+ * @param data data buffer for the data to be read
+ * @param size the maximum requested data size
+ * @param timeout amount of time in ms the device will try to receive data
+ * until a timeout exception is thrown
+ * @param reopenOnTimeout if set to true, the device will try to open the
+ * connection and receive the data again before a timeout
+ * exception is thrown
+ * @return the actual number of bytes read
+ * @throws USBException
+ */
+ public int readInterrupt(int in_ep_address, byte[] data, int size, int timeout, boolean reopenOnTimeout) throws USBException {
+ if(usbDevHandle <= 0) {
+ throw new USBException("invalid device handle");
+ }
+ if(data == null) {
+ throw new USBException("data must not be null");
+ }
+ if(size <= 0) {
+ throw new USBException("size must be > 0");
+ }
+ int lenRead = LibusbWin.usb_interrupt_read(usbDevHandle, in_ep_address, data, size, timeout);
+ if(lenRead < 0) {
+ if(lenRead == TIMEOUT_ERROR_CODE) {
+ // try to reopen the device and send the data again
+ if(reopenOnTimeout) {
+ logger.info("try to reopen");
+ reset();
+ open(dev_configuration, dev_interface, dev_altinterface);
+ return readInterrupt(in_ep_address, data, size, timeout, false);
+ }
+ throw new USBTimeoutException("LibusbWin.usb_bulk_read: " + LibusbWin.usb_strerror());
+ }
+ throw new USBException("LibusbWin.usb_bulk_read: " + LibusbWin.usb_strerror());
+ }
- /**
- * Returns the current device handle. This value is only valid after opening
- * the device.
- *
- * @return the current device handle. This value is only valid after opening
- * the device.
- */
- public int getUsbDevHandle() {
- return usbDevHandle;
- }
+ logger.info("length read: " + lenRead);
+ if(logger.getLevel().intValue() <= Level.FINEST.intValue()) {
+ StringBuffer sb = new StringBuffer("bulkread, ep 0x" + Integer.toHexString(in_ep_address) + ": " + lenRead + " Bytes received: ");
+ for(int i = 0; i < lenRead; i++) {
+ sb.append("0x" + String.format("%1$02X", data[i]) + " ");
+ }
+ logger.info(sb.toString());
+ }
+ return lenRead;
+ }
- /**
- * Returns the maximum packet size in bytes which is allowed to be
- * transmitted at once.
- * The value is determined by reading the endpoint descriptor(s) when
- * opening the device. It is invalid before the device is opened! Note that
- * if some endpoints use different packet sizes the maximum packet size is
- * return. This value may be used to determine if a device is opened in
- * fullspeed or highspeed mode.
- *
- * @return the maximum packet size
- */
- public int getMaxPacketSize() {
- return maxPacketSize;
- }
- /**
- * If enabled, the device is reset when first opened.
- * This will only happen once. When the application is started, the device
- * state is unknown. If the device is not reset, read or write may result in
- * a {@link USBTimeoutException}.
- *
- * This feature is disabled by default.
- *
- * @param enable
- * true if the device should be reset when first opened
- * @param timeout
- * the timeout between the reset and the reopening
- */
- public void setResetOnFirstOpen(boolean enable, int timeout) {
- resetOnFirstOpen = enable;
- resetTimeout = timeout;
- }
+ /**
+ * Claim an interface to send and receive USB data.
+ *
+ * @param usb_dev_handle the handle of the device (MUST BE VALID)
+ * @param configuration the configuration to use
+ * @param interface_ the interface to claim
+ * @param altinterface the alternative interface to use
+ * @throws USBException throws an USBException if the action fails
+ */
+ private void claim_interface(int usb_dev_handle, int configuration, int interface_, int altinterface) throws USBException {
+ if(LibusbWin.usb_set_configuration(usb_dev_handle, configuration) < 0) {
+ throw new USBException("LibusbWin.usb_set_configuration: " + LibusbWin.usb_strerror());
+ }
+ if(LibusbWin.usb_claim_interface(usb_dev_handle, interface_) < 0) {
+ throw new USBException("LibusbWin.usb_claim_interface: " + LibusbWin.usb_strerror());
+ }
+ if(LibusbWin.usb_set_altinterface(usb_dev_handle, altinterface) < 0) {
+ throw new USBException("LibusbWin.usb_set_altinterface: " + LibusbWin.usb_strerror());
+ }
+ logger.info("interface claimed");
+ }
+
+
+ /**
+ * Release a previously claimed interface.
+ *
+ * @param dev_handle the handle of the device (MUST BE VALID)
+ * @param interface_ the interface to claim
+ * @throws USBException throws an USBException if the action fails
+ */
+ private void release_interface(int dev_handle, int interface_) throws USBException {
+ if(LibusbWin.usb_release_interface(dev_handle, interface_) < 0) {
+ usbDevHandle = 0;
+ throw new USBException("LibusbWin.usb_release_interface: " + LibusbWin.usb_strerror());
+ }
+ logger.info("interface released");
+ }
+
+
+ /**
+ * Returns the product ID of the device.
+ *
+ * @return the product ID of the device.
+ */
+ public int getIdProduct() {
+ return idProduct;
+ }
+
+
+ /**
+ * Returns the vendor ID of the device.
+ *
+ * @return the vendor ID of the device.
+ */
+ public int getIdVendor() {
+ return idVendor;
+ }
+
+
+ /**
+ * Returns the alternative interface. This value is only valid after opening
+ * the device.
+ *
+ * @return the alternative interface. This value is only valid after opening
+ * the device.
+ */
+ public int getAltinterface() {
+ return dev_altinterface;
+ }
+
+
+ /**
+ * Returns the current configuration used. This value is only valid after
+ * opening the device.
+ *
+ * @return the current configuration used. This value is only valid after
+ * opening the device.
+ */
+ public int getConfiguration() {
+ return dev_configuration;
+ }
+
+
+ /**
+ * Returns the current interface. This value is only valid after opening the
+ * device.
+ *
+ * @return the current interface. This value is only valid after opening the
+ * device.
+ */
+ public int getInterface() {
+ return dev_interface;
+ }
+
+
+ /**
+ * Returns the current device handle. This value is only valid after opening
+ * the device.
+ *
+ * @return the current device handle. This value is only valid after opening
+ * the device.
+ */
+ public int getUsbDevHandle() {
+ return usbDevHandle;
+ }
+
+
+ /**
+ * Returns the maximum packet size in bytes which is allowed to be
+ * transmitted at once.
+ * The value is determined by reading the endpoint descriptor(s) when
+ * opening the device. It is invalid before the device is opened! Note that
+ * if some endpoints use different packet sizes the maximum packet size is
+ * return. This value may be used to determine if a device is opened in
+ * fullspeed or highspeed mode.
+ *
+ * @return the maximum packet size
+ */
+ public int getMaxPacketSize() {
+ return maxPacketSize;
+ }
+
+
+ /**
+ * Check if the device is open.
+ * This checks only for a valid device handle. It doesn't check if the
+ * device is still attached or working.
+ *
+ * @return true if the device is open
+ */
+ public boolean isOpen() {
+ return usbDevHandle > 0;
+ }
+
+
+ /**
+ * If enabled, the device is reset when first opened.
+ * This will only happen once. When the application is started, the device
+ * state is unknown. If the device is not reset, read or write may result in
+ * a {@link USBTimeoutException}.
+ *
+ * This feature is disabled by default.
+ *
+ * @param enable true if the device should be reset when first opened
+ * @param timeout the timeout between the reset and the reopening
+ */
+ public void setResetOnFirstOpen(boolean enable, int timeout) {
+ resetOnFirstOpen = enable;
+ resetTimeout = timeout;
+ }
}