diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceImpl.java b/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceImpl.java index 92fab64..26403a3 100644 --- a/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceImpl.java +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceImpl.java @@ -175,7 +175,7 @@ public class UsbDeviceImpl implements UsbDevice @Override public String getManufacturerString() throws UsbException, - UnsupportedEncodingException, UsbDisconnectedException + UnsupportedEncodingException { final byte index = this.descriptor.iManufacturer(); if (index == 0) return null; @@ -188,7 +188,8 @@ public class UsbDeviceImpl implements UsbDevice */ @Override - public String getSerialNumberString() throws UsbException + public String getSerialNumberString() throws UsbException, + UnsupportedEncodingException { final byte index = this.descriptor.iSerialNumber(); if (index == 0) return null; @@ -201,7 +202,8 @@ public class UsbDeviceImpl implements UsbDevice */ @Override - public String getProductString() throws UsbException + public String getProductString() throws UsbException, + UnsupportedEncodingException { final byte index = this.descriptor.iProduct(); if (index == 0) return null; @@ -340,9 +342,10 @@ public class UsbDeviceImpl implements UsbDevice */ @Override - public String getString(final byte index) throws UsbException + public String getString(final byte index) throws UsbException, + UnsupportedEncodingException { - return getUsbStringDescriptor(index).toString(); + return getUsbStringDescriptor(index).getString(); } diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceScanner.java b/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceScanner.java new file mode 100644 index 0000000..360426c --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbDeviceScanner.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import static de.ailis.usb4java.USB.USB_CLASS_HUB; +import static de.ailis.usb4java.USB.usb_find_busses; +import static de.ailis.usb4java.USB.usb_find_devices; +import static de.ailis.usb4java.USB.usb_get_busses; +import de.ailis.usb4java.USBLock; +import de.ailis.usb4java.USB_Bus; +import de.ailis.usb4java.USB_Device; +import de.ailis.usb4java.USB_Device_Descriptor; + + +/** + * USB Device scanner. + * + * @author Klaus Reimer (k@ailis.de) + */ + +class UsbDeviceScanner +{ + /** The virtual USB root hub. */ + private final VirtualRootHub rootHub; + + + /** + * Constructor. + * + * @param rootHub + * The virtual USB root hub. + */ + + public UsbDeviceScanner(final VirtualRootHub rootHub) + { + this.rootHub = rootHub; + scan(); + } + + + /** + * Scans for USB device connection changes. + */ + + private void scan() + { + USBLock.acquire(); + try + { + final int bussesChanged = usb_find_busses(); + final int devicesChanged = usb_find_devices(); + if (bussesChanged + devicesChanged == 0) return; + + USB_Bus bus = usb_get_busses(); + while (bus != null) + { + final USB_Device device = bus.root_dev(); + if (device != null) + { + addDevice(this.rootHub, device); + } + bus = bus.next(); + } + } + finally + { + USBLock.release(); + } + } + + + /** + * Adds the specified device to the specified hub and recursively scans for + * more devices. + * + * @param parentHub + * The parent hub + * @param device + * The device to add and scan. + */ + + private void addDevice(final UsbPorts parentHub, final USB_Device device) + { + final USB_Device_Descriptor descriptor = device.descriptor(); + if (descriptor.bDeviceClass() == USB_CLASS_HUB) + { + final UsbHubImpl hub = new UsbHubImpl(device); + parentHub.connectUsbDevice(hub); + for (final USB_Device child : device.children()) + addDevice(hub, child); + } + else + { + final UsbDeviceImpl dev = new UsbDeviceImpl(device); + parentHub.connectUsbDevice(dev); + } + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbHubImpl.java b/src/main/java/de/ailis/usb4java/jsr80/UsbHubImpl.java new file mode 100644 index 0000000..048f2b3 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbHubImpl.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import java.util.List; + +import javax.usb.UsbDevice; +import javax.usb.UsbHub; +import javax.usb.UsbPort; + +import de.ailis.usb4java.USB_Device; + + +/** + * usb4java implementation of JSR-80 UsbHub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public final class UsbHubImpl extends UsbDeviceImpl implements UsbHub, UsbPorts +{ + /** The hub ports. */ + private final UsbPortsImpl ports = new UsbPortsImpl(this); + + + /** + * Constructor. + * + * @param device + * The low-level USB device. + */ + + public UsbHubImpl(final USB_Device device) + { + super(device); + } + + + /** + * @see UsbHub#getNumberOfPorts() + */ + + @Override + public byte getNumberOfPorts() + { + return this.ports.getNumberOfPorts(); + } + + + /** + * @see UsbHub#getUsbPorts() + */ + + @Override + public List getUsbPorts() + { + return this.ports.getUsbPorts(); + } + + + /** + * @see UsbHub#getUsbPort(byte) + */ + + @Override + public UsbPort getUsbPort(final byte number) + { + return this.ports.getUsbPort(number); + } + + + /** + * @see UsbHub#getAttachedUsbDevices() + */ + + @Override + public List getAttachedUsbDevices() + { + return this.ports.getAttachedUsbDevices(); + } + + + /** + * @see UsbHub#isRootUsbHub() + */ + + @Override + public boolean isRootUsbHub() + { + return false; + } + + + /** + * Connects a new device to this hub. + * + * @param device + * The device to add to this hub. + */ + + @Override + public void connectUsbDevice(final UsbDevice device) + { + this.ports.connectUsbDevice(device); + } + + + /** + * Disconnects the specified device from the hub. + * + * @param device + * The device to disconnected from the hub. + */ + + @Override + public void disconnectUsbDevice(final UsbDevice device) + { + this.ports.disconnectUsbDevice(device); + } + + + /** + * @see de.ailis.usb4java.jsr80.UsbDeviceImpl#isUsbHub() + */ + + @Override + public boolean isUsbHub() + { + return true; + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbPortImpl.java b/src/main/java/de/ailis/usb4java/jsr80/UsbPortImpl.java new file mode 100644 index 0000000..32eee22 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbPortImpl.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import javax.usb.UsbDevice; +import javax.usb.UsbHub; +import javax.usb.UsbPort; + + +/** + * usb4java implementation of UsbPort. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public final class UsbPortImpl implements UsbPort +{ + /** The USB hub this port belongs to. */ + private final UsbHub hub; + + /** The port number. */ + private final byte portNumber; + + /** The attached device. */ + private UsbDevice device; + + + /** + * Constructor. + * + * @param hub + * The USB hub this port belongs to. + * @param portNumber + * The port number. + */ + + public UsbPortImpl(final UsbHub hub, final byte portNumber) + { + this.hub = hub; + this.portNumber = portNumber; + } + + + /** + * @see UsbPort#getPortNumber() + */ + + @Override + public final byte getPortNumber() + { + return this.portNumber; + } + + + /** + * @see UsbPort#getUsbHub() + */ + + @Override + public final UsbHub getUsbHub() + { + return this.hub; + } + + + /** + * @see UsbPort#getUsbDevice() + */ + + @Override + public final UsbDevice getUsbDevice() + { + return this.device; + } + + + /** + * @see UsbPort#isUsbDeviceAttached() + */ + + @Override + public final boolean isUsbDeviceAttached() + { + return this.device != null; + } + + + /** + * Connects the specified device to this port. + * + * @param device + * The device to connect. + */ + + final void connectUsbDevice(final UsbDevice device) + { + if (device == null) + throw new IllegalArgumentException("device must not be null"); + if (this.device != null) + throw new IllegalStateException( + "Port already has a connected device"); + this.device = device; + } + + + /** + * Disconnects the currently connected device. + */ + + final void disconnectUsbDevice() + { + if (this.device == null) + throw new IllegalStateException("Port has no connected device"); + this.device = null; + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbPorts.java b/src/main/java/de/ailis/usb4java/jsr80/UsbPorts.java new file mode 100644 index 0000000..6a8c713 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbPorts.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import java.util.List; + +import javax.usb.UsbDevice; +import javax.usb.UsbPort; + + +/** + * A list of USB ports. + * + * @author Klaus Reimer (k@ailis.de) + */ + +interface UsbPorts +{ + /** + * Returns the number of ports. + * + * @return The number of ports. + */ + + byte getNumberOfPorts(); + + + /** + * Returns the ports. + * + * @return The ports. + */ + + List getUsbPorts(); + + + /** + * Returns the USB port with the specified port number. + * + * @param number + * The USB port number. + * @return The USB port or null if no such port. + */ + + UsbPort getUsbPort(final byte number); + + + /** + * Returns the attached USB devices. + * + * @return The attached USB devices. + */ + + List getAttachedUsbDevices(); + + + /** + * Connects a new device to this hub. + * + * @param device + * The device to add to this hub. + */ + + void connectUsbDevice(final UsbDevice device); + + + /** + * Disconnects the specified device from the hub. + * + * @param device + * The device to disconnected from the hub. + */ + + void disconnectUsbDevice(final UsbDevice device); +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbPortsImpl.java b/src/main/java/de/ailis/usb4java/jsr80/UsbPortsImpl.java new file mode 100644 index 0000000..9ccb64a --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbPortsImpl.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.usb.UsbDevice; +import javax.usb.UsbHub; +import javax.usb.UsbPort; + + +/** + * A list of USB ports. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class UsbPortsImpl implements UsbPorts +{ + /** The hub ports. */ + private final List ports = new ArrayList(); + + /** The hub these ports belong to. */ + private final UsbHub hub; + + + /** + * Constructor. + * + * @param hub + * The hub the port belongs to. + */ + + UsbPortsImpl(final UsbHub hub) + { + this.hub = hub; + addPort(); + } + + + /** + * Adds a new port and returns it. + * + * @return The added port. + */ + + private UsbPort addPort() + { + final byte portNo = (byte) (this.ports.size() + 1); + final UsbPortImpl port = new UsbPortImpl(this.hub, portNo); + this.ports.add(port); + return port; + } + + + /** + * Returns the first free port or adds a new one if no free port was found. + * + * @return The first free port. + */ + + private UsbPort getFreePort() + { + for (final UsbPort port : this.ports) + { + if (!port.isUsbDeviceAttached()) return port; + } + return addPort(); + } + + + /** + * Returns the number of ports. + * + * @return The number of ports. + */ + + @Override + public byte getNumberOfPorts() + { + return (byte) this.ports.size(); + } + + + /** + * Returns the ports. + * + * @return The ports. + */ + + @Override + public List getUsbPorts() + { + return Collections.unmodifiableList(this.ports); + } + + + /** + * Returns the USB port with the specified port number. + * + * @param number + * The USB port number. + * @return The USB port or null if no such port. + */ + + @Override + public UsbPort getUsbPort(final byte number) + { + final int index = (number & 0xff) - 1; + if (index < 0 || index >= this.ports.size()) return null; + return this.ports.get(index); + } + + + /** + * Returns the attached USB devices. + * + * @return The attached USB devices. + */ + + @Override + public List getAttachedUsbDevices() + { + final List devices = new ArrayList(); + synchronized (this.ports) + { + for (final UsbPort port : this.ports) + { + if (port.isUsbDeviceAttached()) + { + devices.add(port.getUsbDevice()); + } + } + } + return Collections.unmodifiableList(devices); + } + + + /** + * Connects a new device to this hub. + * + * @param device + * The device to add to this hub. + */ + + @Override + public void connectUsbDevice(final UsbDevice device) + { + synchronized (this.ports) + { + final UsbPortImpl port = (UsbPortImpl) getFreePort(); + port.connectUsbDevice(device); + } + } + + + /** + * Disconnects the specified device from the hub. + * + * @param device + * The device to disconnected from the hub. + */ + + @Override + public void disconnectUsbDevice(final UsbDevice device) + { + synchronized (this.ports) + { + for (final UsbPort port : this.ports) + { + if (device.equals(port.getUsbDevice())) + { + ((UsbPortImpl) port).disconnectUsbDevice(); + } + } + } + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/UsbServicesImpl.java b/src/main/java/de/ailis/usb4java/jsr80/UsbServicesImpl.java index 91306ee..7c0c65a 100644 --- a/src/main/java/de/ailis/usb4java/jsr80/UsbServicesImpl.java +++ b/src/main/java/de/ailis/usb4java/jsr80/UsbServicesImpl.java @@ -5,6 +5,8 @@ package de.ailis.usb4java.jsr80; +import static de.ailis.usb4java.USB.usb_init; + import javax.usb.UsbException; import javax.usb.UsbHub; import javax.usb.UsbServices; @@ -31,16 +33,33 @@ public final class UsbServicesImpl implements UsbServices /** The USB services listeners. */ private final UsbServicesListenerList listeners = new UsbServicesListenerList(); + /** The virtual USB root hub. */ + private final VirtualRootHub rootHub; + + /** The USB device scanner. */ + private final UsbDeviceScanner deviceScanner; + + + /** + * Constructor. + */ + + public UsbServicesImpl() + { + usb_init(); + this.rootHub = new VirtualRootHub(); + this.deviceScanner = new UsbDeviceScanner(this.rootHub); + } + /** * @see UsbServices#getRootUsbHub() */ @Override - public final UsbHub getRootUsbHub() throws UsbException, SecurityException + public UsbHub getRootUsbHub() throws UsbException, SecurityException { - // TODO Implement me - throw new UnsupportedOperationException(); + return this.rootHub; } @@ -49,7 +68,7 @@ public final class UsbServicesImpl implements UsbServices */ @Override - public final void addUsbServicesListener(final UsbServicesListener listener) + public void addUsbServicesListener(final UsbServicesListener listener) { this.listeners.add(listener); } @@ -60,7 +79,7 @@ public final class UsbServicesImpl implements UsbServices */ @Override - public final void removeUsbServicesListener(final UsbServicesListener listener) + public void removeUsbServicesListener(final UsbServicesListener listener) { this.listeners.remove(listener); } @@ -71,7 +90,7 @@ public final class UsbServicesImpl implements UsbServices */ @Override - public final String getApiVersion() + public String getApiVersion() { return API_VERSION; } @@ -82,7 +101,7 @@ public final class UsbServicesImpl implements UsbServices */ @Override - public final String getImpVersion() + public String getImpVersion() { return IMP_VERSION; } @@ -93,7 +112,7 @@ public final class UsbServicesImpl implements UsbServices */ @Override - public final String getImpDescription() + public String getImpDescription() { return IMP_DESCRIPTION; } diff --git a/src/main/java/de/ailis/usb4java/jsr80/VirtualRootHub.java b/src/main/java/de/ailis/usb4java/jsr80/VirtualRootHub.java new file mode 100644 index 0000000..34456bf --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/VirtualRootHub.java @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import javax.usb.UsbConfiguration; +import javax.usb.UsbConst; +import javax.usb.UsbControlIrp; +import javax.usb.UsbDevice; +import javax.usb.UsbDeviceDescriptor; +import javax.usb.UsbDisconnectedException; +import javax.usb.UsbException; +import javax.usb.UsbHub; +import javax.usb.UsbPort; +import javax.usb.UsbStringDescriptor; +import javax.usb.event.UsbDeviceListener; +import javax.usb.util.DefaultUsbControlIrp; + + +/** + * The virtual USB root hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class VirtualRootHub implements UsbHub, UsbPorts +{ + /** The manufacturer string. */ + private static final String MANUFACTURER = "de.ailis.usb4java"; + + /** The manufacturer string. */ + private static final String PRODUCT = "Virtual Root Hub"; + + /** The serial number. */ + private static final String SERIAL_NUMBER = "0.1.12-1"; + + /** The configurations. */ + private final List configurations = + new ArrayList(1); + + /** The device descriptor. */ + private final UsbDeviceDescriptor descriptor = new VirtualUsbDeviceDescriptor(); + + /** The device listeners. */ + private final UsbDeviceListenerList listeners = new UsbDeviceListenerList(); + + /** The hub ports. */ + private final UsbPortsImpl ports = new UsbPortsImpl(this); + + + /** + * Constructor. + */ + + VirtualRootHub() + { + this.configurations.add(new VirtualUsbConfiguration(this)); + } + + + /** + * @see UsbDevice#getParentUsbPort() + */ + + @Override + public UsbPort getParentUsbPort() throws UsbDisconnectedException + { + return null; + } + + + /** + * @see UsbDevice#isUsbHub() + */ + + @Override + public boolean isUsbHub() + { + return true; + } + + + /** + * @see UsbDevice#getManufacturerString() + */ + + @Override + public String getManufacturerString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + return MANUFACTURER; + } + + + /** + * @see UsbDevice#getSerialNumberString() + */ + + @Override + public String getSerialNumberString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + return SERIAL_NUMBER; + } + + + /** + * @see UsbDevice#getProductString() + */ + + @Override + public String getProductString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + return PRODUCT; + } + + + /** + * @see UsbDevice#getSpeed() + */ + + @Override + public Object getSpeed() + { + return UsbConst.DEVICE_SPEED_UNKNOWN; + } + + + /** + * @see UsbDevice#getUsbConfigurations() + */ + + @Override + public List getUsbConfigurations() + { + return this.configurations; + } + + + /** + * @see UsbDevice#getUsbConfiguration(byte) + */ + + @Override + public UsbConfiguration getUsbConfiguration(final byte number) + { + if (number != 1) return null; + return this.configurations.get(0); + } + + + /** + * @see UsbDevice#containsUsbConfiguration(byte) + */ + + @Override + public boolean containsUsbConfiguration(final byte number) + { + return number == 1; + } + + + /** + * @see UsbDevice#getActiveUsbConfigurationNumber() + */ + + @Override + public byte getActiveUsbConfigurationNumber() + { + return 1; + } + + + /** + * @see UsbDevice#getActiveUsbConfiguration() + */ + + @Override + public UsbConfiguration getActiveUsbConfiguration() + { + return this.configurations.get(0); + } + + + /** + * @see UsbDevice#isConfigured() + */ + + @Override + public boolean isConfigured() + { + return true; + } + + + /** + * @see UsbDevice#getUsbDeviceDescriptor() + */ + + @Override + public UsbDeviceDescriptor getUsbDeviceDescriptor() + { + return this.descriptor; + } + + + /** + * @see UsbDevice#getUsbStringDescriptor(byte) + */ + + @Override + public UsbStringDescriptor getUsbStringDescriptor(final byte index) + throws UsbException, UsbDisconnectedException + { + throw new UsbException( + "Can't get USB string descriptor from virtual device"); + } + + + /** + * @see UsbDevice#getString(byte) + */ + + @Override + public String getString(final byte index) throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + throw new UsbException("Can't get string from virtual device"); + } + + + /** + * @see UsbDevice#syncSubmit(javax.usb.UsbControlIrp) + */ + + @Override + public void syncSubmit(final UsbControlIrp irp) throws UsbException, + IllegalArgumentException, UsbDisconnectedException + { + throw new UsbException("Can't syncSubmit on virtual device"); + } + + + /** + * @see UsbDevice#asyncSubmit(javax.usb.UsbControlIrp) + */ + + @Override + public void asyncSubmit(final UsbControlIrp irp) throws UsbException, + IllegalArgumentException, UsbDisconnectedException + { + throw new UsbException("Can't asyncSubmit on virtual device"); + } + + + /** + * @see UsbDevice#syncSubmit(java.util.List) + */ + + @Override + public void syncSubmit(@SuppressWarnings("rawtypes") final List list) + throws UsbException, IllegalArgumentException, UsbDisconnectedException + { + throw new UsbException("Can't syncSubmit on virtual device"); + } + + + /** + * @see UsbDevice#asyncSubmit(java.util.List) + */ + + @Override + public void asyncSubmit(@SuppressWarnings("rawtypes") final List list) + throws UsbException, + IllegalArgumentException, UsbDisconnectedException + { + throw new UsbException("Can't asyncSubmit on virtual device"); + } + + + /** + * @see UsbDevice#createUsbControlIrp(byte, byte, short, short) + */ + + @Override + public UsbControlIrp createUsbControlIrp(final byte bmRequestType, + final byte bRequest, + final short wValue, final short wIndex) + { + return new DefaultUsbControlIrp(bmRequestType, bRequest, wValue, wIndex); + } + + + /** + * @see UsbDevice#addUsbDeviceListener(javax.usb.event.UsbDeviceListener) + */ + + @Override + public void addUsbDeviceListener(final UsbDeviceListener listener) + { + this.listeners.add(listener); + } + + + /** + * @see UsbDevice#removeUsbDeviceListener(javax.usb.event.UsbDeviceListener) + */ + + @Override + public void removeUsbDeviceListener(final UsbDeviceListener listener) + { + this.listeners.remove(listener); + } + + + /** + * @see javax.usb.UsbHub#getNumberOfPorts() + */ + + @Override + public byte getNumberOfPorts() + { + return this.ports.getNumberOfPorts(); + } + + + /** + * @see javax.usb.UsbHub#getUsbPorts() + */ + + @Override + public List getUsbPorts() + { + return this.ports.getUsbPorts(); + } + + + /** + * @see javax.usb.UsbHub#getUsbPort(byte) + */ + + @Override + public UsbPort getUsbPort(final byte number) + { + return this.ports.getUsbPort(number); + } + + + /** + * @see javax.usb.UsbHub#getAttachedUsbDevices() + */ + + @Override + public List getAttachedUsbDevices() + { + return this.ports.getAttachedUsbDevices(); + } + + + /** + * @see javax.usb.UsbHub#isRootUsbHub() + */ + + @Override + public boolean isRootUsbHub() + { + return true; + } + + + /** + * @see UsbPorts#connectUsbDevice(UsbDevice) + */ + + @Override + public void connectUsbDevice(final UsbDevice device) + { + this.ports.connectUsbDevice(device); + } + + + /** + * @see UsbPorts#disconnectUsbDevice(UsbDevice) + */ + + @Override + public void disconnectUsbDevice(final UsbDevice device) + { + this.ports.disconnectUsbDevice(device); + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbConfiguration.java b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbConfiguration.java new file mode 100644 index 0000000..8a503a8 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbConfiguration.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import javax.usb.UsbConfiguration; +import javax.usb.UsbConfigurationDescriptor; +import javax.usb.UsbDevice; +import javax.usb.UsbDisconnectedException; +import javax.usb.UsbException; +import javax.usb.UsbInterface; + + +/** + * Virtual USB configuration used by the virtual USB root hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class VirtualUsbConfiguration implements UsbConfiguration +{ + /** The virtual interfaces. */ + private final List interfaces = new ArrayList(); + + /** The device this configuration belongs to. */ + private final UsbDevice device; + + /** The USB configuration descriptor. */ + private final UsbConfigurationDescriptor descriptor = new VirtualUsbConfigurationDescriptor(); + + + /** + * Constructor. + * + * @param device + * The device this configuration belongs to. + */ + + VirtualUsbConfiguration(final UsbDevice device) + { + this.device = device; + this.interfaces.add(new VirtualUsbInterface(this)); + } + + + /** + * @see UsbConfiguration#isActive() + */ + + @Override + public boolean isActive() + { + return true; + } + + + /** + * @see UsbConfiguration#getUsbInterfaces() + */ + + @Override + public List getUsbInterfaces() + { + return this.interfaces; + } + + + /** + * @see UsbConfiguration#getUsbInterface(byte) + */ + + @Override + public UsbInterface getUsbInterface(final byte number) + { + if (number != 0) return null; + return this.interfaces.get(0); + } + + + /** + * @see UsbConfiguration#containsUsbInterface(byte) + */ + + @Override + public boolean containsUsbInterface(final byte number) + { + return number == 0; + } + + + /** + * @see javax.usb.UsbConfiguration#getUsbDevice() + */ + + @Override + public UsbDevice getUsbDevice() + { + return this.device; + } + + + /** + * @see javax.usb.UsbConfiguration#getUsbConfigurationDescriptor() + */ + + @Override + public UsbConfigurationDescriptor getUsbConfigurationDescriptor() + { + return this.descriptor; + } + + /** + * @see javax.usb.UsbConfiguration#getConfigurationString() + */ + + @Override + public String getConfigurationString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + return null; + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbConfigurationDescriptor.java b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbConfigurationDescriptor.java new file mode 100644 index 0000000..9165fc3 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbConfigurationDescriptor.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import javax.usb.UsbConfigurationDescriptor; +import javax.usb.UsbConst; +import javax.usb.UsbDescriptor; + + +/** + * The virtual USB configuration descriptor used by the virtual USB root hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class VirtualUsbConfigurationDescriptor implements + UsbConfigurationDescriptor +{ + /** + * @see UsbDescriptor#bLength() + */ + + @Override + public byte bLength() + { + return UsbConst.DESCRIPTOR_MIN_LENGTH_CONFIGURATION; + } + + + /** + * @see UsbDescriptor#bDescriptorType() + */ + + @Override + public byte bDescriptorType() + { + return UsbConst.DESCRIPTOR_TYPE_CONFIGURATION; + } + + + /** + * @see UsbConfigurationDescriptor#wTotalLength() + */ + + @Override + public short wTotalLength() + { + return UsbConst.DESCRIPTOR_MIN_LENGTH_CONFIGURATION + UsbConst.DESCRIPTOR_MIN_LENGTH_INTERFACE; + } + + + /** + * @see UsbConfigurationDescriptor#bNumInterfaces() + */ + + @Override + public byte bNumInterfaces() + { + return 1; + } + + + /** + * @see UsbConfigurationDescriptor#bConfigurationValue() + */ + + @Override + public byte bConfigurationValue() + { + return 1; + } + + + /** + * @see UsbConfigurationDescriptor#iConfiguration() + */ + + @Override + public byte iConfiguration() + { + return 0; + } + + + /** + * @see UsbConfigurationDescriptor#bmAttributes() + */ + + @Override + public byte bmAttributes() + { + return (byte) 0x80; + } + + + /** + * @see UsbConfigurationDescriptor#bMaxPower() + */ + + @Override + public byte bMaxPower() + { + return 0; + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbDeviceDescriptor.java b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbDeviceDescriptor.java new file mode 100644 index 0000000..ea07f43 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbDeviceDescriptor.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import javax.usb.UsbConst; +import javax.usb.UsbDescriptor; +import javax.usb.UsbDeviceDescriptor; + + +/** + * Virtual USB device descriptor used by the virtual USB root hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class VirtualUsbDeviceDescriptor implements UsbDeviceDescriptor +{ + /** + * @see UsbDescriptor#bLength() + */ + + @Override + public byte bLength() + { + return UsbConst.DESCRIPTOR_MIN_LENGTH_DEVICE; + } + + + /** + * @see UsbDescriptor#bDescriptorType() + */ + + @Override + public byte bDescriptorType() + { + return UsbConst.DESCRIPTOR_TYPE_DEVICE; + } + + + /** + * @see UsbDeviceDescriptor#bcdUSB() + */ + + @Override + public short bcdUSB() + { + return 0x101; + } + + + /** + * @see UsbDeviceDescriptor#bDeviceClass() + */ + + @Override + public byte bDeviceClass() + { + return UsbConst.HUB_CLASSCODE; + } + + + /** + * @see UsbDeviceDescriptor#bDeviceSubClass() + */ + + @Override + public byte bDeviceSubClass() + { + return 0; + } + + + /** + * @see UsbDeviceDescriptor#bDeviceProtocol() + */ + + @Override + public byte bDeviceProtocol() + { + return 0; + } + + + /** + * @see UsbDeviceDescriptor#bMaxPacketSize0() + */ + + @Override + public byte bMaxPacketSize0() + { + return 8; + } + + + /** + * @see UsbDeviceDescriptor#idVendor() + */ + + @Override + public short idVendor() + { + return (short) 0xffff; + } + + + /** + * @see UsbDeviceDescriptor#idProduct() + */ + + @Override + public short idProduct() + { + return (short) 0xffff; + } + + + /** + * @see UsbDeviceDescriptor#bcdDevice() + */ + + @Override + public short bcdDevice() + { + return 0; + } + + + /** + * @see UsbDeviceDescriptor#iManufacturer() + */ + + @Override + public byte iManufacturer() + { + return 1; + } + + + /** + * @see UsbDeviceDescriptor#iProduct() + */ + + @Override + public byte iProduct() + { + return 2; + } + + + /** + * @see UsbDeviceDescriptor#iSerialNumber() + */ + + @Override + public byte iSerialNumber() + { + return 3; + } + + + /** + * @see UsbDeviceDescriptor#bNumConfigurations() + */ + + @Override + public byte bNumConfigurations() + { + return 1; + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbInterface.java b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbInterface.java new file mode 100644 index 0000000..af8ee20 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbInterface.java @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import javax.usb.UsbClaimException; +import javax.usb.UsbConfiguration; +import javax.usb.UsbDisconnectedException; +import javax.usb.UsbEndpoint; +import javax.usb.UsbException; +import javax.usb.UsbInterface; +import javax.usb.UsbInterfaceDescriptor; +import javax.usb.UsbInterfacePolicy; +import javax.usb.UsbNotActiveException; + + +/** + * The virtual USB interfaces used by the virtual USB root hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class VirtualUsbInterface implements UsbInterface +{ + /** The list of endpoints. */ + private final List endpoints = new ArrayList(0); + + /** The list of alternate settings. */ + private final List settings = new ArrayList(0); + + /** The USB configuration. */ + private final UsbConfiguration configuration; + + /** The interface descriptor. */ + private final UsbInterfaceDescriptor descriptor = new VirtualUsbInterfaceDescriptor(); + + + /** + * Constructor + * + * @param configuration + * The USB configuration. + */ + + public VirtualUsbInterface(final UsbConfiguration configuration) + { + this.configuration = configuration; + } + + /** + * @see UsbInterface#claim() + */ + + @Override + public void claim() throws UsbClaimException, UsbException, + UsbNotActiveException, UsbDisconnectedException + { + throw new UsbException("Virtual interfaces can't be claimed"); + } + + + /** + * @see UsbInterface#claim(UsbInterfacePolicy) + */ + + @Override + public void claim(final UsbInterfacePolicy policy) + throws UsbClaimException, + UsbException, UsbNotActiveException, UsbDisconnectedException + { + throw new UsbException("Virtual interfaces can't be claimed"); + } + + + /** + * @see UsbInterface#release() + */ + + @Override + public void release() throws UsbClaimException, UsbException, + UsbNotActiveException, UsbDisconnectedException + { + throw new UsbException("Virtual interfaces can't be released"); + } + + + /** + * @see UsbInterface#isClaimed() + */ + + @Override + public boolean isClaimed() + { + return true; + } + + + /** + * @see UsbInterface#isActive() + */ + + @Override + public boolean isActive() + { + return true; + } + + + /** + * @see UsbInterface#getNumSettings() + */ + + @Override + public int getNumSettings() + { + return 0; + } + + + /** + * @see UsbInterface#getActiveSettingNumber() + */ + + @Override + public byte getActiveSettingNumber() throws UsbNotActiveException + { + return 0; + } + + + /** + * @see UsbInterface#getActiveSetting() + */ + + @Override + public UsbInterface getActiveSetting() throws UsbNotActiveException + { + return this; + } + + + /** + * @see UsbInterface#getSetting(byte) + */ + + @Override + public UsbInterface getSetting(final byte number) + { + return this; + } + + + /** + * @see UsbInterface#containsSetting(byte) + */ + + @Override + public boolean containsSetting(final byte number) + { + return false; + } + + + /** + * @see UsbInterface#getSettings() + */ + + @Override + public List getSettings() + { + return this.settings; + } + + + /** + * @see UsbInterface#getUsbEndpoints() + */ + + @Override + public List getUsbEndpoints() + { + return this.endpoints; + } + + + /** + * @see UsbInterface#getUsbEndpoint(byte) + */ + + @Override + public UsbEndpoint getUsbEndpoint(final byte address) + { + return null; + } + + + /** + * @see UsbInterface#containsUsbEndpoint(byte) + */ + + @Override + public boolean containsUsbEndpoint(final byte address) + { + return false; + } + + + /** + * @see UsbInterface#getUsbConfiguration() + */ + + @Override + public UsbConfiguration getUsbConfiguration() + { + return this.configuration; + } + + + /** + * @see UsbInterface#getUsbInterfaceDescriptor() + */ + + @Override + public UsbInterfaceDescriptor getUsbInterfaceDescriptor() + { + return this.descriptor; + } + + + /** + * @see UsbInterface#getInterfaceString() + */ + + @Override + public String getInterfaceString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + return null; + } +} diff --git a/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbInterfaceDescriptor.java b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbInterfaceDescriptor.java new file mode 100644 index 0000000..462fd9c --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jsr80/VirtualUsbInterfaceDescriptor.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jsr80; + +import javax.usb.UsbConst; +import javax.usb.UsbDescriptor; +import javax.usb.UsbInterfaceDescriptor; + + +/** + * Virtual USB interface descriptor used by the virtual USB root hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +final class VirtualUsbInterfaceDescriptor implements UsbInterfaceDescriptor +{ + /** + * @see UsbDescriptor#bLength() + */ + + @Override + public byte bLength() + { + return UsbConst.DESCRIPTOR_MIN_LENGTH_INTERFACE; + } + + + /** + * @see UsbDescriptor#bDescriptorType() + */ + + @Override + public byte bDescriptorType() + { + return UsbConst.DESCRIPTOR_TYPE_INTERFACE; + } + + + /** + * @see UsbInterfaceDescriptor#bInterfaceNumber() + */ + + @Override + public byte bInterfaceNumber() + { + return 0; + } + + + /** + * @see UsbInterfaceDescriptor#bAlternateSetting() + */ + + @Override + public byte bAlternateSetting() + { + return 0; + } + + + /** + * @see UsbInterfaceDescriptor#bNumEndpoints() + */ + + @Override + public byte bNumEndpoints() + { + return 0; + } + + + /** + * @see UsbInterfaceDescriptor#bInterfaceClass() + */ + + @Override + public byte bInterfaceClass() + { + return UsbConst.HUB_CLASSCODE; + } + + + /** + * @see UsbInterfaceDescriptor#bInterfaceSubClass() + */ + + @Override + public byte bInterfaceSubClass() + { + return 0; + } + + /** + * @see UsbInterfaceDescriptor#bInterfaceProtocol() + */ + + @Override + public byte bInterfaceProtocol() + { + return 0; + } + + + /** + * @see UsbInterfaceDescriptor#iInterface() + */ + + @Override + public byte iInterface() + { + return 0; + } +} diff --git a/src/test/java/Test.java b/src/test/java/Test.java new file mode 100644 index 0000000..d23a3df --- /dev/null +++ b/src/test/java/Test.java @@ -0,0 +1,52 @@ +import java.util.List; + +import javax.usb.UsbDevice; +import javax.usb.UsbHostManager; +import javax.usb.UsbHub; +import javax.usb.UsbPort; +import javax.usb.UsbServices; + +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + + +/** + * Test + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class Test +{ + public static void dumpHub(final UsbHub rootHub, final String indent) throws Exception + { + final List ports = rootHub.getUsbPorts(); + for (final UsbPort port: ports) + { + System.out.print(indent); + System.out.format(" \\__%d: ", port.getPortNumber()); + if (port.isUsbDeviceAttached()) + { + final UsbDevice device = port.getUsbDevice(); + System.out.println(device.getProductString()); + if (device.isUsbHub()) + { + final UsbHub hub = (UsbHub) device; + dumpHub(hub, indent + " "); + } + } + else System.out.println("No device attached"); + } + } + + public static void main(final String[] args) throws Exception + { + final UsbServices services = UsbHostManager.getUsbServices(); + final UsbHub rootHub = services.getRootUsbHub(); + System.out.println(rootHub.getProductString()); + dumpHub(rootHub, ""); + } +} + diff --git a/src/test/resources/javax.usb.properties b/src/test/resources/javax.usb.properties new file mode 100644 index 0000000..e357bef --- /dev/null +++ b/src/test/resources/javax.usb.properties @@ -0,0 +1 @@ +javax.usb.services = de.ailis.usb4java.jsr80.UsbServicesImpl