webusb - 通过 WebUSB JavaScript 打开钱箱
问题描述
我有 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>
解决方案
在不了解该设备的情况下,我在代码中看到了两个错误,
- 在 C# 示例中,命令
[27, 112, 0, 60, 255]
使用十进制给出的值,而在 Javascript 示例中,值作为十六进制常量给出。在 Javascript 中构建命令缓冲区的适当代码是,
const cmd = new Uint8Array([27, 112, 0, 60, 255]);
- 与其用来发送数据,不如使用并选择端点号 3
controlTransferOut()
最有可能是正确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 转串行芯片的驱动程序。
推荐阅读
- azure-active-directory - 在 1 个视图中查看多个订阅的 Azure 门户 AAD 登录日志和活动审核日志
- android - Android Visualizer 不会从 Spotify 流媒体音乐中获取音频
- vb.net - >= 消息框序列无法正常工作
- python - 在数据框中查找对应方进行计算
- spring-data-elasticsearch - 如何使用规范在 spring-data-elasticsearch 中使用 @Field 注释进行配置分析:启用:假
- selenium - 在使用相同的 xpath 定位元素时获取 InvalidSelectorException,该 xpath 在具有 1 个匹配节点的 firepath 中运行良好
- android - Android Studio 在 3.3 版的布局编辑器中禁用 textview 周围的阴影
- html - 将查询字符串从 bot 传递到 html 页面
- c# - 将对象转换为不带标题的 CSV 字符串 Servicestack CSVSerializer
- r - 在同一面板上的密度图顶部堆叠点图并让轴对齐