package cnadeau.driver;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import javax.usb.UsbConfiguration;
import javax.usb.UsbDevice;
import javax.usb.UsbException;
import javax.usb.UsbHostManager;
import javax.usb.UsbHub;
import javax.usb.UsbInterface;
import javax.usb.UsbPort;
import org.apache.log4j.Logger;
import cnadeau.driver.exceptions.CM19AException;
import cnadeau.enums.AvailableLoggers;
public class CM19AUsbDeviceLookupImpl implements CM19AUsbDeviceLookup
{
private final Logger logger = Logger.getLogger(AvailableLoggers.Driver.toString());
/**
* Find the CM19a device. Uses the isDevice() method to find out whether the device has been found.
*
* @param UsbHub
* A USB hub. Initially made with the Virtual Root USB hub.
* @return The CM19a device or null if it wasn't found
* @author Jan Roberts
*
*/
private UsbDevice findDevice(UsbHub hub)
{
UsbDevice cm19a = null;
Iterator iterator = hub.getUsbPorts().iterator();
while (iterator.hasNext())
{
UsbPort port = (UsbPort) iterator.next();
if (port.isUsbDeviceAttached())
{
UsbDevice device = port.getUsbDevice();
/* Is this the device? If so, quit looking */
if (device.isUsbHub())
{
cm19a = findDevice((UsbHub) device);
if (isCM19ADevice(cm19a))
{
break;
}
}
else if (isCM19ADevice(device))
{
cm19a = device;
break;
/*
* If this is a hub, recurse; if the CM19a is found, return it
*/
}
}
}
return cm19a;
}
/**
* Test for whether or not the device being examined is the CM19a. Assumes that the vendor id and the product id will uniquely identify it.
*
* @param device
* A UsbDevice
* @return true if device is the CM19a, false otherwise
* @author Jan Roberts
*/
private boolean isCM19ADevice(UsbDevice device)
{
final short vendorId = (short) 0x0bc7;
final short productId = (short) 0x0002;
boolean isDevice = false;
if (device == null)
return false;
if (device.getUsbDeviceDescriptor().idVendor() == vendorId && device.getUsbDeviceDescriptor().idProduct() == productId)
{
logger.debug("CM19A found on port " + device.getParentUsbPort().getPortNumber());
isDevice = true;
}
return isDevice;
}
/**
* Starts the user space driver. The CM19a has two endpoints, one for communication from the host to the CM19a and the other for communication from the
* CM19a to the host.
*
* @author Jan Roberts
*/
@Override
public UsbInterfaceInfos findCM19ADevice() throws CM19AException, UsbException, UnsupportedEncodingException
{
UsbHub virtualRootUsbHub = UsbHostManager.getUsbServices().getRootUsbHub();
if (virtualRootUsbHub == null)
{
throw new CM19AException("No virtual root usb hub found");
}
/* Find the attached CM19a */
UsbDevice cm19a = findDevice(virtualRootUsbHub);
if (cm19a == null)
{
throw new CM19AException("No CM19a found; /dev/bus/usb permissions problem?");
}
if (logger.isDebugEnabled())
{
StringBuilder builder = new StringBuilder("Device found and configured is ");
if (!cm19a.isConfigured())
{
builder.append("not");
}
builder.append(" configured");
logger.debug(builder.toString());
}
UsbConfiguration config = cm19a.getActiveUsbConfiguration();
if (config == null)
{
throw new CM19AException("No active configuration found");
}
/* Get the first interface, there should only be one */
UsbInterface usbInterface = (UsbInterface) config.getUsbInterfaces().get(0);
logger.debug("Got device; Manufacturer is " + cm19a.getManufacturerString());
logger.debug("Got interface; Active is " + usbInterface.isActive() + " Claimed is " + usbInterface.isClaimed());
try
{
usbInterface.claim();
logger.debug("Interface has been claimed");
}
catch (UsbException ue)
{
throw new CM19AException("Couldn't claim interface. " + "Message is " + ue.getMessage());
}
return new UsbInterfaceInfos(usbInterface);
}
}