0

我有 ac# 应用程序,可以打开安装了 Windows 驱动程序的现金抽屉。非常简单,因为驱动程序使 USB 设备显示为串行端口:

 SerialPort rsPort = new SerialPort(textBox1.Text);
 byte[] openCmd = new byte[5];
 openCmd[0] = 27;
 openCmd[1] = 112;
 openCmd[2] = 0;
 openCmd[3] = 60;
 openCmd[4] = 255;
 rsPort.Open();
 Thread.Sleep(100);
 rsPort.Write(openCmd, 0, 5);
 Thread.Sleep(100);
 rsPort.Close();

我现在正试图通过 WebUSB 打开同一个 USB 现金抽屉。我使用 ZaDig 安装了通用 USB 驱动器,Chrome 可以看到 USB 设备;可以打开设备;但是,我正在努力发送正确的命令。

这是配置的图像:

在此处输入图像描述

这是我当前的代码:

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript WebUSB</h2>

<button id="myBtn">Try it</button>

<script>
document.getElementById("myBtn").addEventListener("click", talkToDrawer);

async function talkToDrawer() {
  try {
    let device = await navigator.usb.requestDevice({ filters: [{ vendorId: 1659 }] });
    console.log(device);
    await device.open(); // Begin a session.
    await device.selectConfiguration(1); // Select configuration #1 for the device.
    await device.claimInterface(0); // Request exclusive control over interface #2.
    result = await device.controlTransferOut({
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x27,
        value: 0,
        index: 1
     });
     result = await device.controlTransferOut({
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x112,
        value: 0,
        index: 1
     });
     result = await device.controlTransferOut({
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x0,
        value: 0,
        index: 1
     });
     result = await device.controlTransferOut({
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x60,
        value: 0,
        index: 1
     });
         result = await device.controlTransferOut({
        requestType: 'standard', // tried all combinations: standard / class / vendor
        recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
        request: 0x255,
        value: 0,
        index: 1
     });

  } catch (error) {
    console.log(error);
  }
}


</script>

</body>
</html> 
4

1 回答 1

1

在不了解该设备的情况下,我在代码中看到了两个错误,

  1. 在 C# 示例中,命令[27, 112, 0, 60, 255]使用十进制给出的值,而在 Javascript 示例中,值作为十六进制常量给出。在 Javascript 中构建命令缓冲区的适当代码是,
const cmd = new Uint8Array([27, 112, 0, 60, 255]);
  1. 与其用来发送数据,不如使用并选择端点号 3controlTransferOut()最有可能是正确transferOut()的。Prolific USB 到串行转换器芯片实现类似于标准 USB 串行类的协议,它使用一对批量 IN 和 OUT 端点对于串行数据流,
result = await device.transferOut(3, cmd);

剩下的悬而未决的问题是您是否需要在发送此命令之前执行任何控制传输。控制传输用于配置设备,对于 USB 转串行芯片,这通常涉及设置波特率或将 DCE 位设置为高电平等事情。在对如何与 USB 设备进行通信进行逆向工程时,我建议使用Wireshark查看来自工作驱动程序的 USB 流量。

请注意,如果您使用的是串行设备,则应该使用Serial API。在 chrome://flags/#enable-experimental-web-platform-features 标志后面的 Chrome 中有一个实验性实现。此 API 专为专门针对串行设备的应用程序而设计,避免了重新实现 USB 转串行芯片的驱动程序。

于 2020-02-27T22:10:55.200 回答