Finished pipe implementation.

This commit is contained in:
Klaus Reimer 2011-02-04 23:32:36 +01:00 committed by k
parent cf4dd66d31
commit 8563bd97d5
8 changed files with 1022 additions and 11 deletions

View File

@ -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();
} }

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
} }

View File

@ -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;
}
}

View File

@ -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();
} }

View File

@ -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();
}
}

View File

@ -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;
}
}