diff --git a/java/src/ch/ntb/usb/Device.java b/java/src/ch/ntb/usb/Device.java
index bf2b595..e72f7dd 100644
--- a/java/src/ch/ntb/usb/Device.java
+++ b/java/src/ch/ntb/usb/Device.java
@@ -23,8 +23,18 @@ public class Device {
private int maxPacketSize;
- private int idVendor, idProduct, dev_configuration, dev_interface,
- dev_altinterface;
+ /**
+ * Mandatory identification values for the device.
+ */
+ private int idVendor, idProduct;
+
+ /**
+ * Optional identification value for the device (e.g. if there are multiple
+ * devices with the same vendor and product id).
+ */
+ private String filename;
+
+ private int dev_configuration, dev_interface, dev_altinterface;
private long usbDevHandle;
@@ -34,32 +44,22 @@ public class Device {
private Usb_Device dev;
- private boolean initUSBDone;
-
protected Device(short idVendor, short idProduct) {
- initUSBDone = false;
resetOnFirstOpen = false;
resetDone = false;
maxPacketSize = -1;
this.idVendor = idVendor;
this.idProduct = idProduct;
+ this.filename = null;
}
- private void initUSB() {
- LibusbJava.usb_init();
- initUSBDone = true;
- }
-
- private Usb_Bus initBus() throws USBException {
- LibusbJava.usb_find_busses();
- LibusbJava.usb_find_devices();
-
- Usb_Bus bus = LibusbJava.usb_get_busses();
- if (bus == null) {
- throw new USBException("LibusbJava.usb_get_busses(): "
- + LibusbJava.usb_strerror());
- }
- return bus;
+ protected Device(short idVendor, short idProduct, String filename) {
+ resetOnFirstOpen = false;
+ resetDone = false;
+ maxPacketSize = -1;
+ this.idVendor = idVendor;
+ this.idProduct = idProduct;
+ this.filename = filename;
}
private void updateMaxPacketSize(Usb_Device device) throws USBException {
@@ -84,8 +84,14 @@ public class Device {
}
}
- private Usb_Device initDevice() throws USBException {
- Usb_Bus bus = initBus();
+ /**
+ * Initializes the device. The parameters idVendor and
+ * idProduct are mandatory. The parameter
+ * filename is optional.
+ */
+ private Usb_Device initDevice(int idVendorParam, int idProductParam,
+ String filename) throws USBException {
+ Usb_Bus bus = USB.getBus();
Usb_Device device = null;
// search for device
@@ -93,8 +99,17 @@ public class Device {
device = bus.getDevices();
while (device != null) {
Usb_Device_Descriptor devDesc = device.getDescriptor();
- if ((devDesc.getIdVendor() == idVendor)
- && (devDesc.getIdProduct() == idProduct)) {
+ if (filename != null
+ && filename.compareTo(device.getFilename()) == 0
+ && devDesc.getIdVendor() == idVendorParam
+ && devDesc.getIdProduct() == idProductParam) {
+ // idVendor, idProduct and filename
+ logger.info("Device found: " + device.getFilename());
+ updateMaxPacketSize(device);
+ return device;
+ } else if (devDesc.getIdVendor() == idVendorParam
+ && devDesc.getIdProduct() == idProductParam) {
+ // only idVendor and idProduct
logger.info("Device found: " + device.getFilename());
updateMaxPacketSize(device);
return device;
@@ -114,9 +129,7 @@ public class Device {
* @throws USBException
*/
public void updateDescriptors() throws USBException {
- if (!initUSBDone)
- initUSB();
- dev = initDevice();
+ dev = initDevice(idVendor, idProduct, filename);
}
/**
@@ -175,9 +188,7 @@ public class Device {
throw new USBException("device opened, close or reset first");
}
- initUSB();
-
- dev = initDevice();
+ dev = initDevice(idVendor, idProduct, filename);
if (dev != null) {
long res = LibusbJava.usb_open(dev);
@@ -724,4 +735,26 @@ public class Device {
resetOnFirstOpen = enable;
resetTimeout = timeout;
}
+
+ /**
+ * Returns the optional filename which is set when there are multiple
+ * devices with the same vendor and product id. See
+ * {@link USB#getDevice(short, short, String)}. Use
+ * {@link Usb_Device#getFilename()} to read the filename of a device.
+ *
+ * @return the filename if set or null
+ */
+ protected String getFilename() {
+ return filename;
+ }
+
+ /**
+ * Returns the Usb_Device instance associated with this device. This value
+ * is only valid after opening the device.
+ *
+ * @return the Usb_Device instance associated with this device.
+ */
+ public Usb_Device getDevice() {
+ return dev;
+ }
}
diff --git a/java/src/ch/ntb/usb/USB.java b/java/src/ch/ntb/usb/USB.java
index f9b293d..6948f9a 100644
--- a/java/src/ch/ntb/usb/USB.java
+++ b/java/src/ch/ntb/usb/USB.java
@@ -167,6 +167,8 @@ public class USB {
private static LinkedList devices = new LinkedList();
+ private static boolean initUSBDone = false;
+
/**
* Create a new device an register it in a device queue. If the device is
* already registered, a reference to it will be returned.
@@ -175,22 +177,38 @@ public class USB {
* the vendor id of the USB device
* @param idProduct
* the product id of the USB device
+ * @param filename
+ * an optional filename which can be used to distinguish multiple
+ * devices with the same vendor and product id.
* @return a newly created device or an already registered device
*/
- public static Device getDevice(short idVendor, short idProduct) {
+ public static Device getDevice(short idVendor, short idProduct,
+ String filename) {
// check if this device is already registered
- Device dev = getRegisteredDevice(idVendor, idProduct);
+ Device dev = getRegisteredDevice(idVendor, idProduct, filename);
if (dev != null) {
logger.info("return already registered device");
return dev;
}
- dev = new Device(idVendor, idProduct);
+ dev = new Device(idVendor, idProduct, filename);
logger.info("create new device");
devices.add(dev);
return dev;
}
+ /**
+ * See {@link #getDevice(short, short, String)}. The parameter
+ * filename is set to null.
+ *
+ * @param idVendor
+ * @param idProduct
+ * @return
+ */
+ public static Device getDevice(short idVendor, short idProduct) {
+ return getDevice(idVendor, idProduct, null);
+ }
+
/**
* Get an already registered device or null if the device does not exist.
*
@@ -198,16 +216,55 @@ public class USB {
* the vendor id of the USB device
* @param idProduct
* the product id of the USB device
+ * @param filename
+ * an optional filename which can be used to distinguish multiple
+ * devices with the same vendor and product id.
* @return the device or null
*/
- private static Device getRegisteredDevice(short idVendor, short idProduct) {
+ private static Device getRegisteredDevice(short idVendor, short idProduct,
+ String filename) {
for (Iterator iter = devices.iterator(); iter.hasNext();) {
Device dev = iter.next();
- if ((dev.getIdVendor() == idVendor)
- && (dev.getIdProduct() == idProduct)) {
+ if (filename != null && filename.compareTo(dev.getFilename()) == 0
+ && dev.getIdVendor() == idVendor
+ && dev.getIdProduct() == idProduct) {
+ return dev;
+ } else if (dev.getIdVendor() == idVendor
+ && dev.getIdProduct() == idProduct) {
return dev;
}
}
return null;
}
+
+ /**
+ * Returns the root {@link Usb_Bus} element.
+ *
+ * @return the root {@link Usb_Bus} element
+ * @throws USBException
+ */
+ public static Usb_Bus getBus() throws USBException {
+ if (!initUSBDone) {
+ init();
+ }
+ LibusbJava.usb_find_busses();
+ LibusbJava.usb_find_devices();
+
+ Usb_Bus bus = LibusbJava.usb_get_busses();
+ if (bus == null) {
+ throw new USBException("LibusbJava.usb_get_busses(): "
+ + LibusbJava.usb_strerror());
+ }
+ return bus;
+ }
+
+ /**
+ * Explicitly calls {@link LibusbJava#usb_init()}. Note that you don't need
+ * to call this procedure as it is called implicitly when creating a new
+ * device with {@link USB#getDevice(short, short, String)}.
+ */
+ public static void init() {
+ LibusbJava.usb_init();
+ initUSBDone = true;
+ }
}
diff --git a/java/src/ch/ntb/usb/Utils.java b/java/src/ch/ntb/usb/Utils.java
index fef8fc3..e14591d 100644
--- a/java/src/ch/ntb/usb/Utils.java
+++ b/java/src/ch/ntb/usb/Utils.java
@@ -7,35 +7,43 @@
*/
package ch.ntb.usb;
+import java.io.PrintStream;
+
public class Utils {
public static void logBus(Usb_Bus bus) {
+ logBus(bus, System.out);
+ }
+
+ public static void logBus(Usb_Bus bus, PrintStream out) {
Usb_Bus usb_Bus = bus;
while (usb_Bus != null) {
- System.out.println(usb_Bus.toString());
+ out.println(usb_Bus.toString());
Usb_Device dev = usb_Bus.getDevices();
while (dev != null) {
- System.out.println("\t" + dev.toString());
+ out.println("\t" + dev.toString());
// Usb_Device_Descriptor
Usb_Device_Descriptor defDesc = dev.getDescriptor();
- System.out.println("\t\t" + defDesc.toString());
+ out.println("\t\t" + defDesc.toString());
// Usb_Config_Descriptor
Usb_Config_Descriptor[] confDesc = dev.getConfig();
for (int i = 0; i < confDesc.length; i++) {
- System.out.println("\t\t" + confDesc[i].toString());
+ out.println("\t\t" + confDesc[i].toString());
Usb_Interface[] int_ = confDesc[i].getInterface();
if (int_ != null) {
for (int j = 0; j < int_.length; j++) {
- System.out.println("\t\t\t" + int_[j].toString());
- Usb_Interface_Descriptor[] intDesc = int_[j].getAltsetting();
+ out.println("\t\t\t" + int_[j].toString());
+ Usb_Interface_Descriptor[] intDesc = int_[j]
+ .getAltsetting();
if (intDesc != null) {
for (int k = 0; k < intDesc.length; k++) {
- System.out.println("\t\t\t\t"
+ out.println("\t\t\t\t"
+ intDesc[k].toString());
- Usb_Endpoint_Descriptor[] epDesc = intDesc[k].getEndpoint();
+ Usb_Endpoint_Descriptor[] epDesc = intDesc[k]
+ .getEndpoint();
if (epDesc != null) {
for (int e = 0; e < epDesc.length; e++) {
- System.out.println("\t\t\t\t\t"
+ out.println("\t\t\t\t\t"
+ epDesc[e].toString());
}
}
diff --git a/java/test/ch/ntb/usb/test/DeviceTest.java b/java/test/ch/ntb/usb/test/DeviceTest.java
index 1146a6e..7b43925 100644
--- a/java/test/ch/ntb/usb/test/DeviceTest.java
+++ b/java/test/ch/ntb/usb/test/DeviceTest.java
@@ -8,13 +8,17 @@
package ch.ntb.usb.test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
+import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
+import java.util.logging.Logger;
import junit.framework.Assert;
@@ -26,8 +30,10 @@ import ch.ntb.usb.Device;
import ch.ntb.usb.LibusbJava;
import ch.ntb.usb.USB;
import ch.ntb.usb.USBException;
+import ch.ntb.usb.Usb_Bus;
import ch.ntb.usb.Usb_Config_Descriptor;
import ch.ntb.usb.Usb_Device_Descriptor;
+import ch.ntb.usb.Utils;
import ch.ntb.usb.testApp.AbstractDeviceInfo;
import ch.ntb.usb.testApp.AbstractDeviceInfo.TransferMode;
@@ -48,6 +54,8 @@ public class DeviceTest {
private static Device dev;
+ private static Logger log = Logger.getLogger(DeviceTest.class.getName());
+
@SuppressWarnings("unchecked")
@BeforeClass
public static void setUp() throws Exception {
@@ -71,6 +79,17 @@ public class DeviceTest {
// initialise the device
LibusbJava.usb_set_debug(255);
dev = USB.getDevice(devinfo.getIdVendor(), devinfo.getIdProduct());
+ assertNotNull(dev);
+
+ // print the devices
+ LibusbJava.usb_init();
+ LibusbJava.usb_find_busses();
+ LibusbJava.usb_find_devices();
+ Usb_Bus bus = LibusbJava.usb_get_busses();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ Utils.logBus(bus, ps);
+ log.info(baos.toString());
}
@SuppressWarnings("null")
@@ -78,11 +97,11 @@ public class DeviceTest {
public void getDescriptors() throws Exception {
dev.updateDescriptors();
Usb_Device_Descriptor devDescriptor = dev.getDeviceDescriptor();
- assertTrue(devDescriptor != null);
+ assertNotNull(devDescriptor);
assertEquals(devinfo.getIdProduct(), devDescriptor.getIdProduct());
assertEquals(devinfo.getIdVendor(), devDescriptor.getIdVendor());
Usb_Config_Descriptor confDescriptors[] = dev.getConfigDescriptors();
- assertTrue(confDescriptors != null);
+ assertNotNull(confDescriptors);
assertTrue(confDescriptors[0].getInterface().length > 0);
}
@@ -139,6 +158,20 @@ public class DeviceTest {
doClose();
}
+ @Test
+ public void openWithFilename() throws Exception {
+ // get device by filename
+ doOpen();
+ assertNotNull(dev.getDevice());
+ String oldFilename = dev.getDevice().getFilename();
+ assertNotNull(oldFilename);
+ log.info("Filename: " + oldFilename);
+ Device dev2 = USB.getDevice(devinfo.getIdVendor(), devinfo
+ .getIdProduct(), oldFilename);
+ assertEquals(dev, dev2);
+ doClose();
+ }
+
@Test
public void bulkWriteRead() throws Exception {
checkBulkEndpoints();
@@ -224,8 +257,8 @@ public class DeviceTest {
@Test
public void controlMsg() throws Exception {
try {
- dev.open(devinfo.getConfiguration(), devinfo.getInterface(), devinfo
- .getAltinterface());
+ dev.open(devinfo.getConfiguration(), devinfo.getInterface(),
+ devinfo.getAltinterface());
// GET STATUS (device)
byte[] data = getTestData(2);
int length = dev.controlMsg(USB.REQ_TYPE_DIR_DEVICE_TO_HOST
@@ -237,10 +270,11 @@ public class DeviceTest {
assertEquals((byte) 0x00, data[1]);
// GET STATUS (interface)
data = getTestData(2);
- length = dev.controlMsg(USB.REQ_TYPE_DIR_DEVICE_TO_HOST
- | USB.REQ_TYPE_TYPE_STANDARD | USB.REQ_TYPE_RECIP_INTERFACE,
- USB.REQ_GET_STATUS, 0, 0, data, data.length, devinfo
- .getTimeout(), false);
+ length = dev.controlMsg(
+ USB.REQ_TYPE_DIR_DEVICE_TO_HOST
+ | USB.REQ_TYPE_TYPE_STANDARD
+ | USB.REQ_TYPE_RECIP_INTERFACE, USB.REQ_GET_STATUS,
+ 0, 0, data, data.length, devinfo.getTimeout(), false);
assertTrue(length > 0);
assertEquals((byte) 0x00, data[0]);
assertEquals((byte) 0x00, data[1]);
@@ -265,7 +299,8 @@ public class DeviceTest {
// data = byte[1];
// length = dev.controlMsg(USB.REQ_TYPE_DIR_DEVICE_TO_HOST
// | USB.REQ_TYPE_TYPE_STANDARD | USB.REQ_TYPE_RECIP_INTERFACE,
- // USB.REQ_GET_INTERFACE, 0, devinfo.getInterface(), data, data.length,
+ // USB.REQ_GET_INTERFACE, 0, devinfo.getInterface(), data,
+ // data.length,
// devinfo
// .getTimeout(), false);
// logData(data, length);
@@ -273,8 +308,8 @@ public class DeviceTest {
data = getTestData(128);
length = dev.controlMsg(USB.REQ_TYPE_DIR_DEVICE_TO_HOST
| USB.REQ_TYPE_TYPE_STANDARD | USB.REQ_TYPE_RECIP_DEVICE,
- USB.REQ_GET_DESCRIPTOR, 1 << 8, 0, data, data.length, devinfo
- .getTimeout(), false);
+ USB.REQ_GET_DESCRIPTOR, 1 << 8, 0, data, data.length,
+ devinfo.getTimeout(), false);
validateDeviceDescriptor(data, length);
// GET DESCRIPTOR (string descriptor (1))
data = getTestData(128);
@@ -369,14 +404,15 @@ public class DeviceTest {
return b;
}
+ @SuppressWarnings("unused")
private void logData(byte[] data, int length) {
if (length > 0) {
- System.out.println("length: " + length);
+ log.info("length: " + length);
+ String logData = "";
for (int i = 0; i < length; i++) {
- System.out.print("0x" + Integer.toHexString(data[i] & 0xff)
- + "\t");
+ logData += "0x" + Integer.toHexString(data[i] & 0xff) + "\t";
}
- System.out.println();
+ log.info(logData);
}
}
@@ -399,8 +435,7 @@ public class DeviceTest {
devinfo.getAltinterface());
fail("USBException expected");
} catch (USBException e) {
- System.err.println("INFO: " + getClass()
- + ": error expected: could not set config "
+ log.severe("could not set config "
+ (devinfo.getConfiguration() + 5));
}
doOpenWriteReadClose();
@@ -413,8 +448,7 @@ public class DeviceTest {
devinfo.getAltinterface());
fail("USBException expected");
} catch (USBException e) {
- System.err.println("INFO: " + getClass()
- + ": error expected: could not claim interface "
+ log.severe("could not claim interface "
+ (devinfo.getInterface() + 5));
}
doOpenWriteReadClose();
@@ -427,8 +461,7 @@ public class DeviceTest {
devinfo.getAltinterface() + 5);
fail("USBException expected");
} catch (USBException e) {
- System.err.println("INFO: " + getClass()
- + ": error expected: could not set alt interface "
+ log.severe("could not set alt interface "
+ (devinfo.getAltinterface() + 5));
}
doOpenWriteReadClose();
@@ -436,33 +469,33 @@ public class DeviceTest {
@Test
public void testGetIdProduct() {
- Assert.assertEquals(dev.getIdProduct(), devinfo.getIdProduct());
+ Assert.assertEquals(devinfo.getIdProduct(), dev.getIdProduct());
}
@Test
public void testGetIdVendor() {
- Assert.assertEquals(dev.getIdVendor(), devinfo.getIdVendor());
+ Assert.assertEquals(devinfo.getIdVendor(), dev.getIdVendor());
}
@Test
public void testGetAltinterface() {
- Assert.assertEquals(dev.getAltinterface(), devinfo.getAltinterface());
+ Assert.assertEquals(devinfo.getAltinterface(), dev.getAltinterface());
}
@Test
public void testGetConfiguration() {
- Assert.assertEquals(dev.getConfiguration(), devinfo.getConfiguration());
+ Assert.assertEquals(devinfo.getConfiguration(), dev.getConfiguration());
}
@Test
public void testGetInterface() {
- Assert.assertEquals(dev.getInterface(), devinfo.getInterface());
+ Assert.assertEquals(devinfo.getInterface(), dev.getInterface());
}
@Test
public void testGetMaxPacketSize() throws USBException {
doOpen();
- Assert.assertEquals(dev.getMaxPacketSize(), devinfo.getMaxDataSize());
+ Assert.assertEquals(devinfo.getMaxDataSize(), dev.getMaxPacketSize());
doClose();
}
@@ -495,7 +528,8 @@ public class DeviceTest {
if (devinfo.getOutEPBulk() != -1) {
dev.writeBulk(devinfo.getOutEPBulk(), testData,
testData.length, devinfo.getTimeout(), false);
- } else if (devinfo.getInEPBulk() != -1) {
+ }
+ if (devinfo.getInEPBulk() != -1) {
dev.readBulk(devinfo.getInEPBulk(), readData,
readData.length, devinfo.getTimeout(), false);
}
@@ -503,18 +537,22 @@ public class DeviceTest {
if (devinfo.getOutEPInt() != -1) {
dev.writeInterrupt(devinfo.getOutEPInt(), testData,
testData.length, devinfo.getTimeout(), false);
- } else if (devinfo.getInEPInt() != -1) {
+ }
+ if (devinfo.getInEPInt() != -1) {
dev.readInterrupt(devinfo.getInEPInt(), readData,
readData.length, devinfo.getTimeout(), false);
}
}
+ if (devinfo.doCompareData()) {
+ compare(testData, readData);
+ }
+ } catch (AssertionError e) {
+ closeOnException();
+ throw e;
} catch (Exception e) {
closeOnException();
throw e;
}
- if (devinfo.doCompareData()) {
- compare(testData, readData);
- }
}
private static void compare(byte[] d1, byte[] d2) {