Pipes

The absolute last piece where you finally get to send some non-control data is the USB pipe. This is represented by an instance of the UsbPipe interface. The getUsbPipe( ) method in UsbEndpoint returns the single pipe associated with that endpoint:

public UsbPipe getUsbPipe( )

USB I/O is packet-based like UDP, not stream-based like TCP. You do not get an InputStream or an OutputStream from a pipe. Instead, you send or receive IRPs. In Java, IRPs are represented by the javax.usb.UsbIrp class. This is a wrapper around a byte array containing the actual data sent to or received from the device.

You cannot send arbitrarily large byte arrays to a device. A low-speed device can accept at most eight bytes in each packet. A full-speed device can accept up to 1,023 bytes. A high-speed device can accept up to 1,024 bytes per packet.

This can be further restricted depending on the type of transfer: low-speed control transfers always use 8-byte packets; high-speed control transfers use 8-, 16-, 32-, or 64-byte packets; and full-speed control transfers always use 64-byte packets.

Writing to an output pipe to move data from the host to the device follows these steps:

  1. Open the pipe by calling the open( ) method.

  2. Stuff a data array into a UsbIrp.

  3. Send the IRP down the pipe, either synchronously with syncSubmit( ) or asynchronously with asyncSubmit( ).

  4. Close the pipe with the close( ) method.

Steps 2 and 3 may be repeated as many times as desired.

Reading from an input pipe to collect data from the device for the host follows these steps:

  1. Open the pipe by calling the open( ) method.

  2. Create a new empty UsbIrp to hold data received from the device.

  3. Put an IRP on the pipe to receive the data from the device either synchronously with syncSubmit( ) or asynchronously with asyncSubmit( ).

  4. Read the data out of the IRP you created in step 2.

  5. Close the pipe with the close( ) method.

Steps 2 through 4 can be repeated as many times as necessary. A completed IRP can be reused provided you call setComplete(false) on each IRP before you resubmit it.

Before you can write to a pipe, you must open it by invoking the open( ) method:

public void open( ) throws UsbException, UsbNotActiveException, UsbNotClaimedException, UsbDisconnectedException

The interface the pipe belongs to must be both active and claimed. Otherwise, this method throws a UsbNotActiveException or a UsbNotClaimedException, respectively.

You send the IRPs to the device either synchronously (blocking) or asynchronously (nonblocking):

public void syncSubmit(UsbIrp irp) throws UsbException, UsbNotActiveException, IllegalArgumentException, UsbDisconnectedException public void asyncSubmit(UsbIrp irp) throws UsbException, UsbNotActiveException, UsbNotOpenException, IllegalArgumentException, UsbDisconnectedException

You can also submit a list of IRPs to be used in sequence:

public void syncSubmit(List list) throws UsbException, UsbNotActiveException, UsbNotOpenException, IllegalArgumentException, UsbDisconnectedException public void asyncSubmit(List list) throws UsbException, UsbNotSctiveException, UsbNotOpenException, IllegalArgumentException, UsbDisconnectedException

To keep data flowing at a brisk pace, youll normally want to make sure enough IRPs are available for any incoming data. Streaming applications such as audio recording or anything that transfers large data buffers should submit multiple buffers in a block.

Finally, you can just submit the data array and let the pipe build the IRP for you. This is probably the simplest approach:

public void syncSubmit(byte[] data) throws UsbException, UsbNotActiveException, UsbNotOpenException, IllegalArgumentException, UsbDisconnectedException public void asyncSubmit(byte[] data) throws UsbException, UsbNotActiveException, UsbNotOpenException, IllegalArgumentException, UsbDisconnectedException

However, this does not give you all the options working with an actual UsbIrp object does.

All six variants throw a UsbNotOpenException if the pipe has not yet been opened. All six throw an IllegalArgumentException if the IRP or list of IRPs is not properly prepared for the pipe.

When you e finished with a pipe you should close it. This takes three steps:

  1. Cancel all pending submissions.

  2. Close the pipe.

  3. Release the interface you claimed.

For example:

pipe.abortAllSubmissions( ); pipe.close( ); theInterface.release( );

It seems to be necessary to call abortAllSubmissions( ) even if you don have any pending submissions. Im not sure why, but when I skipped this step, I always got a UsbException with the message "Cannot close pipe with pending submissions."

Категории

© amp.flylib.com,