tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

usbDevice_transferIn-manual.https.html (5378B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <meta charset="utf-8">
      5    <title></title>
      6    <script src="/resources/testharness.js"></script>
      7    <script src="/resources/testharnessreport.js"></script>
      8    <script src="resources/manual.js"></script>
      9  </head>
     10  <body>
     11    <p>
     12      This test requires a USB device implementing the USB CDC-ACM protocol
     13      configured to loop back TX to RX. For example, this Arduino sketch could
     14      be used:
     15 
     16      <pre>
     17 void setup() {
     18  Serial.begin(115200);
     19  Serial.setTimeout(0);
     20  while (!Serial) {
     21    ;
     22  }
     23 }
     24 
     25 void loop() {
     26  if (Serial.available()) {
     27    char buf[1024]; // Greater than the endpoint packet size.
     28    int count = Serial.readBytes(buf, sizeof buf);
     29    Serial.write(buf, count);
     30  }
     31 }
     32      </pre>
     33    </p>
     34    <script>
     35      manual_usb_serial_test(async (t, device, inEndpoint, outEndpoint) => {
     36        // Set up two IN transfers which should complete in order.
     37        const transfer1 =
     38            device.transferIn(inEndpoint.endpointNumber, inEndpoint.packetSize);
     39        const transfer2 =
     40            device.transferIn(inEndpoint.endpointNumber, inEndpoint.packetSize);
     41 
     42        // Write a single byte to the port which should be echoed to complete
     43        // transfer1.
     44        let result = await device.transferOut(
     45            outEndpoint.endpointNumber, new Uint8Array(['a'.charCodeAt(0)]));
     46        assert_equals(result.status, 'ok');
     47        assert_equals(result.bytesWritten, 1);
     48 
     49        result = await transfer1;
     50        assert_equals(result.status, 'ok');
     51        assert_not_equals(result.data, null);
     52        assert_equals(result.data.byteLength, 1, 'byteLength');
     53        assert_equals(result.data.getUint8(0), 'a'.charCodeAt(0));
     54 
     55        // Set up a third IN transfer which will be canceled when the device is
     56        // closed at the end of the test.
     57        const transfer3 = promise_rejects_dom(
     58            t, 'AbortError',
     59            device.transferIn(inEndpoint.endpointNumber,
     60                              inEndpoint.packetSize));
     61 
     62        // Write a single byte to the port which should be echoed to complete
     63        // transfer2.
     64        result = await device.transferOut(
     65            outEndpoint.endpointNumber, new Uint8Array(['b'.charCodeAt(0)]));
     66        assert_equals(result.status, 'ok');
     67        assert_equals(result.bytesWritten, 1);
     68 
     69        result = await transfer2;
     70        assert_equals(result.status, 'ok');
     71        assert_not_equals(result.data, null);
     72        assert_equals(result.data.byteLength, 1, 'byteLength');
     73        assert_equals(result.data.getUint8(0), 'b'.charCodeAt(0));
     74 
     75        await device.close();
     76        await transfer3;
     77      }, 'Multiple small IN transfers on an endpoint complete in order');
     78 
     79      manual_usb_serial_test(async (t, device, inEndpoint, outEndpoint) => {
     80        const bufferLength = outEndpoint.packetSize * 20;
     81        const parallelRequests = 6;
     82 
     83        // Keep track of the order in which transfers are submitted.
     84        let enqueueSequence = 0;
     85        let dequeueSequence = 0;
     86        const received = new Uint8Array(bufferLength);
     87        let receivedOffset = 0;
     88        let done = false;
     89        const transfers = [];
     90 
     91        async function readNext(sequence) {
     92          let result;
     93          try {
     94            result = await device.transferIn(inEndpoint.endpointNumber,
     95                                             inEndpoint.packetSize);
     96          } catch (e) {
     97            // The last few transfers will fail when the device is closed.
     98            assert_true(done);
     99            assert_equals(dequeueSequence++, sequence, 'dequeueSequence done');
    100            assert_equals(receivedOffset, bufferLength, 'receivedOffset');
    101            assert_equals(e.name, 'AbortError');
    102            return;
    103          }
    104 
    105          assert_equals(dequeueSequence++, sequence, 'dequeueSequence');
    106          assert_equals(result.status, 'ok');
    107          assert_not_equals(result.data, null);
    108 
    109          const data = new Uint8Array(
    110              result.data.buffer, result.data.byteOffset,
    111              result.data.byteLength);
    112          received.set(data, receivedOffset);
    113          receivedOffset += result.data.byteLength;
    114 
    115          // Check |done| because there might be zero-length packet completions
    116          // after the data has been completely received.
    117          if (!done) {
    118            if (receivedOffset == bufferLength) {
    119              done = true;
    120              assert_array_equals(received, buffer);
    121              await device.close();
    122            } else {
    123              await readNext(enqueueSequence++);
    124            }
    125          }
    126        }
    127 
    128        for (let i = 0; i < parallelRequests; ++i) {
    129          transfers.push(readNext(enqueueSequence++));
    130        }
    131 
    132        // Write a large buffer to the device which will be split up into
    133        // smaller packets when echoed back.
    134        const buffer = new Uint8Array(bufferLength);
    135        for (let i = 0; i < buffer.byteLength; ++i) {
    136          buffer[i] = i;
    137        }
    138        let result = await device.transferOut(
    139            outEndpoint.endpointNumber, buffer);
    140        assert_equals(result.status, 'ok');
    141        assert_equals(result.bytesWritten, buffer.byteLength);
    142 
    143        await Promise.all(transfers);
    144        assert_equals(dequeueSequence, enqueueSequence);
    145      }, 'Multiple large IN transfers on an endpoint complete in order');
    146    </script>
    147  </body>
    148 </html>