mirror of https://github.com/rusefi/usb4java.git
Finished pipe implementation.
This commit is contained in:
parent
cf4dd66d31
commit
8563bd97d5
|
@ -568,11 +568,21 @@ abstract class AbstractDevice implements UsbDevice
|
||||||
@Override
|
@Override
|
||||||
public final void syncSubmit(final UsbControlIrp irp) throws UsbException
|
public final void syncSubmit(final UsbControlIrp irp) throws UsbException
|
||||||
{
|
{
|
||||||
|
if( (irp.bRequest() == UsbConst.REQUEST_SET_CONFIGURATION) && (irp.bmRequestType() ==0) )
|
||||||
|
{
|
||||||
|
final int result2 = usb_set_configuration(open(), irp.wValue());
|
||||||
|
if (result2 < 0) throw new UsbException(usb_strerror());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
USBLock.acquire();
|
USBLock.acquire();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final ByteBuffer buffer = ByteBuffer
|
final ByteBuffer buffer = ByteBuffer
|
||||||
.allocateDirect(irp.getLength());
|
.allocateDirect(irp.getLength());
|
||||||
|
buffer.put(irp.getData(), 0, irp.getLength());
|
||||||
|
buffer.rewind();
|
||||||
final USB_Dev_Handle handle = open();
|
final USB_Dev_Handle handle = open();
|
||||||
final int len = usb_control_msg(handle, irp.bmRequestType(),
|
final int len = usb_control_msg(handle, irp.bmRequestType(),
|
||||||
irp.bRequest(),
|
irp.bRequest(),
|
||||||
|
@ -580,11 +590,13 @@ abstract class AbstractDevice implements UsbDevice
|
||||||
if (len < 0) throw new UsbException(usb_strerror());
|
if (len < 0) throw new UsbException(usb_strerror());
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
buffer.get(irp.getData(), 0, len);
|
buffer.get(irp.getData(), 0, len);
|
||||||
|
irp.setActualLength(len);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
USBLock.release();
|
USBLock.release();
|
||||||
}
|
}
|
||||||
|
irp.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||||
|
* See LICENSE.txt for licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.ailis.usb4java.jsr80;
|
||||||
|
|
||||||
|
import static de.ailis.usb4java.USB.usb_strerror;
|
||||||
|
|
||||||
|
import javax.usb.UsbException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* libusb-specific UsbException.
|
||||||
|
*
|
||||||
|
* @author Klaus Reimer (k@ailis.de)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class LibUsbException extends UsbException
|
||||||
|
{
|
||||||
|
/** Serial version UID. */
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** The error code. */
|
||||||
|
private final int errorCode;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param errorCode
|
||||||
|
* The error code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public LibUsbException(final int errorCode)
|
||||||
|
{
|
||||||
|
super(String.format("USB error %i: %s", errorCode, usb_strerror()));
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the error code.
|
||||||
|
*
|
||||||
|
* @return The error code
|
||||||
|
*/
|
||||||
|
|
||||||
|
public int getErrorCode()
|
||||||
|
{
|
||||||
|
return this.errorCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,339 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||||
|
* See LICENSE.txt for licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.ailis.usb4java.jsr80;
|
||||||
|
|
||||||
|
import static de.ailis.usb4java.USB.usb_bulk_read;
|
||||||
|
import static de.ailis.usb4java.USB.usb_bulk_write;
|
||||||
|
import static de.ailis.usb4java.USB.usb_interrupt_read;
|
||||||
|
import static de.ailis.usb4java.USB.usb_interrupt_write;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import javax.usb.UsbConst;
|
||||||
|
import javax.usb.UsbEndpoint;
|
||||||
|
import javax.usb.UsbEndpointDescriptor;
|
||||||
|
import javax.usb.UsbException;
|
||||||
|
import javax.usb.UsbIrp;
|
||||||
|
|
||||||
|
import de.ailis.usb4java.USB_Dev_Handle;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This thread is responsible for processing the request packet queue of a pipe.
|
||||||
|
* The thread is created and started when a pipe is opened and is stopped when
|
||||||
|
* the pipe is closed.
|
||||||
|
*
|
||||||
|
* @author Klaus Reimer (k@ailis.de)
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PipeQueueProcessor extends Thread
|
||||||
|
{
|
||||||
|
/** The pipe. */
|
||||||
|
private final UsbPipeImpl pipe;
|
||||||
|
|
||||||
|
/** If thread should stop. */
|
||||||
|
private boolean stop;
|
||||||
|
|
||||||
|
/** If thread is running or not. */
|
||||||
|
private boolean running;
|
||||||
|
|
||||||
|
/** If packets are currently processed. */
|
||||||
|
private boolean processing;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param pipe
|
||||||
|
* The pipe.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public PipeQueueProcessor(final UsbPipeImpl pipe)
|
||||||
|
{
|
||||||
|
this.pipe = pipe;
|
||||||
|
setDaemon(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the thread.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
this.stop = true;
|
||||||
|
notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the thread and waits until it has really stopped.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void shutdownAndWait()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
while (isRunning())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
catch (final InterruptedException e)
|
||||||
|
{
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the USB endpoint descriptor.
|
||||||
|
*
|
||||||
|
* @return The USB endpoint descriptor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private UsbEndpointDescriptor getEndpointDescriptor()
|
||||||
|
{
|
||||||
|
return this.pipe.getUsbEndpoint().getUsbEndpointDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the USB device.
|
||||||
|
*
|
||||||
|
* @return The USB device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private AbstractDevice getDevice()
|
||||||
|
{
|
||||||
|
return this.pipe.getDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the specified request packet.
|
||||||
|
*
|
||||||
|
* @param irp
|
||||||
|
* The request packet to process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void processIrp(final UsbIrp irp)
|
||||||
|
{
|
||||||
|
final UsbEndpoint endpoint = this.pipe.getUsbEndpoint();
|
||||||
|
final byte type = endpoint.getType();
|
||||||
|
final byte direction = endpoint.getDirection();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case UsbConst.ENDPOINT_TYPE_BULK:
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case UsbConst.ENDPOINT_DIRECTION_OUT:
|
||||||
|
irp.setActualLength(bulkWrite(irp.getData()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UsbConst.ENDPOINT_DIRECTION_IN:
|
||||||
|
irp.setActualLength(bulkRead(irp.getData()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UsbConst.ENDPOINT_TYPE_INTERRUPT:
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case UsbConst.ENDPOINT_DIRECTION_OUT:
|
||||||
|
irp.setActualLength(interruptWrite(irp.getData()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UsbConst.ENDPOINT_DIRECTION_IN:
|
||||||
|
irp.setActualLength(interruptRead(irp.getData()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UsbException("Unsupported endpoint type: " + type);
|
||||||
|
}
|
||||||
|
catch (final UsbException e)
|
||||||
|
{
|
||||||
|
irp.setUsbException(e);
|
||||||
|
}
|
||||||
|
irp.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes from a bulk endpoint into the specified data array.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* The data array to write the read bytes to.
|
||||||
|
* @throws UsbException
|
||||||
|
* When transfer fails.
|
||||||
|
* @return The number of read bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private int bulkRead(final byte[] data) throws UsbException
|
||||||
|
{
|
||||||
|
final UsbEndpointDescriptor descriptor = getEndpointDescriptor();
|
||||||
|
final int size =
|
||||||
|
Math.min(data.length, descriptor.wMaxPacketSize() & 0xffff);
|
||||||
|
final int ep = descriptor.bEndpointAddress();
|
||||||
|
final ByteBuffer buffer = ByteBuffer.allocateDirect(size);
|
||||||
|
final int result = usb_bulk_read(getDevice().open(), ep, buffer, 5000);
|
||||||
|
if (result < 0) throw new LibUsbException(result);
|
||||||
|
buffer.rewind();
|
||||||
|
buffer.get(data, 0, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the specified bytes to a bulk endpoint.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* The data array with the bytes to write.
|
||||||
|
* @throws UsbException
|
||||||
|
* When transfer fails.
|
||||||
|
* @return The number of written bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private int bulkWrite(final byte[] data) throws UsbException
|
||||||
|
{
|
||||||
|
final UsbEndpointDescriptor descriptor = getEndpointDescriptor();
|
||||||
|
final int total = data.length;
|
||||||
|
final int size = Math.min(total, descriptor.wMaxPacketSize() & 0xffff);
|
||||||
|
final int ep = descriptor.bEndpointAddress();
|
||||||
|
final ByteBuffer buffer = ByteBuffer.allocateDirect(size);
|
||||||
|
final USB_Dev_Handle handle = getDevice().open();
|
||||||
|
int written = 0;
|
||||||
|
while (written < total)
|
||||||
|
{
|
||||||
|
buffer.put(data, written, Math.min(total - written, size));
|
||||||
|
buffer.rewind();
|
||||||
|
final int result = usb_bulk_write(handle, ep, buffer, 5000);
|
||||||
|
if (result < 0) throw new LibUsbException(result);
|
||||||
|
written += result;
|
||||||
|
buffer.rewind();
|
||||||
|
}
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes from an interrupt endpoint into the specified data array.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* The data array to write the read bytes to.
|
||||||
|
* @throws UsbException
|
||||||
|
* When transfer fails.
|
||||||
|
* @return The number of read bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private int interruptRead(final byte[] data) throws UsbException
|
||||||
|
{
|
||||||
|
final UsbEndpointDescriptor descriptor = getEndpointDescriptor();
|
||||||
|
final int size =
|
||||||
|
Math.min(data.length, descriptor.wMaxPacketSize() & 0xffff);
|
||||||
|
final int ep = descriptor.bEndpointAddress();
|
||||||
|
final ByteBuffer buffer = ByteBuffer.allocateDirect(size);
|
||||||
|
final int result =
|
||||||
|
usb_interrupt_read(getDevice().open(), ep, buffer, 5000);
|
||||||
|
if (result < 0) throw new LibUsbException(result);
|
||||||
|
buffer.rewind();
|
||||||
|
buffer.get(data, 0, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the specified bytes to a interrupt endpoint.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* The data array with the bytes to write.
|
||||||
|
* @throws UsbException
|
||||||
|
* When transfer fails.
|
||||||
|
* @return The number of written bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private int interruptWrite(final byte[] data) throws UsbException
|
||||||
|
{
|
||||||
|
final UsbEndpointDescriptor descriptor = getEndpointDescriptor();
|
||||||
|
final int total = data.length;
|
||||||
|
final int size = Math.min(total, descriptor.wMaxPacketSize() & 0xffff);
|
||||||
|
final int ep = descriptor.bEndpointAddress();
|
||||||
|
final ByteBuffer buffer = ByteBuffer.allocateDirect(size);
|
||||||
|
final USB_Dev_Handle handle = getDevice().open();
|
||||||
|
int written = 0;
|
||||||
|
while (written < total)
|
||||||
|
{
|
||||||
|
buffer.put(data, written, Math.min(total - written, size));
|
||||||
|
buffer.rewind();
|
||||||
|
final int result = usb_interrupt_write(handle, ep, buffer, 5000);
|
||||||
|
if (result < 0) throw new LibUsbException(result);
|
||||||
|
written += result;
|
||||||
|
buffer.rewind();
|
||||||
|
}
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Runnable#run()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
this.running = true;
|
||||||
|
final UsbIrpQueue queue = this.pipe.getQueue();
|
||||||
|
while (!this.stop)
|
||||||
|
{
|
||||||
|
UsbIrp irp = queue.get();
|
||||||
|
while (!this.stop && irp != null)
|
||||||
|
{
|
||||||
|
this.processing = true;
|
||||||
|
processIrp(irp);
|
||||||
|
irp = queue.get();
|
||||||
|
}
|
||||||
|
this.processing = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
catch (final InterruptedException e)
|
||||||
|
{
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.running = false;
|
||||||
|
notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this thread is running.
|
||||||
|
*
|
||||||
|
* @return True if thread is running, false if not.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isRunning()
|
||||||
|
{
|
||||||
|
return this.running;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if packets are currently processed.
|
||||||
|
*
|
||||||
|
* @return If packets are processed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isProcessing()
|
||||||
|
{
|
||||||
|
return this.processing;
|
||||||
|
}
|
||||||
|
}
|
|
@ -84,7 +84,7 @@ public final class UsbConfigurationImpl implements UsbConfiguration
|
||||||
this.interfaces.put(ifaceNumber, settings);
|
this.interfaces.put(ifaceNumber, settings);
|
||||||
}
|
}
|
||||||
final UsbInterface usbInterface = new UsbInterfaceImpl(this,
|
final UsbInterface usbInterface = new UsbInterfaceImpl(this,
|
||||||
desc);
|
desc, device);
|
||||||
|
|
||||||
// If we have no active setting for current interface number
|
// If we have no active setting for current interface number
|
||||||
// yet or the alternate setting number is 0 (which marks the
|
// yet or the alternate setting number is 0 (which marks the
|
||||||
|
@ -92,7 +92,10 @@ public final class UsbConfigurationImpl implements UsbConfiguration
|
||||||
// the active setting.
|
// the active setting.
|
||||||
if (!this.activeSettings.containsKey(ifaceNumber) ||
|
if (!this.activeSettings.containsKey(ifaceNumber) ||
|
||||||
desc.bAlternateSetting() == 0)
|
desc.bAlternateSetting() == 0)
|
||||||
|
{
|
||||||
this.activeSettings.put(ifaceNumber, usbInterface);
|
this.activeSettings.put(ifaceNumber, usbInterface);
|
||||||
|
System.out.println("Active: " + usbInterface);
|
||||||
|
}
|
||||||
|
|
||||||
// Add the interface to the settings list
|
// Add the interface to the settings list
|
||||||
settings.put(settingNumber, usbInterface);
|
settings.put(settingNumber, usbInterface);
|
||||||
|
@ -160,7 +163,7 @@ public final class UsbConfigurationImpl implements UsbConfiguration
|
||||||
@Override
|
@Override
|
||||||
public UsbInterface getUsbInterface(final byte number)
|
public UsbInterface getUsbInterface(final byte number)
|
||||||
{
|
{
|
||||||
return this.activeSettings.get(number);
|
return this.activeSettings.get((int) number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||||
|
* See LICENSE.txt for licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.ailis.usb4java.jsr80;
|
||||||
|
|
||||||
|
import javax.usb.UsbConst;
|
||||||
|
import javax.usb.UsbEndpoint;
|
||||||
|
import javax.usb.UsbEndpointDescriptor;
|
||||||
|
import javax.usb.UsbInterface;
|
||||||
|
import javax.usb.UsbPipe;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* usb4java implementation of UsbEndpoint.
|
||||||
|
*
|
||||||
|
* @author Klaus Reimer (k@ailis.de)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class UsbEndpointImpl implements UsbEndpoint
|
||||||
|
{
|
||||||
|
/** The USB interface this endpoint belongs to. */
|
||||||
|
private final UsbInterfaceImpl iface;
|
||||||
|
|
||||||
|
/** The USB endpoint descriptor. */
|
||||||
|
private final UsbEndpointDescriptor descriptor;
|
||||||
|
|
||||||
|
/** The USB pipe for this endpoint. */
|
||||||
|
private final UsbPipe pipe;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param iface
|
||||||
|
* The USB interface this endpoint belongs to.
|
||||||
|
* @param descriptor
|
||||||
|
* The USB endpoint descriptor.
|
||||||
|
* @param device
|
||||||
|
* The USB device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public UsbEndpointImpl(final UsbInterfaceImpl iface,
|
||||||
|
final UsbEndpointDescriptor descriptor, final AbstractDevice device)
|
||||||
|
{
|
||||||
|
this.iface = iface;
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
this.pipe = new UsbPipeImpl(this, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UsbEndpoint#getUsbInterface()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsbInterface getUsbInterface()
|
||||||
|
{
|
||||||
|
return this.iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UsbEndpoint#getUsbEndpointDescriptor()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsbEndpointDescriptor getUsbEndpointDescriptor()
|
||||||
|
{
|
||||||
|
return this.descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UsbEndpoint#getDirection()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getDirection()
|
||||||
|
{
|
||||||
|
return (byte) (this.descriptor.bEndpointAddress() & UsbConst.ENDPOINT_DIRECTION_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UsbEndpoint#getType()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getType()
|
||||||
|
{
|
||||||
|
return (byte) (this.descriptor.bmAttributes() & UsbConst.ENDPOINT_TYPE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UsbEndpoint#getUsbPipe()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsbPipe getUsbPipe()
|
||||||
|
{
|
||||||
|
return this.pipe;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,11 +8,14 @@ package de.ailis.usb4java.jsr80;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.usb.UsbClaimException;
|
import javax.usb.UsbClaimException;
|
||||||
import javax.usb.UsbConfiguration;
|
import javax.usb.UsbConfiguration;
|
||||||
import javax.usb.UsbEndpoint;
|
import javax.usb.UsbEndpoint;
|
||||||
|
import javax.usb.UsbEndpointDescriptor;
|
||||||
import javax.usb.UsbException;
|
import javax.usb.UsbException;
|
||||||
import javax.usb.UsbInterface;
|
import javax.usb.UsbInterface;
|
||||||
import javax.usb.UsbInterfaceDescriptor;
|
import javax.usb.UsbInterfaceDescriptor;
|
||||||
|
@ -20,6 +23,7 @@ import javax.usb.UsbInterfacePolicy;
|
||||||
import javax.usb.UsbNotActiveException;
|
import javax.usb.UsbNotActiveException;
|
||||||
|
|
||||||
import de.ailis.usb4java.USBLock;
|
import de.ailis.usb4java.USBLock;
|
||||||
|
import de.ailis.usb4java.USB_Endpoint_Descriptor;
|
||||||
import de.ailis.usb4java.USB_Interface_Descriptor;
|
import de.ailis.usb4java.USB_Interface_Descriptor;
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +41,13 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
/** The interface descriptor. */
|
/** The interface descriptor. */
|
||||||
private final UsbInterfaceDescriptor descriptor;
|
private final UsbInterfaceDescriptor descriptor;
|
||||||
|
|
||||||
|
/** The endpoint address to endpoints mapping. */
|
||||||
|
private final Map<Byte, UsbEndpoint> endpointMap =
|
||||||
|
new HashMap<Byte, UsbEndpoint>();
|
||||||
|
|
||||||
|
/** The endpoints. */
|
||||||
|
private final List<UsbEndpoint> endpoints;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -45,15 +56,30 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
* The USB configuration.
|
* The USB configuration.
|
||||||
* @param lowLevelDescriptor
|
* @param lowLevelDescriptor
|
||||||
* The low-level USB interface descriptor.
|
* The low-level USB interface descriptor.
|
||||||
|
* @param device
|
||||||
|
* The USB device.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public UsbInterfaceImpl(final UsbConfigurationImpl configuration,
|
public UsbInterfaceImpl(final UsbConfigurationImpl configuration,
|
||||||
final USB_Interface_Descriptor lowLevelDescriptor)
|
final USB_Interface_Descriptor lowLevelDescriptor,
|
||||||
|
final AbstractDevice device)
|
||||||
{
|
{
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.descriptor = new UsbInterfaceDescriptorImpl(lowLevelDescriptor);
|
this.descriptor = new UsbInterfaceDescriptorImpl(lowLevelDescriptor);
|
||||||
}
|
|
||||||
|
|
||||||
|
final List<UsbEndpoint> endpoints = new ArrayList<UsbEndpoint>();
|
||||||
|
for (final USB_Endpoint_Descriptor desc : lowLevelDescriptor
|
||||||
|
.endpoint())
|
||||||
|
{
|
||||||
|
final UsbEndpointDescriptor descriptor =
|
||||||
|
new UsbEndpointDescriptorImpl(desc);
|
||||||
|
final UsbEndpoint endpoint =
|
||||||
|
new UsbEndpointImpl(this, descriptor, device);
|
||||||
|
this.endpointMap.put(descriptor.bEndpointAddress(), endpoint);
|
||||||
|
endpoints.add(endpoint);
|
||||||
|
}
|
||||||
|
this.endpoints = Collections.unmodifiableList(endpoints);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the configuration is active. If not then an
|
* Checks if the configuration is active. If not then an
|
||||||
|
@ -108,7 +134,8 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
device.setActiveUsbConfigurationNumber(this.configuration
|
device.setActiveUsbConfigurationNumber(this.configuration
|
||||||
.getUsbConfigurationDescriptor().bConfigurationValue());
|
.getUsbConfigurationDescriptor().bConfigurationValue());
|
||||||
device.claimInterface(this.descriptor.bInterfaceNumber());
|
device.claimInterface(this.descriptor.bInterfaceNumber());
|
||||||
this.configuration.setUsbInterface(this.descriptor.bInterfaceNumber(), this);
|
this.configuration.setUsbInterface(
|
||||||
|
this.descriptor.bInterfaceNumber(), this);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -148,6 +175,9 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive()
|
public boolean isActive()
|
||||||
{
|
{
|
||||||
|
System.out.println(this.configuration.getUsbInterface(this.descriptor
|
||||||
|
.bInterfaceNumber()));
|
||||||
|
System.out.println(this);
|
||||||
return this.configuration.getUsbInterface(this.descriptor
|
return this.configuration.getUsbInterface(this.descriptor
|
||||||
.bInterfaceNumber()) == this;
|
.bInterfaceNumber()) == this;
|
||||||
}
|
}
|
||||||
|
@ -238,8 +268,7 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
@Override
|
@Override
|
||||||
public List<UsbEndpoint> getUsbEndpoints()
|
public List<UsbEndpoint> getUsbEndpoints()
|
||||||
{
|
{
|
||||||
// TODO
|
return this.endpoints;
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,8 +279,7 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
@Override
|
@Override
|
||||||
public UsbEndpoint getUsbEndpoint(final byte address)
|
public UsbEndpoint getUsbEndpoint(final byte address)
|
||||||
{
|
{
|
||||||
// TODO
|
return this.endpointMap.get(address);
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -262,8 +290,7 @@ public final class UsbInterfaceImpl implements UsbInterface
|
||||||
@Override
|
@Override
|
||||||
public boolean containsUsbEndpoint(final byte address)
|
public boolean containsUsbEndpoint(final byte address)
|
||||||
{
|
{
|
||||||
// TODO
|
return this.endpointMap.containsKey(address);
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||||
|
* See LICENSE.txt for licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.ailis.usb4java.jsr80;
|
||||||
|
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import javax.usb.UsbIrp;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* USB I/O request packet queue.
|
||||||
|
*
|
||||||
|
* @author Klaus Reimer (k@ailis.de)
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class UsbIrpQueue
|
||||||
|
{
|
||||||
|
/** The queued packets. */
|
||||||
|
private final Deque<UsbIrp> irps = new LinkedList<UsbIrp>();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a request packet to the queue.
|
||||||
|
*
|
||||||
|
* @param irp
|
||||||
|
* The packet to add to the queue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void add(final UsbIrp irp)
|
||||||
|
{
|
||||||
|
synchronized (this.irps)
|
||||||
|
{
|
||||||
|
this.irps.add(irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next request packet to process.
|
||||||
|
*
|
||||||
|
* @return The next packet to process or null if queue is empty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public UsbIrp get()
|
||||||
|
{
|
||||||
|
synchronized (this.irps)
|
||||||
|
{
|
||||||
|
return this.irps.poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all remaining unprocessed requests.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
synchronized (this.irps)
|
||||||
|
{
|
||||||
|
this.irps.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if queue is empty.
|
||||||
|
*
|
||||||
|
* @return True if queue is empty, false if not.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return this.irps.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,392 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Klaus Reimer <k@ailis.de>
|
||||||
|
* See LICENSE.txt for licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.ailis.usb4java.jsr80;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.usb.UsbConfiguration;
|
||||||
|
import javax.usb.UsbControlIrp;
|
||||||
|
import javax.usb.UsbDisconnectedException;
|
||||||
|
import javax.usb.UsbException;
|
||||||
|
import javax.usb.UsbInterface;
|
||||||
|
import javax.usb.UsbIrp;
|
||||||
|
import javax.usb.UsbNotActiveException;
|
||||||
|
import javax.usb.UsbNotClaimedException;
|
||||||
|
import javax.usb.UsbNotOpenException;
|
||||||
|
import javax.usb.UsbPipe;
|
||||||
|
import javax.usb.event.UsbPipeListener;
|
||||||
|
import javax.usb.util.DefaultUsbControlIrp;
|
||||||
|
import javax.usb.util.DefaultUsbIrp;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* usb4java implementation of UsbPipe.
|
||||||
|
*
|
||||||
|
* @author Klaus Reimer (k@ailis.de)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class UsbPipeImpl implements UsbPipe
|
||||||
|
{
|
||||||
|
/** The endpoint this pipe belongs to. */
|
||||||
|
private final UsbEndpointImpl endpoint;
|
||||||
|
|
||||||
|
/** The device. */
|
||||||
|
private final AbstractDevice device;
|
||||||
|
|
||||||
|
/** The USB pipe listeners. */
|
||||||
|
private final UsbPipeListenerList listeners = new UsbPipeListenerList();
|
||||||
|
|
||||||
|
/** If pipe is open or not. */
|
||||||
|
private boolean opened;
|
||||||
|
|
||||||
|
/** The request queue. */
|
||||||
|
private final UsbIrpQueue queue = new UsbIrpQueue();
|
||||||
|
|
||||||
|
/** The thread which processes the queue. null if none. */
|
||||||
|
private PipeQueueProcessor queueProcessor;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param endpoint
|
||||||
|
* The endpoint this pipe belongs to.
|
||||||
|
* @param device
|
||||||
|
* The USB device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
UsbPipeImpl(final UsbEndpointImpl endpoint, final AbstractDevice device)
|
||||||
|
{
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the USB device.
|
||||||
|
*
|
||||||
|
* @return The USB device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
AbstractDevice getDevice()
|
||||||
|
{
|
||||||
|
return this.device;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the pipe is active.
|
||||||
|
*
|
||||||
|
* @throws UsbNotActiveException
|
||||||
|
* When pipe is not active
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void checkActive() throws UsbNotActiveException
|
||||||
|
{
|
||||||
|
if (!isActive())
|
||||||
|
throw new UsbNotActiveException("Pipe is not active.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the interface is active.
|
||||||
|
*
|
||||||
|
* @throws UsbNotClaimedException
|
||||||
|
* When interface is not claimed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void checkClaimed() throws UsbNotClaimedException
|
||||||
|
{
|
||||||
|
if (!this.endpoint.getUsbInterface().isClaimed())
|
||||||
|
throw new UsbNotClaimedException("Interface is not claimed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the device is not disconnected.
|
||||||
|
*
|
||||||
|
* @throws UsbDisconnectedException
|
||||||
|
* When device has been disconnected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void checkDisconnected() throws UsbDisconnectedException
|
||||||
|
{
|
||||||
|
// TODO implement me
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the pipe is open.
|
||||||
|
*
|
||||||
|
* @throws UsbNotOpenException
|
||||||
|
* When pipe is not open.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void checkOpen() throws UsbNotOpenException
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
throw new UsbNotOpenException("Pipe is not open.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#open()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void open() throws UsbException, UsbNotActiveException,
|
||||||
|
UsbNotClaimedException, UsbDisconnectedException
|
||||||
|
{
|
||||||
|
checkActive();
|
||||||
|
checkClaimed();
|
||||||
|
checkDisconnected();
|
||||||
|
if (this.opened) throw new UsbException("Pipe is already open");
|
||||||
|
|
||||||
|
this.queueProcessor = new PipeQueueProcessor(this);
|
||||||
|
this.queueProcessor.start();
|
||||||
|
|
||||||
|
this.opened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#close()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws UsbException, UsbNotActiveException,
|
||||||
|
UsbNotOpenException, UsbDisconnectedException
|
||||||
|
{
|
||||||
|
checkActive();
|
||||||
|
checkClaimed();
|
||||||
|
checkDisconnected();
|
||||||
|
if (!this.opened) throw new UsbException("Pipe is already closed");
|
||||||
|
if (this.queueProcessor.isProcessing() || !this.queue.isEmpty())
|
||||||
|
throw new UsbException("Pipe is still in use");
|
||||||
|
|
||||||
|
this.queue.clear();
|
||||||
|
this.queueProcessor.shutdownAndWait();
|
||||||
|
this.queueProcessor = null;
|
||||||
|
|
||||||
|
this.opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#isActive()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
final UsbInterface iface = this.endpoint.getUsbInterface();
|
||||||
|
final UsbConfiguration config = iface.getUsbConfiguration();
|
||||||
|
return iface.isActive() && config.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#isOpen()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen()
|
||||||
|
{
|
||||||
|
return this.opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#getUsbEndpoint()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsbEndpointImpl getUsbEndpoint()
|
||||||
|
{
|
||||||
|
return this.endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#syncSubmit(byte[])
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int syncSubmit(final byte[] data) throws UsbException,
|
||||||
|
UsbNotActiveException, UsbNotOpenException, IllegalArgumentException,
|
||||||
|
UsbDisconnectedException
|
||||||
|
{
|
||||||
|
final UsbIrp irp = asyncSubmit(data);
|
||||||
|
irp.waitUntilComplete();
|
||||||
|
if (irp.isUsbException()) throw irp.getUsbException();
|
||||||
|
return irp.getActualLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#asyncSubmit(byte[])
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsbIrp asyncSubmit(final byte[] data) throws UsbException,
|
||||||
|
UsbNotActiveException, UsbNotOpenException, IllegalArgumentException,
|
||||||
|
UsbDisconnectedException
|
||||||
|
{
|
||||||
|
if (data == null)
|
||||||
|
throw new IllegalArgumentException("data must not be null");
|
||||||
|
final UsbIrp irp = createUsbIrp();
|
||||||
|
irp.setAcceptShortPacket(true);
|
||||||
|
irp.setData(data);
|
||||||
|
asyncSubmit(irp);
|
||||||
|
return irp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#syncSubmit(javax.usb.UsbIrp)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncSubmit(final UsbIrp irp) throws UsbException,
|
||||||
|
UsbNotActiveException, UsbNotOpenException, IllegalArgumentException,
|
||||||
|
UsbDisconnectedException
|
||||||
|
{
|
||||||
|
if (irp == null)
|
||||||
|
throw new IllegalArgumentException("irp must not be null");
|
||||||
|
asyncSubmit(irp);
|
||||||
|
irp.waitUntilComplete();
|
||||||
|
if (irp.isUsbException()) throw irp.getUsbException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#asyncSubmit(javax.usb.UsbIrp)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void asyncSubmit(final UsbIrp irp) throws UsbException,
|
||||||
|
UsbNotActiveException, UsbNotOpenException, IllegalArgumentException,
|
||||||
|
UsbDisconnectedException
|
||||||
|
{
|
||||||
|
if (irp == null)
|
||||||
|
throw new IllegalArgumentException("irp must not be null");
|
||||||
|
checkActive();
|
||||||
|
checkDisconnected();
|
||||||
|
checkOpen();
|
||||||
|
|
||||||
|
this.queue.add(irp);
|
||||||
|
this.queueProcessor.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#syncSubmit(java.util.List)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncSubmit(@SuppressWarnings("rawtypes") final List list)
|
||||||
|
throws UsbException, UsbNotActiveException, UsbNotOpenException,
|
||||||
|
IllegalArgumentException, UsbDisconnectedException
|
||||||
|
{
|
||||||
|
for (final Object item: list)
|
||||||
|
{
|
||||||
|
final UsbIrp irp = (UsbIrp) item;
|
||||||
|
syncSubmit(irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#asyncSubmit(java.util.List)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void asyncSubmit(@SuppressWarnings("rawtypes") final List list)
|
||||||
|
throws UsbException, UsbNotActiveException, UsbNotOpenException,
|
||||||
|
IllegalArgumentException, UsbDisconnectedException
|
||||||
|
{
|
||||||
|
for (final Object item: list)
|
||||||
|
{
|
||||||
|
final UsbIrp irp = (UsbIrp) item;
|
||||||
|
asyncSubmit(irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#abortAllSubmissions()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void abortAllSubmissions() throws UsbNotActiveException,
|
||||||
|
UsbNotOpenException, UsbDisconnectedException
|
||||||
|
{
|
||||||
|
checkActive();
|
||||||
|
checkDisconnected();
|
||||||
|
checkOpen();
|
||||||
|
this.queue.clear();
|
||||||
|
this.queueProcessor.shutdownAndWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#createUsbIrp()
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsbIrp createUsbIrp()
|
||||||
|
{
|
||||||
|
return new DefaultUsbIrp();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#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 javax.usb.UsbPipe#addUsbPipeListener(javax.usb.event.UsbPipeListener)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addUsbPipeListener(final UsbPipeListener listener)
|
||||||
|
{
|
||||||
|
this.listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.usb.UsbPipe#removeUsbPipeListener(javax.usb.event.UsbPipeListener)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeUsbPipeListener(final UsbPipeListener listener)
|
||||||
|
{
|
||||||
|
this.listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the request packet queue.
|
||||||
|
*
|
||||||
|
* @return The request packet queue. Never null.
|
||||||
|
*/
|
||||||
|
|
||||||
|
UsbIrpQueue getQueue()
|
||||||
|
{
|
||||||
|
return this.queue;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue