0

无法定义要发送到我的串行设备(通过 USB 连接)的数据。

我如何获得设备:

function callTransfer(temp1) {
    temp1.controlTransferOut({
        requestType: 'standard',
        recipient: 'device',
        request: 0x07,
        value: 0x08,
        index: 0x04
    })
        .then(() => {
            console.log('sent req'); device.transferIn(1, 32)
        }) // Waiting for 32 bytes of data from endpoint #1.
        .then(result => {
            console.log(result);
        })
        .catch(error => {
            console.log(error);
        });
}

navigator.usb.requestDevice({
    filters: [{}]
}).then((selectedDevice) => {
    device = selectedDevice;
    return device.open()
        .then(() => device.reset())
        .then(() => device.selectConfiguration(1))
        .then(() => device.claimInterface(device.configuration.interfaces[0].interfaceNumber))
        .then(() => {
            callTransfer(device);
        })
});

之后我可以进入wireshark并读取值:

recipient = usb.bmRequestType (but not freely definable it is an enum - link see below)
request = usb.setup.bRequest
value = usb.setup.wValue
index = usb.setup.wIndex

但对于我的设备,我还需要设置 usb.LanguageId、usb.DescriptorIndex 等。收件人也不属于这 4 个枚举

有没有办法发送原始数据或设置更多属性?

知道有transferOut功能,但是当我尝试它时,它只是在最后转储它,这对我的问题不起作用。

试图更改接收者或请求参数,但它不起作用,或者更糟糕的是,向 controlTransferOut 对象添加更多参数似乎没有改变任何东西。

资源:

  1. WICG
  2. MDN 网络文档
  3. 谷歌开发者网络更新
  4. WebUSB API Arduino 示例代码
  5. Google Developers 为 WebUSB 构建设备
4

2 回答 2

1

您发送的请求看起来像一个 SET_DESCRIPTOR 请求。由于您提到了语言 ID,我假设您正在尝试设置字符串描述符。设置字符串描述符时,应分别在“index”参数和“value”参数的低字节中设置语言 ID 和描述符索引参数。“value”参数的高字节应设置为 0x03,表示您正在设置字符串描述符。“数据”参数应该是一个ArrayBuffer包含您要发送到设备的描述符。

来源:https ://www.beyondlogic.org/usbnutshell/usb6.shtml

bmRequestType 字段是根据“recipient”和“requestType”参数以及您是否调用controlTransferIn()或来设置的controlTransferOut()。这使您可以完全控制该字段。

来源:https ://wigg.github.io/webusb/#control-transfer

它可能有助于解释您要完成的工作。我不知道接受 SET_DESCRIPTOR 请求的 USB 串行设备。回答此类问题时,您要连接的设备的文档很有帮助。

于 2020-05-22T17:23:11.330 回答
0

所以这就是我想出的(非常感谢@Reilly Grant)

负载装置

let y;
navigator.usb.requestDevice({
    filters: [{}]
}).then((selectedDevice) => {
    device = selectedDevice;
    return device.open()
        .then(() => device.reset())
        .then(() => device.selectConfiguration(1))
        .then(() => device.claimInterface(device.configuration.interfaces[0].interfaceNumber))
        .then(() => {
            y = device;
        })
});

请求设备名称(只是一个例子)

y.controlTransferIn({
        requestType: 'standard',
        recipient: 'device',
        request: 0x06,
        value: 0x0302,
        index: 0x409
    }, 255)
        .then(result => {
            let decoder = new TextDecoder()
            console.log(decoder.decode(result.data));
            console.log('sent req');
        }).catch(error => {
            console.log(error);
        });

这些资源对我有帮助:

仔细阅读它们。这需要一点时间,但这一切都是值得的!

此外,如果您不知道,您可以像这样添加多个十六进制值:0x2341,其中 23 是第一对,41 是第二对。

如果您在卸载/取消绑定设备时遇到问题,请查看此其他帖子:取消绑定 USB 接口以使用 Chrome Web USB API


按照 USBControlTransferParameters 的细分(controlTransferIn 的对象)

要了解发送每个参数的内容,请查看“标准设备请求”。在我的示例中,我想获取设备的名称。所以我检查了bRequest(wireshark中的信息),上面写着“GET_DESCRIPTOR”,你会发现它旁边的0x06是请求参数(再次检查“标准设备请求”桌子)。您还可以从 wireshark 获取 requestType 和接收者(您会在 bmRequestType 下找到它,但不要被愚弄这些数字不起作用,所以只需检查它显示的 requestType 和接收者并将它们填写为字符串。这个值是棘手的原因对于这个请求,您必须添加 2 个十六进制值(索引和描述符类型 | 按此顺序执行,beyondlogic 的文档在这里我认为是错误的)。在wireshark 中,它是 DescriptorIndex 和 bDescriptorType。所以最后你得到了索引,我认为你可以把它留空,意思是 0x00,但它是为了定义语言,所以我添加了它(在 wireshark 中它是 LanguageId)。然后 255 是我再次从 wireshark 得到的长度,但它应该是返回的长度。


如果使用 linux,请设置权限

它将发送一条错误消息,例如:访问被拒绝

在最后结帐此页面:访问 Web 上的 USB 设备

SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
于 2020-05-23T00:06:15.580 回答