thegecko / webusb

Node.js implementation of the WebUSB Specification
https://thegecko.github.io/webusb/
MIT License
183 stars 27 forks source link

onReceiveError Error: transferIn error: endpoint not found #18

Closed monteslu closed 6 years ago

monteslu commented 6 years ago

Really close to having things working, but I hit this now :)

I'm trying to replicate this demo: https://github.com/webusb/arduino/tree/gh-pages/demos/console I'm using an Arduino Leonardo, with the sketch from that demo loaded. I'm able to send bytes, but not able to receive bytes from the arduino

Here's the sample code I'm using which is a simplified version of the console demo.

global.navigator = {};
navigator.usb = require('webusb').usb;
var TextEncoder = require('text-encoding').TextEncoder;

global.textEncoder = new TextEncoder();

var serial = {};

(function() {
  'use strict';

  serial.getPorts = function() {
    return navigator.usb.getDevices().then(devices => {
      return devices.map(device => new serial.Port(device));
    });
  };

  serial.requestPort = function() {
    const filters = [
      { 'vendorId': 0x2341, 'productId': 0x8036 },
      { 'vendorId': 0x2341, 'productId': 0x8037 },
      { 'vendorId': 0x2341, 'productId': 0x804d },
      { 'vendorId': 0x2341, 'productId': 0x804e },
      { 'vendorId': 0x2341, 'productId': 0x804f },
      { 'vendorId': 0x2341, 'productId': 0x8050 },
    ];
    return navigator.usb.requestDevice({ 'filters': filters }).then(
      device => new serial.Port(device)
    );
  }

  serial.Port = function(device) {
    this.device_ = device;
  };

  serial.Port.prototype.connect = function() {
    let readLoop = () => {
      this.device_.transferIn(5, 64).then(result => {
        this.onReceive(result.data);
        readLoop();
      }, error => {
        console.log('onReceiveError', error);
        // this.onReceiveError(error);
      });
    };

    return this.device_.open()
        .then(() => {
          if (this.device_.configuration === null) {
            return this.device_.selectConfiguration(1);
          }
        })
        .then(() => this.device_.claimInterface(2))
        .then(() => this.device_.selectAlternateInterface(2, 0))
        .then(() => this.device_.controlTransferOut({
            'requestType': 'class',
            'recipient': 'interface',
            'request': 0x22,
            'value': 0x01,
            'index': 0x02}))
        .then(() => {
          readLoop();
        });
  };

  serial.Port.prototype.disconnect = function() {
    return this.device_.controlTransferOut({
            'requestType': 'class',
            'recipient': 'interface',
            'request': 0x22,
            'value': 0x00,
            'index': 0x02})
        .then(() => this.device_.close());
  };

  serial.Port.prototype.send = function(data) {
    return this.device_.transferOut(4, data);
  };
})();

var port;

function connect() {
  console.log('Connecting to ' + port.device_.productName + '...');
  port.connect().then(() => {
    console.log(port);
    console.log('Connected.');
    port.onReceive = data => {
      let textDecoder = new TextDecoder();
      console.log(textDecoder.decode(data));
    }
    port.onReceiveError = error => {
      console.log('Receive error: ' + error);
    };

    port.send(textEncoder.encode('H'));

  }, error => {
    console.log('Connection error: ' + error);
  });
};

serial.requestPort().then(selectedPort => {
  global.port = port = selectedPort;
  connect();
}).catch(error => {
  console.log('Connection error: ' + error);
});

The readLooop() fails. It appears that https://github.com/thegecko/webusb/blob/master/src/device.ts#L452 does not return an endpoint.

thegecko commented 6 years ago

Closing in favour of #19