Открыть денежный ящик через WebUSB JavaScript

У меня есть приложение C #, которое может открывать денежный ящик с установленным драйвером 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();

Я сейчас пытаюсь открыть тот же денежный ящик USB через WebUSB. Я использовал 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> 

person Display Name    schedule 26.02.2020    source источник
comment
НЕ размещайте изображения кода, данных, сообщений об ошибках и т. д. - скопируйте или введите текст в вопрос. Как задать вопрос   -  person Rob    schedule 26.02.2020


Ответы (1)


Не зная больше об устройстве, я вижу в коде две ошибки:

  1. В примере C # это команда [27, 112, 0, 60, 255] со значениями, указанными в десятичном формате, а в примере с Javascript значения задаются как шестнадцатеричные константы. Соответствующий код для создания буфера команд в Javascript:
const cmd = new Uint8Array([27, 112, 0, 60, 255]);
  1. Вместо использования controlTransferOut() для отправки данных, скорее всего, будет правильным использовать transferOut() и выбрать конечную точку номер 3. Микросхемы преобразователя USB в последовательный порт Prolific реализуют протокол, аналогичный стандартному последовательному классу USB, который использует пару массивов IN и Конечные точки OUT для последовательного потока данных,
result = await device.transferOut(3, cmd);

Остается открытым вопрос, нужно ли выполнять какие-либо передачи управления перед отправкой этой команды. Передача управления используется для настройки устройства, а для микросхемы USB-последовательный порт это обычно включает в себя такие вещи, как установка скорости передачи данных или установка высокого уровня бита DCE. При обратном проектировании того, как взаимодействовать с USB-устройством, я рекомендую использовать Wireshark для просмотра USB-трафика с рабочего Водитель.

Обратите внимание, что если вы работаете с последовательным устройством, вам следует взять Последовательный API. В Chrome есть экспериментальная реализация, доступная за флагом chrome: // flags / # enable-experimental-web-platform-features. Этот API разработан для приложений, специально нацеленных на последовательные устройства, и позволяет избежать повторной реализации драйвера для микросхемы USB-to-Serial.

person Reilly Grant    schedule 27.02.2020