USB デバイス

このドキュメントでは、USB API を使用して USB デバイスと通信する方法について説明します。一部のデバイス は USB API でアクセスできません(詳しくは、下記の「注意点」をご覧ください)。Chrome アプリ シリアル デバイスや Bluetooth デバイスに接続することもできます。

USB の背景情報については、公式の USB 仕様をご覧ください。 USB in a NutShell は、参考になる合理的な集中講座です。

マニフェストの要件

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 のキオスクアプリとして実行されるアプリの場合は緩和されています。キオスクアプリの場合、 interfaceClass 権限プロパティを使用して、次のような USB デバイスへのアクセス権限をリクエストします。

  • 特定のインターフェース クラスの USB インターフェースを実装する
  • 特定の USB デバイスクラスがある

たとえば、次の usbDevices 権限は、すべての USB デバイスへのアクセス権をアプリに付与します。 プリンタ インターフェース(インターフェース クラスコード 7)と USB ハブデバイス(デバイス クラスコード)への実装 9):

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

使用可能な interfaceClass 値の一覧については、USB クラスコードをご覧ください。

interfaceClass プロパティを vendorId プロパティと組み合わせると、USB にのみアクセスできます (次の例で示すとおり)に特定のベンダーのデバイスを接続できます。

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

デバイスの検索

ユーザーのシステムに接続されている特定のデバイスが 1 つ以上あるかどうかを確認するには、 usb.getDevices メソッド:

chrome.usb.getDevices(enumerateDevicesOptions, callback);
パラメータ(型)説明
EnumerateDevicesOptions(オブジェクト)バス上のデバイスの正しいタイプを見つけるために使用される vendorId(long 型)と productId(long 型)の両方を指定するオブジェクト。マニフェストでは、アプリがアクセスするすべての vendorIddeviceId のペアをリストする usbDevices 権限セクションを宣言する必要があります。
コールバック(関数)デバイスの列挙が完了すると呼び出されます。このコールバックは、1 つのパラメータ(devicevendorIdproductId の 3 つのプロパティを持つ Device オブジェクトの配列)を指定して実行されます。device プロパティは、接続済みデバイスの不変の識別子です。ステータスは、デバイスを電源から外すまで変化しません。ID の詳細は不透明型であるため、変更される可能性があります。現在のタイプに依存しないようにします。
デバイスが見つからない場合、配列は空になります。

例:

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 メソッドを使用できます。このメソッドは、 リクエストして、1 回の呼び出しでデバイスを開くことができます。

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 プロトコルでは、コントロールバルクアイソクロナス、および 4 種類の転送が定義されています。 割り込み。以下では、これらの転送について説明します。

転送は、デバイスからホスト(インバウンド)とホストからデバイス(アウトバウンド)の双方向で行うことができます。期限 USB プロトコルの性質上、インバウンドとアウトバウンドの両方のメッセージはホストが開始する必要があります。 (Chrome アプリを実行しているパソコン)。受信(デバイスからホスト)メッセージの場合、ホスト(開始 (JavaScript コードで指定)によって「受信」フラグが付けられたメッセージを送信します。ダウンロードします。詳細情報 メッセージはデバイスによって異なりますが、通常はユーザーがリクエストしようとしているものを 削除します。その後、デバイスはリクエストされたデータを返します。デバイスの応答は、 転送方法で指定したコールバックに非同期で配信されます。アウトバウンド (ホストからデバイスへの)メッセージもこれと似ていますが、レスポンスにはデバイスから返されたデータは含まれません。

デバイスからのメッセージごとに、指定されたコールバックは、イベント オブジェクトを 次のプロパティがあります。

プロパティ説明
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 との間で送受信を行い、claimInterface は 必要ありません。この方法は簡単で、次の 3 つのパラメータを受け取ります。

chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
パラメータ(タイプ)説明
connectionHandleusb.openDevice コールバックで受信されたオブジェクト。
transferInfo以下の表の値を持つパラメータ オブジェクト。詳しくは、USB デバイス プロトコルの仕様をご確認ください。
transferCallback()転送が完了すると呼び出されます。

transferInfo オブジェクトの値:

説明
requestType(文字列)"vendor"、"standard"、"class"「reserved」です。
受信者(文字列)"device"、"interface"、"endpoint"または「other」を指定します。
方向(文字列)「in」使用できます。「in」方向は、情報をホストに送信することを
デバイスに通知します。USB バス上の通信はすべてホストが開始
するため、「in」デバイスから情報を
送り返すことができます。
リクエスト(整数)デバイスのプロトコルで定義されます。
値(整数)デバイスのプロトコルで定義されます。
インデックス(整数)デバイスのプロトコルで定義されます。
長さ(整数)方向が「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"
エンドポイント(整数): デバイスで定義。通常は、USB 検査ツールで確認できます。lsusb -v
length(整数): 方向が「in」の場合にのみ使用されます。ホストが応答で期待しているデータ量であることをデバイスに通知します。
packets × packetLength 以上にする必要があります。
データ(配列バッファ): デバイスのプロトコルによって定義されます。方向が「out」の場合にのみ使用されます。
パケット数(整数)この転送で想定されるパケットの合計数。
packageLength(整数)この転送で想定される各パケットの長さ。

例:

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

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

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

一括転送

一括転送は、信頼性が高く、時間的制約のない大量のデータを転送する場合によく使用されます。 できます。usb.bulkTransfer には 3 つのパラメータがあります。

chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
パラメータ説明
connectionHandleusb.openDevice コールバックで受信されたオブジェクト。
transferInfo以下の表の値を持つパラメータ オブジェクト。
transferCallback転送が完了すると呼び出されます。

transferInfo オブジェクトの値:

説明
方向(文字列)「in」使用できます。
エンドポイント(整数)デバイスのプロトコルで定義されます。
長さ(整数)方向が「in」の場合にのみ使用されます。ホストが要求しているデータ量であることをデバイスに通知します。
データ(ArrayBuffer)デバイスのプロトコルで定義されます。方向が「out」の場合にのみ使用されます。

例:

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

INTERRUPT 転送

割り込み転送は、時間的制約のある少量のデータに使用されます。すべての USB 通信は ホストコードは通常、デバイスを定期的にポーリングし、割り込み IN を送信します。 割り込みキューになんらかのデータがある場合に、デバイスからデータを送り返す転送 (デバイスで管理されます)。usb.interruptTransfer には次の 3 つのパラメータがあります。

chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
パラメータ説明
connectionHandleusb.openDevice コールバックで受信されたオブジェクト。
transferInfo以下の表の値を持つパラメータ オブジェクト。
transferCallback転送が完了すると呼び出されます。このコールバックにはデバイスのレスポンスが含まれていません。このコールバックの目的は、非同期転送リクエストが処理されたことをコードに通知することです。

transferInfo オブジェクトの値:

説明
方向(文字列)「in」使用できます。
エンドポイント(整数)デバイスのプロトコルで定義されます。
長さ(整数)方向が「in」の場合にのみ使用されます。ホストが要求しているデータ量であることをデバイスに通知します。
データ(ArrayBuffer)デバイスのプロトコルで定義されます。方向が「out」の場合にのみ使用されます。

例:

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

注意点

すべてのデバイスに USB API でアクセスできるわけではありません。一般に、次の理由でデバイスにアクセスできません。 オペレーティング システムのカーネルまたはネイティブ ドライバのいずれかが、ユーザー空間コードからそれらを保留します。一部 たとえば、OS X システムで HID プロファイルを持つデバイスや、USB ペンドライブなどです。

ほとんどの Linux システムでは、USB デバイスはデフォルトで読み取り専用権限にマッピングされます。Google Chat を開く方法 アクセスするには、ユーザーもそのデバイスに対する書き込みアクセス権を持っている必要があります。シンプルな解決策は、 udev ルールを設定します次の内容のファイル /etc/udev/rules.d/50-yourdevicename.rules を作成します。 content:

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

次に、udev デーモン service udev restart を再起動します。デバイスの権限は 次の手順で正しく設定できます。

  • lsusb を実行して、バス番号とデバイス番号を確認します。
  • ls -al /dev/bus/usb/[bus]/[device] を実行します。このファイルの所有者はグループ「plugdev」である必要がありますかつ、 グループの書き込み権限を設定します。

この手順では root アクセス権が必要であるため、アプリは自動的にこの処理を実行できません。おすすめの方法 エンドユーザー向けの手順を提供し、Google Cloud サポートの 説明します。

ChromeOS の場合は、usb.requestAccess を呼び出すだけです。この処理は権限ブローカーが行います。