<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="resources/manual.js"></script>
  </head>
  <body>
    <p>
      This test requires a USB device implementing the USB CDC-ACM protocol
      configured to loop back TX to RX. For example, this Arduino sketch could
      be used:

      <pre>
void setup() {
  Serial.begin(115200);
  Serial.setTimeout(0);
  while (!Serial) {
    ;
  }
}

void loop() {
  if (Serial.available()) {
    char buf[1024]; // Greater than the endpoint packet size.
    int count = Serial.readBytes(buf, sizeof buf);
    Serial.write(buf, count);
  }
}
      </pre>
    </p>
    <script>
      manual_usb_serial_test(async (t, device, inEndpoint, outEndpoint) => {
        // Set up two IN transfers which should complete in order.
        const transfer1 =
            device.transferIn(inEndpoint.endpointNumber, inEndpoint.packetSize);
        const transfer2 =
            device.transferIn(inEndpoint.endpointNumber, inEndpoint.packetSize);

        // Write a single byte to the port which should be echoed to complete
        // transfer1.
        let result = await device.transferOut(
            outEndpoint.endpointNumber, new Uint8Array(['a'.charCodeAt(0)]));
        assert_equals(result.status, 'ok');
        assert_equals(result.bytesWritten, 1);

        result = await transfer1;
        assert_equals(result.status, 'ok');
        assert_not_equals(result.data, null);
        assert_equals(result.data.byteLength, 1, 'byteLength');
        assert_equals(result.data.getUint8(0), 'a'.charCodeAt(0));

        // Set up a third IN transfer which will be canceled when the device is
        // closed at the end of the test.
        const transfer3 = promise_rejects_dom(
            t, 'AbortError',
            device.transferIn(inEndpoint.endpointNumber,
                              inEndpoint.packetSize));

        // Write a single byte to the port which should be echoed to complete
        // transfer2.
        result = await device.transferOut(
            outEndpoint.endpointNumber, new Uint8Array(['b'.charCodeAt(0)]));
        assert_equals(result.status, 'ok');
        assert_equals(result.bytesWritten, 1);

        result = await transfer2;
        assert_equals(result.status, 'ok');
        assert_not_equals(result.data, null);
        assert_equals(result.data.byteLength, 1, 'byteLength');
        assert_equals(result.data.getUint8(0), 'b'.charCodeAt(0));

        await device.close();
        await transfer3;
      }, 'Multiple small IN transfers on an endpoint complete in order');

      manual_usb_serial_test(async (t, device, inEndpoint, outEndpoint) => {
        const bufferLength = outEndpoint.packetSize * 20;
        const parallelRequests = 6;

        // Keep track of the order in which transfers are submitted.
        let enqueueSequence = 0;
        let dequeueSequence = 0;
        const received = new Uint8Array(bufferLength);
        let receivedOffset = 0;
        let done = false;
        const transfers = [];

        async function readNext(sequence) {
          let result;
          try {
            result = await device.transferIn(inEndpoint.endpointNumber,
                                             inEndpoint.packetSize);
          } catch (e) {
            // The last few transfers will fail when the device is closed.
            assert_true(done);
            assert_equals(dequeueSequence++, sequence, 'dequeueSequence done');
            assert_equals(receivedOffset, bufferLength, 'receivedOffset');
            assert_equals(e.name, 'AbortError');
            return;
          }

          assert_equals(dequeueSequence++, sequence, 'dequeueSequence');
          assert_equals(result.status, 'ok');
          assert_not_equals(result.data, null);

          const data = new Uint8Array(
              result.data.buffer, result.data.byteOffset,
              result.data.byteLength);
          received.set(data, receivedOffset);
          receivedOffset += result.data.byteLength;

          // Check |done| because there might be zero-length packet completions
          // after the data has been completely received.
          if (!done) {
            if (receivedOffset == bufferLength) {
              done = true;
              assert_array_equals(received, buffer);
              await device.close();
            } else {
              await readNext(enqueueSequence++);
            }
          }
        }

        for (let i = 0; i < parallelRequests; ++i) {
          transfers.push(readNext(enqueueSequence++));
        }

        // Write a large buffer to the device which will be split up into
        // smaller packets when echoed back.
        const buffer = new Uint8Array(bufferLength);
        for (let i = 0; i < buffer.byteLength; ++i) {
          buffer[i] = i;
        }
        let result = await device.transferOut(
            outEndpoint.endpointNumber, buffer);
        assert_equals(result.status, 'ok');
        assert_equals(result.bytesWritten, buffer.byteLength);

        await Promise.all(transfers);
        assert_equals(dequeueSequence, enqueueSequence);
      }, 'Multiple large IN transfers on an endpoint complete in order');
    </script>
  </body>
</html>
