USB-Geräte

In diesem Dokument wird die USB API zur Kommunikation mit USB-Geräten beschrieben. Einige Geräte sind nicht über die USB API zugänglich. Weitere Informationen finden Sie unten im Abschnitt Vorbehalte. Chrome-Apps kann auch eine Verbindung zu Seriellen und Bluetooth-Geräten herstellen.

Hintergrundinformationen zu USB finden Sie in den offiziellen USB-Spezifikationen. USB in a NutShell ist ein vernünftiger Crashkurs, den Sie vielleicht hilfreich finden.

Manifestanforderung

Für die USB API ist das USB-Kabel erforderlich. Berechtigung in der Manifestdatei:

"permissions": [
  "usb"
]

Außerdem müssen Sie alle Gerätetypen angeben, die Sie verwenden möchten, um Fingerabdrucke zu verhindern. auf die Sie in der Manifestdatei zugreifen möchten. Jeder USB-Gerätetyp entspricht einer Anbieter-ID/Produkt-ID. (VID/PID)-Paar. Du kannst usb.getDevices verwenden, um Geräte nach ihrem VID/PID-Paar aufzulisten.

Du musst die VID/PID-Paare für jeden Gerätetyp, den du verwenden möchtest, unter der usbDevices deklarieren in der Manifestdatei Ihrer App, wie im folgenden Beispiel gezeigt:

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

Seit Chrome 57 müssen alle Gerätetypen im App-Manifest deklariert werden: für Apps, die als ChromeOS-Kiosk-Apps ausgeführt werden. Für Kiosk-Apps können Sie die interfaceClass, um die Berechtigung für den Zugriff auf USB-Geräte anzufordern, die:

  • USB-Schnittstelle einer bestimmten Interface-Klasse implementieren
  • eine bestimmte USB-Geräteklasse haben,

Mit der folgenden usbDevices-Berechtigung würde z. B. einer App Zugriff auf alle USB-Geräte gewährt, die Druckerschnittstelle (Schnittstellencode 7) und USB-Hub-Geräte (Geräteklassencode 7) implementieren 9):

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

Eine Liste der zulässigen interfaceClass-Werte findest du unter USB-Klassencodes.

Die Eigenschaft interfaceClass kann mit der Eigenschaft vendorId kombiniert werden, um nur Zugriff auf USB zu erhalten. Geräte von einem bestimmten Anbieter, wie das folgende Beispiel zeigt:

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

Gerät finden

Um festzustellen, ob ein oder mehrere Geräte mit dem System eines Nutzers verbunden sind, verwende die usb.getDevices-Methode:

chrome.usb.getDevices(enumerateDevicesOptions, callback);
Parameter (Typ)Beschreibung
EnumerateDevicesOptions (Objekt)Ein Objekt, das sowohl vendorId (long) als auch productId (long) angibt, mit dem der richtige Gerätetyp im Bus ermittelt wird. In deinem Manifest muss der Berechtigungsabschnitt „usbDevices“ deklariert werden, in dem alle vendorId- und deviceId-Paare aufgeführt sind, auf die deine App zugreifen möchte.
Callback (Funktion)Wird aufgerufen, wenn die Geräteauflistung abgeschlossen ist. Der Callback wird mit einem Parameter ausgeführt. Dabei handelt es sich um ein Array aus Device-Objekten mit drei Eigenschaften: device, vendorId und productId. Die Geräteeigenschaft ist eine stabile Kennung für ein verbundenes Gerät. Sie ändert sich erst, wenn das Gerät vom Stromnetz getrennt ist. Die Details der Kennung sind undurchsichtig und können sich ändern. Verlassen Sie sich nicht auf den aktuellen Typ.
Wenn keine Geräte gefunden werden, ist das Array leer.

Beispiel:

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);

Gerät öffnen

Nachdem die Device-Objekte zurückgegeben wurden, können Sie ein Gerät mit usb.openDevice öffnen, um eine Alias. Die Kommunikation mit USB-Geräten ist nur über Verbindungs-Handles möglich.

AttributBeschreibung
GerätIm usb.getDevices-Rückruf empfangenes Objekt.
Daten (Arraybuffer)Enthält die Daten, die vom Gerät bei einer eingehenden Übertragung gesendet wurden.

Beispiel:

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);

Um das Öffnen zu vereinfachen, können Sie die Methode usb.findDevices verwenden, die folgende Daten enthält: fordert Zugriff an und öffnet Geräte in einem Aufruf:

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

Dies entspricht:

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);
        }
      });
    });
  })
});

Über USB werden Daten von einem Gerät übertragen und von diesem empfangen

Das USB-Protokoll definiert vier Arten von Übertragungen: Kontrolle, Bulk, isochrone und unterbrechen. Diese Übertragungen werden im Folgenden beschrieben.

Übertragungen können in beide Richtungen erfolgen: vom Gerät zum Host (eingehend) und vom Host zum Gerät (ausgehend). Fällig Aufgrund des USB-Protokolls müssen sowohl eingehende als auch ausgehende Nachrichten vom Host initiiert werden. Das ist der Computer, auf dem die Chrome App ausgeführt wird. Bei eingehenden Nachrichten (Gerät-zu-Host) hat der Host (initiiert) durch Ihren JavaScript-Code) sendet eine Nachricht, die als "eingehend" gekennzeichnet ist. auf das Gerät übertragen. Die Details der Nachricht hängt vom Gerät ab, enthält aber in der Regel eine Identifizierung Ihrer Anfrage daraus entfernt werden. Das Gerät antwortet dann mit den angeforderten Daten. Die Antwort des Geräts wird von Chrome und wird asynchron an den Callback gesendet, den Sie in der Übertragungsmethode angeben. Ein Outbound (Host-to-Device) ist ähnlich, aber die Antwort enthält keine vom Gerät zurückgegebenen Daten.

Für jede Nachricht vom Gerät empfängt der angegebene Callback ein Ereignisobjekt mit dem Parameter folgenden Properties:

AttributBeschreibung
resultCode (Ganzzahl)0 bedeutet Erfolg; andere Werte auf Fehler hinweisen. Ein Fehlerstring kann
aus chrome.extension.lastError gelesen werden, wenn ein Fehler
angegeben wird.
Daten (Arraybuffer)Enthält die Daten, die vom Gerät bei einer eingehenden Übertragung gesendet wurden.

Beispiel:

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 Übertragungen

Kontrollübertragungen werden in der Regel verwendet, um Konfigurations- oder Befehlsparameter an einen USB-Speicher zu senden oder zu empfangen. . Die Methode „controlTransfer“ sendet immer an Endpunkt 0 bzw. liest von diesem aus und kein „claimInterface“ ist erforderlich. Die Methode ist einfach und erhält drei Parameter:

chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
Parameter (Typen)Beschreibung
connectionHandleObjekt im usb.openDevice-Rückruf empfangen.
transferInfoParameterobjekt mit Werten aus der Tabelle unten. Weitere Informationen finden Sie in den Spezifikationen des USB-Geräteprotokolls.
transferCallback()Wird aufgerufen, wenn die Übertragung abgeschlossen ist.

Werte für das Objekt transferInfo:

WertBeschreibung
requestType (String)"vendor", "standard", "class" oder „reserviert“.
Empfänger (String)"Gerät", "Schnittstelle", "Endpunkt" oder „Sonstiges“.
Richtung (String)„in“ oder „aus“. Das „In“ Richtung wird das Gerät darüber informiert,
dass es Informationen an den Host senden soll. Die gesamte Kommunikation über einen USB
-Bus wird vom Host initiiert. Verwenden Sie daher ein „in“. übertragen, damit ein Gerät
Informationen zurücksenden kann.
Anfrage (Ganzzahl)Durch das Protokoll Ihres Geräts definiert.
Wert (Ganzzahl)Durch das Protokoll Ihres Geräts definiert.
Index (Ganzzahl)Durch das Protokoll Ihres Geräts definiert.
Länge (Ganzzahl)Wird nur verwendet, wenn die Richtung „in“ ist. Informiert das Gerät darüber, dass dies die Datenmenge ist, die der Host als Antwort erwartet.
Daten (Arraybuffer)Durch das Protokoll deines Geräts definiert; erforderlich, wenn die Richtung „out“ ist.

Beispiel:

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-Übertragungen

Isochrone Übertragungen sind die komplexeste Art der USB-Übertragung. Sie werden häufig für Streams verwendet. wie Video und Ton. Zum Starten einer isochronen Übertragung (eingehend oder ausgehend) Sie müssen die Methode usb.isochronousTransfer verwenden:

chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transferCallback)
ParameterBeschreibung
connectionHandleObjekt im usb.openDevice-Rückruf empfangen.
isochronousTransferInfoParameterobjekt mit den Werten in der Tabelle unten.
transferCallback()Wird aufgerufen, wenn die Übertragung abgeschlossen ist.

Werte für das Objekt isochronousTransferInfo:

WertBeschreibung
transferInfo (Objekt)Ein Objekt mit den folgenden Attributen:
direction (String): "in" oder „out“.
Endpunkt (Ganzzahl): definiert durch dein Gerät. Für gewöhnlich ist ein USB-Instrospektivenwerkzeug verfügbar, z. B. lsusb -v
Länge (Ganzzahl): wird nur verwendet, wenn die Richtung „in“ ist. Informiert das Gerät darüber, dass dies die Datenmenge ist, die der Host als Antwort erwartet.
Sollte MINDESTENS packets × packetLength sein.
Daten (Array-Zwischenspeicher): durch das Protokoll des Geräts definiert; wird nur verwendet, wenn die Richtung „out“ ist.
Pakete (Ganzzahl)Gesamtzahl der Pakete, die bei dieser Übertragung erwartet werden.
packageLength (Ganzzahl)Erwartete Länge jedes Pakets in dieser Übertragung.

Beispiel:

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

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

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

BULK-Übertragungen

Bulk-Übertragungen werden in der Regel verwendet, um eine große Menge an nicht zeitkritischen Daten in einer zuverlässigen usb.bulkTransfer hat drei Parameter:

chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
ParameterBeschreibung
connectionHandleObjekt im usb.openDevice-Rückruf empfangen.
transferInfoParameterobjekt mit den Werten in der Tabelle unten.
transferCallbackWird aufgerufen, wenn die Übertragung abgeschlossen ist.

Werte für das Objekt transferInfo:

WertBeschreibung
Richtung (String)„in“ oder „aus“.
Endpunkt (Ganzzahl)Durch das Protokoll Ihres Geräts definiert.
Länge (Ganzzahl)Wird nur verwendet, wenn die Richtung „in“ ist. Informiert das Gerät darüber, dass dies die Datenmenge ist, die der Host als Antwort erwartet.
Daten (ArrayBuffer)Durch das Protokoll Ihres Geräts definiert. wird nur verwendet, wenn die Richtung „out“ ist.

Beispiel:

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

UNTERBRECHUNGSFREISTELLUNGEN

Unterbrochene Übertragungen werden für kleine zeitkritische Daten verwendet. Da die gesamte USB-Kommunikation vom Host eingeleitet wird, fragt der Hostcode normalerweise in regelmäßigen Abständen das Gerät ab, um eine Unterbrechung Übertragungen, durch die das Gerät Daten zurücksendet, wenn sich etwas in der Unterbrechungswarteschlange befindet (vom Gerät gepflegt) usb.interruptTransfer hat drei Parameter:

chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
ParameterBeschreibung
connectionHandleObjekt im usb.openDevice-Rückruf empfangen.
transferInfoParameterobjekt mit den Werten in der Tabelle unten.
transferCallbackWird aufgerufen, wenn die Übertragung abgeschlossen ist. Beachten Sie, dass dieser Callback nicht die Geräteantwort enthält. Der Zweck des Callbacks besteht darin, Ihren Code darüber zu informieren, dass die asynchronen Übertragungsanfragen verarbeitet wurden.

Werte für das Objekt transferInfo:

WertBeschreibung
Richtung (String)„in“ oder „aus“.
Endpunkt (Ganzzahl)Durch das Protokoll Ihres Geräts definiert.
Länge (Ganzzahl)Wird nur verwendet, wenn die Richtung „in“ ist. Informiert das Gerät darüber, dass dies die Datenmenge ist, die der Host als Antwort erwartet.
Daten (ArrayBuffer)Durch das Protokoll Ihres Geräts definiert. wird nur verwendet, wenn die Richtung „out“ ist.

Beispiel:

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

Vorsichtsmaßnahmen

Nicht auf alle Geräte kann über die USB API zugegriffen werden. Im Allgemeinen sind Geräte nicht barrierefrei, werden sie entweder vom Kernel des Betriebssystems oder von einem nativen Treiber abgehalten. Einige Beispiele hierfür sind Geräte mit HID-Profilen auf OSX-Systemen und USB-Sticks.

Auf den meisten Linux-Systemen werden USB-Geräte standardmäßig mit Leseberechtigungen verknüpft. So öffnen Sie eine Gerät über diese API verwenden, muss Ihr Nutzer auch Schreibzugriff darauf haben. Eine einfache Lösung besteht darin, eine udev-Regel festlegen. Erstellen Sie die Datei /etc/udev/rules.d/50-yourdevicename.rules mit folgendem Code: Inhalt:

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

Starten Sie dann einfach den udev-Daemon neu: service udev restart. Sie können prüfen, ob Geräteberechtigungen indem Sie die folgenden Schritte ausführen:

  • Führen Sie lsusb aus, um die Bus- und Gerätenummern zu ermitteln.
  • Führen Sie ls -al /dev/bus/usb/[bus]/[device] aus. Diese Datei sollte der Gruppe „plugdev“ gehören und haben Schreibberechtigungen für Gruppen.

Ihre App kann dies nicht automatisch tun, da hierfür Root-Zugriff erforderlich ist. Wir empfehlen, Sie Endnutzern eine Anleitung zur Verfügung stellen und auf den Abschnitt Vorsichtsmaßnahmen auf dieser Seite verlinken, Erklärung.

Unter ChromeOS rufen Sie einfach usb.requestAccess auf. Der Permission-Broker erledigt dies für Sie.