WICG / webusb

Connecting hardware to the web.
https://wicg.github.io/webusb/
Other
1.32k stars 132 forks source link

Bulk Input stack until next Bulk Output command #122

Closed hatemben closed 6 years ago

hatemben commented 6 years ago

I was trying to figure out how to get my scanner (Canon DR-M160II) working through webusb and as I am on linux, I converted Sane commands to webusb using kernel usbmon.

The same exact Sane commands fire scan event and work correctly, while when running these commands via WebUSB some BI commands seems to get stack in the scanner until another BO event is fired.

Scanner specification here

Below configuration commands :

` var dat = line2buffer('00000014 00019000 00000000 00000000 00000000 00000000',24); var dat2 = line2buffer('00000014 00019000 00000000 12000000 30000000 00000000',24); var dat3 = line2buffer('00000014 00019000 00000000 1201f000 1e000000 00000000',24); var dat4 = line2buffer('00000014 00019000 00000000 28008400 00000000 08000000',24);

var dat5 = line2buffer('00000014 00019000 00000000 00000000 00000000 00000000',24); var dat6 = line2buffer('00000014 00019000 00000000 28008400 00000000 08000000',24); var dat7 = line2buffer('00000014 00019000 00000000 28008400 00000000 08000000',24);

navigator.usb.requestDevice({ filters: [{ vendorId: 0x1083}] }) .then(selectedDevice => { device = selectedDevice; return device.open(); // Begin a session. }) .then(() => device.selectConfiguration(1)) .then(() => device.claimInterface(0)) .then(() => device.controlTransferOut({ requestType: 'standard', recipient: 'endpoint', request: 1, value: 0, index: 129})) .then(() => device.controlTransferOut({ requestType: 'standard', recipient: 'endpoint', request: 1, value: 0, index: 2})) .then(() => device.transferOut(2, dat)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 1.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 1.2:' + datalog(result.data)) }) .then(() => device.transferOut(2, dat2)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 2.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 48)) .then(result => { console.log('Conn Received 2.2:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 2.3:' + datalog(result.data)) }) .then(() => device.transferOut(2, dat3)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 3.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 30)) .then(result => { console.log('Conn Received 3.2:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 3.3:' + datalog(result.data)) }) .then(() => device.transferOut(2, dat4)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 4.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 4.2:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 4.3:' + datalog(result.data)) }) .then(() => device.controlTransferOut({ requestType: 'standard', recipient: 'endpoint', request: 1, value: 0, index: 129})) .then(() => device.controlTransferOut({ requestType: 'standard', recipient: 'endpoint', request: 1, value: 0, index: 2})) .then(() => device.transferOut(2, dat5)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 5.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) // this command goes without answer until another BO command .then(result => { console.log('Conn Received 5.2:' + datalog(result.data)) }) .then(() => device.transferOut(2, dat6)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 6.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 6.2:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 6.3:' + datalog(result.data)) }) .then(() => device.transferOut(2, dat7)) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 7.1:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 7.2:' + datalog(result.data)) }) .then(() => device.transferIn(1, 8)) .then(result => { console.log('Conn Received 7.3:' + datalog(result.data)) }) .then( result => { console.log('Connection successfull'); } ) .catch( error => { console.log(error); } );

function datalog(res){ var result = ""; for (var i = 0; i < res.byteLength; i++) { result += res.getInt8(i).toString(16); } return result; }

function line2buffer(line, length){ line = line.replace(/ +/g, ""); line = line.split("")

var buf = new ArrayBuffer(length); var dat = new Uint8Array(buf, 0, buf.length); var j = 0;

for (var i = 0; i < (line.length/2); i ++) { dat[i]=parseInt(line[j]+''+line[j+1], 16); j+=2; } return dat } `

Below the response :

screenshot from 2018-01-25 10-40-13

And once I send a BO command, I got response for previous commands

screenshot from 2018-01-25 10-40-31

Thank you

reillyeon commented 6 years ago

Chaining promises like you have means that the next transfer will wait until the previous one completes. A common pattern in USB interfaces is to issue IN and OUT transfers in parallel as the OUT transfer will trigger a response that satisfies the IN transfer.

Closing this issue as this repository is not the right place for getting help using WebUSB. For general assistance please ask questions on StackOverflow (tag: webusb). If you believe you have hit a bug in Chrome please use the Chromium bug tracker (component: Blink>USB).