USB 기기

이 문서에서는 USB API를 사용하여 USB 기기와 통신하는 방법을 설명합니다. 일부 기기 USB API를 통해 액세스할 수 없습니다 (자세한 내용은 아래의 주의사항 참조). Chrome 앱 직렬블루투스 기기에도 연결할 수 있습니다.

USB에 대한 배경 정보는 공식 USB 사양을 참고하세요. NutShell의 USB는 도움이 될 수 있는 합리적인 단기 집중 과정입니다.

매니페스트 요구사항

USB API는 ‘usb’ 권한을 부여할 수 있습니다.

"permissions": [
  "usb"
]

또한 지문 인쇄를 방지하려면 사용 가능한 모든 기기 유형을 선언해야 합니다. 매니페스트 파일에서 액세스할 수 있습니다 USB 기기의 각 유형은 공급업체 ID/제품 ID에 해당합니다. (VID/PID) 쌍으로 표시됩니다. usb.getDevices를 사용하여 VID/PID 쌍으로 기기를 열거할 수 있습니다.

사용하려는 각 기기 유형의 VID/PID 쌍을 usbDevices에서 선언해야 합니다. 권한을 선언할 수도 있습니다.

"permissions": [
  {
    "usbDevices": [
      {
        "vendorId": 123,
        "productId": 456
      }
    ]
  }
]

Chrome 57부터 앱 매니페스트에서 모든 기기 유형을 선언해야 하는 요구사항은 다음과 같습니다. ChromeOS 키오스크 앱으로 실행되는 앱에 적합합니다. 키오스크 앱의 경우 다음과 같은 USB 기기에 대한 액세스 권한을 요청하는 interfaceClass 권한 속성입니다.

  • 특정 인터페이스 클래스의 USB 인터페이스 구현
  • 특정 USB 기기 클래스가 있음

예를 들어 다음 usbDevices 권한은 앱이 다음을 실행하는 모든 USB 기기에 액세스하도록 허용합니다. 프린터 인터페이스 (인터페이스 클래스 코드 7)와 USB 허브 기기 (기기 클래스 코드)에 9):

"permissions": [
  {
    "usbDevices": [
      {"interfaceClass": 7},
      {"interfaceClass": 9}
    ]
  }
]

허용되는 interfaceClass 값 목록은 USB 클래스 코드를 참고하세요.

interfaceClass 속성을 vendorId 속성과 결합하여 USB에만 액세스할 수 있습니다. 특정 공급업체의 기기를 사용할 수 있습니다.

"permissions": [
  {
    "usbDevices": [
      {
        "vendorId": 123,
        "interfaceClass": 7
      }
    ]
  }
]

기기 찾기

하나 이상의 특정 기기가 사용자의 시스템에 연결되어 있는지 확인하려면 usb.getDevices 메서드를 통해 가져올 수 있습니다.

chrome.usb.getDevices(enumerateDevicesOptions, callback);
매개변수 (유형)설명
EnumerateDevicesOptions (객체)버스에서 올바른 유형의 기기를 찾는 데 사용되는 vendorId (long)과 productId (long)을 모두 지정하는 객체입니다. 매니페스트에서 앱이 액세스하려는 모든 vendorIddeviceId 쌍을 나열하는 usbDevices 권한 섹션을 선언해야 합니다.
콜백 (함수)기기 열거가 완료되면 호출됩니다. 콜백은 하나의 매개변수, 세 가지 속성(device, vendorId, productId)이 있는 Device 객체의 배열로 실행됩니다. 기기 속성은 연결된 기기의 안정적인 식별자입니다. 기기의 플러그를 뽑을 때까지 변경되지 않습니다. 식별자의 세부정보는 불투명하며 변경될 수 있습니다. 현재 유형에 의존하지 마세요.
기기를 찾을 수 없으면 배열이 비어 있게 됩니다.

예:

function onDeviceFound(devices) {
  this.devices=devices;
  if (devices) {
    if (devices.length > 0) {
      console.log("Device(s) found: "+devices.length);
    } else {
      console.log("Device could not be found");
    }
  } else {
    console.log("Permission denied.");
  }
}

chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, onDeviceFound);

기기 열기

Device 객체가 반환되면 usb.openDevice를 사용하여 기기를 열어 연결 핸들을 반환합니다. 연결 핸들을 사용해서만 USB 기기와 통신할 수 있습니다.

속성설명
기기usb.getDevices 콜백에서 객체를 수신했습니다.
데이터 (배열 버퍼)인바운드 전송이 이루어진 경우 기기에서 전송한 데이터가 포함됩니다.

예:

var usbConnection = null;
var onOpenCallback = function(connection) {
  if (connection) {
    usbConnection = connection;
    console.log("Device opened.");
  } else {
    console.log("Device failed to open.");
  }
};

chrome.usb.openDevice(device, onOpenCallback);

여는 과정을 단순화하려면 다음을 열거하는 usb.findDevices 메서드를 사용할 수 있습니다. 액세스를 요청하고 한 번의 호출로 기기를 엽니다.

chrome.usb.findDevices({"vendorId": vendorId, "productId": productId, "interfaceId": interfaceId}, callback);

이는 다음과 동일합니다.

chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, function (devices) {
  if (!devices) {
    console.log("Error enumerating devices.");
    callback();
    return;
  }
  var connections = [], pendingAccessRequests = devices.length;
  devices.forEach(function (device) {
    chrome.usb.requestAccess(interfaceId, function () {
      // No need to check for errors at this point.
      // Nothing can be done if an error occurs anyway. You should always try
      // to open the device.
      chrome.usb.openDevices(device, function (connection) {
        if (connection) connections.push(connection);
        pendingAccessRequests--;
        if (pendingAccessRequests == 0) {
          callback(connections);
        }
      });
    });
  })
});

USB로 데이터를 전송하고 기기에서 데이터 수신

USB 프로토콜은 네 가지 유형의 전송, 즉 제어, 일괄, 등시인터럽트. 이러한 이전은 아래에 설명되어 있습니다.

전송은 기기에서 호스트 (인바운드) 및 호스트-기기 (아웃바운드) 등 양방향으로 이루어질 수 있습니다. 기한 수신 및 발신 메시지는 모두 호스트가 시작해야 하므로, USB 프로토콜의 특성상 (Chrome 앱을 실행하는 컴퓨터) 수신 (기기에서 호스트) 메시지의 경우 호스트 (시작됨) '수신'으로 플래그가 지정된 메시지를 전송합니다. 전송됩니다. 이 기기에 따라 다르지만 일반적으로 사용자가 요청하는 내용에 대한 식별 정보가 있습니다. 합니다. 그러면 기기가 요청된 데이터로 응답합니다. 기기의 응답은 Chrome에 전달되며 사용자가 전송 메서드에서 지정한 콜백에 비동기식으로 전송됩니다. 아웃바운드 (호스트-디바이스) 메시지는 비슷하지만 응답에는 기기에서 반환된 데이터가 포함되지 않습니다.

기기의 각 메시지에 대해 지정된 콜백은 다음 속성이 포함됩니다.

속성설명
resultCode (정수)0은 성공, 다른 값은 실패를 나타냅니다 실패가 표시된 경우
chrome.extension.lastError에서 오류 문자열을 읽을 수
있습니다.
데이터 (배열 버퍼)인바운드 전송이 이루어진 경우 기기에서 전송한 데이터가 포함됩니다.

예:

var onTransferCallback = function(event) {
   if (event && event.resultCode === 0 && event.data) {
     console.log("got " + event.data.byteLength + " bytes");
   }
};

chrome.usb.bulkTransfer(connectionHandle, transferInfo, onTransferCallback);

전송 CONTROL

제어 전송은 일반적으로 구성 또는 명령 매개변수를 USB로 전송하거나 수신하는 데 사용됩니다. 있습니다. controlTransfer 메서드는 항상 엔드포인트 0에서 읽기/전송하기이며, requestInterface가 필요합니다. 이 메서드는 간단하며 다음 세 개의 매개변수를 수신합니다.

chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
매개변수 (유형)설명
connectionHandleusb.openDevice 콜백에서 객체를 수신했습니다.
transferInfo매개변수 객체입니다. 자세한 내용은 USB 기기 프로토콜 사양을 확인하세요.
transferCallback()전송이 완료되면 호출됩니다.

transferInfo 객체의 값:

설명
requestType (문자열)'vendor', 'standard', 'class' '예약됨'으로 표시됩니다.
수신자 (문자열)'기기', '인터페이스', '엔드포인트' 또는 '기타'.
방향 (문자열)'in' 또는 'out'입니다. 'in' 방향은 기기에 정보를 호스트로 전송해야 한다고
알리는 데 사용됩니다. USB
버스의 모든 통신은 호스트에서 시작되므로 'in' 기기가 정보를 다시 보낼 수 있도록
전송합니다.
요청 (정수)기기의 프로토콜로 정의됩니다.
값 (정수)기기의 프로토콜로 정의됩니다.
index (정수)기기의 프로토콜로 정의됩니다.
길이 (정수)방향이 'in'인 경우에만 사용됩니다. 호스트가 응답 시 기대할 수 있는 데이터의 양임을 기기에 알립니다.
데이터 (배열 버퍼)기기 프로토콜에 의해 정의되며 방향이 'out'일 때 필요합니다.

예:

var transferInfo = {
  "requestType": "vendor",
   "recipient": "device",
  "direction": "out",
  "request":  0x31,
  "value": 120,
  "index": 0,
  // Note that the ArrayBuffer, not the TypedArray itself is used.
  "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
};
chrome.usb.controlTransfer(connectionHandle, transferInfo, optionalCallback);

ISOCHRONOUS 전송

등시 전송은 가장 복잡한 유형의 USB 전송입니다. 주로 스트림에 사용됩니다. 데이터를 분석할 수 있습니다 등시 이체 (수신 또는 발신)를 시작하려면 다음과 같이 usb.isochronousTransfer 메서드를 사용해야 합니다.

chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transferCallback)
매개변수설명
connectionHandleusb.openDevice 콜백에서 객체를 수신했습니다.
isochronousTransferInfo매개변수 객체입니다.
transferCallback()전송이 완료되면 호출됩니다.

isochronousTransferInfo 객체의 값:

설명
transferInfo (객체)다음 속성을 가진 객체:
방향 (문자열): 'in' 또는 "out"입니다.
엔드포인트 (정수): 기기에서 정의합니다. 보통 lsusb -v
길이 (정수) 와 같은 USB 조사 도구를 살펴보면 찾을 수 있습니다. 방향이 'in'인 경우에만 사용됩니다. 호스트가 응답할 것으로 예상되는 데이터의 양임을 기기에 알립니다.
최소 packets × packetLength여야 합니다.
데이터 (배열 버퍼): 기기의 프로토콜에 의해 정의됩니다. 방향이 'out'일 때만 사용됩니다.
패킷 (정수)이 전송에서 예상되는 총 패킷 수입니다.
패킷 길이 (정수)이 전송에서 각 패킷의 예상 길이입니다.

예:

var transferInfo = {
  "direction": "in",
  "endpoint": 1,
  "length": 2560
};

var isoTransferInfo = {
  "transferInfo": transferInfo,
  "packets": 20,
  "packetLength": 128
};

chrome.usb.isochronousTransfer(connectionHandle, isoTransferInfo, optionalCallback);

대량 환승

일괄 전송은 일반적으로 시간에 민감하지 않은 대량의 데이터를 안정적인 있습니다. usb.bulkTransfer에는 세 가지 매개변수가 있습니다.

chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
매개변수설명
connectionHandleusb.openDevice 콜백에서 객체를 수신했습니다.
transferInfo매개변수 객체입니다.
transferCallback전송이 완료되면 호출됩니다.

transferInfo 객체의 값:

설명
방향 (문자열)'in' 또는 'out'입니다.
엔드포인트 (정수)기기의 프로토콜로 정의됩니다.
길이 (정수)방향이 'in'인 경우에만 사용됩니다. 호스트가 응답 시 기대할 수 있는 데이터의 양임을 기기에 알립니다.
data (ArrayBuffer)기기 프로토콜로 정의됩니다. 방향이 'out'일 때만 사용됩니다.

예:

var transferInfo = {
  "direction": "out",
  "endpoint": 1,
  "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
};

이전 중단

인터럽트 전송은 짧은 시간에 민감한 데이터에 사용됩니다. 모든 USB 통신은 호스트 코드는 일반적으로 장치를 주기적으로 폴링하고 인터럽트 IN을 전송합니다. 인터럽트 대기열에 무언가가 있으면 장치가 데이터를 다시 보내도록 만드는 전송 기기에서 관리합니다. usb.interruptTransfer에는 세 가지 매개변수가 있습니다.

chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
매개변수설명
connectionHandleusb.openDevice 콜백에서 객체를 수신했습니다.
transferInfo매개변수 객체입니다.
transferCallback전송이 완료되면 호출됩니다. 이 콜백에는 기기의 응답이 포함되어 있지 않습니다. 콜백의 목적은 단순히 비동기 전송 요청이 처리되었음을 코드에 알리는 것입니다.

transferInfo 객체의 값:

설명
방향 (문자열)'in' 또는 'out'입니다.
엔드포인트 (정수)기기의 프로토콜로 정의됩니다.
길이 (정수)방향이 'in'인 경우에만 사용됩니다. 호스트가 응답 시 기대할 수 있는 데이터의 양임을 기기에 알립니다.
data (ArrayBuffer)기기 프로토콜로 정의됩니다. 방향이 'out'일 때만 사용됩니다.

예:

var transferInfo = {
  "direction": "in",
  "endpoint": 1,
  "length": 2
};
chrome.usb.interruptTransfer(connectionHandle, transferInfo, optionalCallback);

주의사항

USB API를 통해 액세스할 수 없는 기기도 있습니다. 일반적으로 다음과 같은 이유로 기기에 액세스할 수 없습니다. 운영 체제의 커널 또는 네이티브 드라이버가 사용자 공간 코드에서 이들을 막아줍니다. 다소 유용함 OSX 시스템에 HID 프로필이 있는 기기와 USB 펜 드라이브를 예로 들 수 있습니다.

대부분의 Linux 시스템에서 USB 기기는 기본적으로 읽기 전용 권한으로 매핑됩니다. Google Meet의 사용자에게도 쓰기 액세스 권한이 있어야 합니다. 간단한 해결책은 udev 규칙을 설정합니다 다음을 사용하여 /etc/udev/rules.d/50-yourdevicename.rules 파일을 만듭니다. 콘텐츠:

SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

그런 다음 udev 데몬(service udev restart)을 다시 시작하면 됩니다. 기기 권한이 있는지 확인할 수 있습니다. 올바르게 설정되도록 합니다.

  • lsusb를 실행하여 버스 및 기기 번호를 찾습니다.
  • ls -al /dev/bus/usb/[bus]/[device]을 실행합니다. 이 파일은 'plugdev' 그룹에서 소유해야 합니다. 그리고 그룹 쓰기 권한

이 절차에는 루트 액세스 권한이 필요하므로 앱에서 이 작업을 자동으로 실행할 수 없습니다. 권장 조치 이 페이지의 주의사항 섹션으로 이동하여 설명

ChromeOS에서는 usb.requestAccess를 호출하면 됩니다. 권한 브로커가 이 작업을 수행합니다.