From c9e90b2b642705d0c53a0b675baa054cd07b2866 Mon Sep 17 00:00:00 2001 From: spandi Date: Sun, 8 Jun 2008 14:35:18 +0000 Subject: [PATCH] new parameter added to be able to open a specific device based on the filename if there are multiple devices with the same vendor/product id procedure added to get Usb_Bus object from USB class git-svn-id: https://svn.code.sf.net/p/libusbjava/code/trunk@268 94ad28fe-ef68-46b1-9651-e7ae4fcf1c4c --- java/src/ch/ntb/usb/Device.java | 93 +++++++++++++------- java/src/ch/ntb/usb/USB.java | 69 +++++++++++++-- java/src/ch/ntb/usb/Utils.java | 26 ++++-- java/test/ch/ntb/usb/test/DeviceTest.java | 102 +++++++++++++++------- 4 files changed, 213 insertions(+), 77 deletions(-) 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) {