diff --git a/src/test/java/javax/usb/tck/BulkShortPacketIOTests.java b/src/test/java/javax/usb/tck/BulkShortPacketIOTests.java
new file mode 100755
index 0000000..2a7cb55
--- /dev/null
+++ b/src/test/java/javax/usb/tck/BulkShortPacketIOTests.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2004, International Business Machines Corporation.
+ * All Rights Reserved.
+ *
+ * This software is provided and licensed under the terms and conditions
+ * of the Common Public License:
+ * http://oss.software.ibm.com/developerworks/opensource/license-cpl.html
+ */
+
+package javax.usb.tck;
+
+import java.util.*;
+
+import javax.usb.*;
+
+import org.junit.runner.RunWith;
+
+import de.ailis.usb4java.TCKRunner;
+
+
+
+import junit.framework.*;
+
+/**
+ * Bulk IO Short Packet Test -- Synchronous and asynchronous byte[], IRP, and IRP List submissions
+ *
+ * The goal of the Bulk, Interrupt, and Isochronous IO test is to
+ * verify that IN and OUT pipes can be opened and closed, and verify
+ * that bulk, interrupt, and isochronous transfer operations work successfully, proper
+ * events are generated, and proper exceptions are thrown in the operation.
+ *
+ * This test verifies that UsbShortPacketException is received when expected.
+ *
+ * @author Leslie Blair
+ */
+
+@SuppressWarnings("all")
+@RunWith(TCKRunner.class)
+public class BulkShortPacketIOTests extends TestCase
+{
+ public void setUp() throws Exception
+ {
+ endpointType = UsbConst.ENDPOINT_TYPE_BULK;
+ usbDevice = FindProgrammableDevice.getInstance().getProgrammableDevice();
+ Assert.assertNotNull("Device required for test not found",usbDevice);
+ IOMethods.createListofAllAvailablePipesOfSpecifiedEndpointType(usbDevice, endpointType, usbPipeListGlobal);
+ assertFalse("No pipes of specified endpoint were found.", (0 == usbPipeListGlobal.size()));
+ super.setUp();
+ }
+ public void tearDown() throws Exception
+ {
+ IOMethods.releaseListOfPipes(usbPipeListGlobal);
+ super.tearDown();
+ }
+
+
+ public void testShortPacketException()
+ {
+ //repeat the test for the number of iteration specified
+ for ( int iterations=0; (iterations < IOShortPacketTest.totalIterations); iterations++ )
+ {
+ //first, do all transfers sync and then do async
+ for ( int syncOrAsync=0; syncOrAsync
+ * The goal of the Bulk, Interrupt, and Isochronous IO test is to
+ * verify that IN and OUT pipes can be opened and closed, and verify
+ * that bulk, interrupt, and isochronous transfer operations work successfully, proper
+ * events are generated, and proper exceptions are thrown in the operation.
+ *
+ * @author Leslie Blair
+ */
+
+
+@SuppressWarnings("all")
+public class IOShortPacketTest
+{
+
+ protected void RoundTripIOTestShortPacket(byte testType, int syncOrAsync,int numIrps, int endpointmaxPacketSize,
+ boolean []acceptShortPacket, boolean []verifyAcceptShortPacket,
+ int[] OUTLength, int[] OUTOffset, int[] OUTExpectedLength,
+ Exception []OUTexpectedException,
+
+ int[] INLength, int[]INOffset, int[]INExpectedLength,
+ Exception []INexpectedException,
+ byte [] transformType
+ )
+
+ {
+
+ //Note that this code is based on IOTests.RounTripTest which handles IRP, IRPList, and Byte array. Since only IRPs
+ //are being sent in this test, some of the complexity has been removed; however, although the numIrps is always
+ //one for this test, the code has not been changed to get rid of the arrays.
+
+ //ensure all values set up
+ Assert.assertEquals(numIrps,transformType.length);
+ Assert.assertEquals(numIrps,OUTLength.length);
+ Assert.assertEquals(numIrps,OUTOffset.length);
+ Assert.assertEquals(numIrps,acceptShortPacket.length);
+ Assert.assertEquals(numIrps,verifyAcceptShortPacket.length);
+ Assert.assertEquals(numIrps,OUTExpectedLength.length);
+ Assert.assertEquals(numIrps,OUTexpectedException.length);
+ Assert.assertEquals(numIrps,INLength.length);
+ Assert.assertEquals(numIrps,INOffset.length);
+ Assert.assertEquals(numIrps,INExpectedLength.length);
+ Assert.assertEquals(numIrps,INexpectedException.length);
+
+ Assert.assertNotNull("usbDevice is null, but should not be null.", usbDevice);
+ Assert.assertEquals("For short packet test, number of IRPs should be 1.", 1, numIrps);
+
+
+ /*
+ * set up Pipes and add listeners
+ */
+ UsbPipe inPipe = null;
+ UsbPipe outPipe = null;
+
+ //we need two int values back from method call so we'll put them in the array
+ int [] pipeListIndexes = new int[2];
+ int inPipeArrayIndex = 0;
+ int outPipeArrayIndex = 1;
+
+ IOMethods.findINandOUTPipesForTest(usbPipeListGlobal, endpointmaxPacketSize, pipeListIndexes, inPipeArrayIndex, outPipeArrayIndex);
+ inPipe = (UsbPipe) usbPipeListGlobal.get(pipeListIndexes[inPipeArrayIndex]);
+ outPipe = (UsbPipe) usbPipeListGlobal.get(pipeListIndexes[outPipeArrayIndex]);
+ IOMethods.verifyThePipes(inPipe, outPipe, endpointmaxPacketSize);
+
+ inPipe.addUsbPipeListener(inPipeListener);
+ outPipe.addUsbPipeListener(outPipeListener);
+
+ IOMethods.openPipe(inPipe);
+ IOMethods.openPipe(outPipe);
+
+
+
+ //define buffers to be used in IRPs or sent as byte[]
+ byte[] aggregateOUTbuffer = null;
+ byte[] aggregateINbuffer = null;
+
+
+ //for byte array and single IRP, the OUT and IN buffers are the length specified by the tests
+ aggregateOUTbuffer = new byte[OUTLength[0]];
+ aggregateINbuffer = new byte[INLength[0]];
+
+
+ printDebug("RoundTripTestShortPacket -- IRP " + transmitListStrings[syncOrAsync] +" " + endpointTypeStrings[endpointType]);
+
+
+
+
+
+
+ /*
+ * Create the OUT and IN IRPs or byte arrrays
+ */
+ List transmitBuffers = new ArrayList();
+ List listOfOUTIrps = new ArrayList();
+ List listOfINIrps = new ArrayList();
+
+ for ( int k = 0 ; k < numIrps; k++ )
+ {
+ //create transmit buffer for OUT and IN IRPs
+ TransmitBuffer currentTransmitBuffer = new TransmitBuffer(transformType[k], OUTLength[k]);
+ transmitBuffers.add(currentTransmitBuffer);
+
+
+ //create OUT IRP
+ UsbIrp currentOUTIrp = outPipe.createUsbIrp();
+ listOfOUTIrps.add(currentOUTIrp);
+
+ //set data in OUT IRP
+ currentOUTIrp.setData(aggregateOUTbuffer, OUTOffset[k], OUTLength[k]);
+ currentOUTIrp.setAcceptShortPacket(acceptShortPacket[k]);
+
+ //OUT IRP is ready to go!
+
+
+ if ( endpointType == UsbConst.ENDPOINT_TYPE_ISOCHRONOUS )
+ {
+ /*
+ * For isochronous transfers, all IN Irps will have an offset of zero and
+ * the same buffer length.
+ */
+ //get the longest required buffer length for all of the IRPs. All of the IRPs in the list
+ //have the same length buffer.
+ int standardISOINBufferLength = INLength[0];
+ for ( int l = 1; l standardISOINBufferLength )
+ {
+ standardISOINBufferLength = INLength[l];
+ }
+ }
+ //now that the largest has been found, set the length for each in IRP to the new length
+ for ( int l = 0; l=0; i-- )
+ {
+ //all of the IRPs in which we are interested SHOULD have a non zero length
+ //amount of data returned.
+ //Once the zero length data IRP events are removed, only the IRP events that received the
+ //expected OUT data should be left in the list
+
+ Assert.assertTrue("There should be no error events in the list.",((UsbPipeEvent) listOfPipeEvents.get(i)).getClass() == UsbPipeDataEvent.class);
+ if ( ((UsbPipeDataEvent) listOfPipeEvents.get(i)).getUsbIrp().getActualLength() == 0 )
+ {
+ listOfPipeEvents.remove(i);
+ Assert.assertEquals("Original Irps and pipe event Irps should be zero actual length in the same position in the list.",0,((UsbIrp) listOfIrps.get(i)).getActualLength());
+ listOfIrps.remove(i);
+ }
+ else
+ {
+ Assert.assertEquals("Original Irps and pipe event Irps actual length should be the same at the same position in the list.",
+ ((UsbPipeDataEvent) listOfPipeEvents.get(i)).getUsbIrp().getActualLength(),
+ ((UsbIrp) listOfIrps.get(i)).getActualLength());
+ printDebug("Non-zero actual length pipe event found at index " + i);
+ }
+ }
+ Assert.assertFalse("None of the Isochronous IN IRPs received any data",0 == listOfPipeEvents.size());
+ };
+
+
+
+
+ //-------------------------------------------------------------------------
+ // Instance variables
+ //
+
+ private UsbPipeListener inPipeListener = new UsbPipeListener()
+ {
+ public void dataEventOccurred(UsbPipeDataEvent updE)
+ {
+ Assert.assertNotNull(updE);
+ inPipeEvents.add(updE);
+ printDebug("IN Length: " + updE.getUsbIrp().getLength());
+ printDebug("IN actualLength: " + updE.getUsbIrp().getActualLength());
+ printDebug("IN acceptShortPackets: " + updE.getUsbIrp().getAcceptShortPacket());
+ printDebug("IN data event.");
+ }
+
+ public void errorEventOccurred(UsbPipeErrorEvent upeE)
+ {
+ Assert.assertNotNull(upeE);
+ inPipeEvents.add(upeE);
+ printDebug("IN error event.");
+
+ }
+ };
+
+ private UsbPipeListener outPipeListener = new UsbPipeListener()
+ {
+ public void dataEventOccurred(UsbPipeDataEvent updE)
+ {
+ Assert.assertNotNull(updE);
+ outPipeEvents.add(updE);
+ printDebug("OUT actualLength: " + updE.getUsbIrp().getActualLength());
+ printDebug("OUT data event.");
+ }
+
+ public void errorEventOccurred(UsbPipeErrorEvent upeE)
+ {
+ Assert.assertNotNull(upeE);
+ //outPipeEvents.add(upeE);
+ printDebug("OUT error event.");
+ upeE.getUsbException().printStackTrace();
+ Assert.fail("No OUT pipe error events expected during this test. Exception is " + upeE.getUsbException().getMessage());
+ }
+ };
+
+ /**
+ * Constructor
+ */
+ public IOShortPacketTest()
+ {
+ super();
+ };
+
+ protected IOShortPacketTest(UsbDevice newUsbDevice, List newUsbPipeList, byte newEndpointType, byte newTestType)
+ {
+ usbPipeListGlobal = newUsbPipeList;
+ usbDevice = newUsbDevice;
+ endpointType = newEndpointType;
+ testType = newTestType;
+ };
+
+ private List inPipeEvents = new ArrayList();
+ private List outPipeEvents = new ArrayList();
+
+ private List usbPipeListGlobal = new ArrayList();
+
+ private byte endpointType;
+ private static final int MAX_SIZE_IRP_BUFFER = 750;
+
+
+ protected static final byte TRANSFORM_TYPE_PASSTHROUGH = (byte)0x01;
+ protected static final byte TRANSFORM_TYPE_INVERT_BITS = (byte)0x02;
+ protected static final byte TRANSFORM_TYPE_INVERT_ALTERNATE_BITS = (byte)0x03;
+
+ private UsbDevice usbDevice;
+ protected static int totalIterations = 10;
+ //private int totalIterations = 1;
+ private static final boolean SYNC_SUBMIT = true;
+ private static final boolean ASYNC_SUBMIT = false;
+ protected static final boolean [] transmitList= {SYNC_SUBMIT, ASYNC_SUBMIT};
+ private static final String [] transmitListStrings = {"SYNC","ASYNC"};
+ protected static final byte BYTE_ARRAY = 0;
+ protected static final byte IRP = 1;
+ protected static final byte IRPLIST = 2;
+ private static final String [] endpointTypeStrings = {"CONTROL","ISOCHRONOUS", "BULK", "INTERRUPT"};
+ byte testType;
+
+ protected static void printDebug(String infoString)
+ {
+ if ( printDebug )
+ {
+ System.out.println(infoString);
+ }
+ }
+ private static boolean printDebug = false;
+ // private static boolean printDebug = true;
+}