USB-apparaten

Dit document beschrijft hoe u de USB API gebruikt om met USB-apparaten te communiceren. Sommige apparaten zijn niet toegankelijk via de USB API (zie het gedeelte Waarschuwingen hieronder voor meer informatie). Chrome Apps kunnen ook verbinding maken met seriële en Bluetooth- apparaten.

Voor achtergrondinformatie over USB raadpleegt u de officiële USB-specificaties . USB in een notendop is een redelijke spoedcursus die u wellicht nuttig vindt.

Duidelijke eis

De USB API vereist de 'usb'-machtiging in het manifestbestand:

"permissions": [
  "usb"
]

Om vingerafdrukken te voorkomen, moet u bovendien alle apparaattypen waartoe u toegang wilt hebben, in het manifestbestand declareren. Elk type USB-apparaat komt overeen met een leveranciers-ID/product-ID (VID/PID)-paar. U kunt usb.getDevices gebruiken om apparaten te inventariseren op basis van hun VID/PID-paar.

U moet de VID/PID-paren declareren voor elk type apparaat dat u wilt gebruiken onder de machtiging usbDevices in het manifestbestand van uw app, zoals weergegeven in het onderstaande voorbeeld:

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

Sinds Chrome 57 zijn de vereisten voor het declareren van alle apparaattypen in het app-manifest versoepeld voor apps die worden uitgevoerd als ChromeOS- kiosk-apps . Voor kiosk-apps kunt u de toestemmingseigenschap interfaceClass gebruiken om toestemming te vragen voor toegang tot USB-apparaten die:

  • een USB-interface van een specifieke interfaceklasse implementeren
  • een specifieke USB-apparaatklasse hebben

Met de volgende machtiging usbDevices zou een app bijvoorbeeld toegang krijgen tot alle USB-apparaten die een printerinterface implementeren (interfaceklassecode 7) en tot USB-hubapparaten (apparaatklassecode 9):

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

Zie USB-klassecodes voor de lijst met acceptabele interfaceClass waarden.

De eigenschap interfaceClass kan worden gecombineerd met de eigenschap vendorId om alleen toegang te krijgen tot USB-apparaten van een specifieke leverancier, zoals blijkt uit het volgende voorbeeld:

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

Een apparaat zoeken

Gebruik de methode usb.getDevices om te bepalen of een of meer specifieke apparaten zijn aangesloten op het systeem van een gebruiker:

chrome.usb.getDevices(enumerateDevicesOptions, callback);
Parameter (type) Beschrijving
EnumerateDevicesOptions (object) Een object dat zowel een vendorId (lang) als productId (lang) specificeert, gebruikt om het juiste type apparaat op de bus te vinden. Uw manifest moet de machtigingssectie usbDevices declareren met alle vendorId en deviceId paren waartoe uw app toegang wil hebben.
terugbellen (functie) Wordt aangeroepen wanneer de inventarisatie van het apparaat is voltooid. De callback wordt uitgevoerd met één parameter, een array van Device objecten met drie eigenschappen: device , vendorId , productId . De apparaateigenschap is een stabiele identificatie voor een aangesloten apparaat. Het zal niet veranderen totdat het apparaat wordt losgekoppeld. De details van de identificatie zijn ondoorzichtig en kunnen worden gewijzigd. Vertrouw niet op het huidige type.
Als er geen apparaten worden gevonden, is de array leeg.

Voorbeeld:

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

Een apparaat openen

Zodra de Device objecten zijn geretourneerd, kunt u een apparaat openen met usb.openDevice om een ​​verbindingsingang te verkrijgen. U kunt alleen met USB-apparaten communiceren via verbindingsgrepen.

Eigendom Beschrijving
apparaat Object ontvangen in usb.getDevices -callback.
gegevens (arraybuffer) Bevat de gegevens die door het apparaat zijn verzonden als de overdracht inkomend was.

Voorbeeld:

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

Om het openingsproces te vereenvoudigen, kunt u de methode usb.findDevices gebruiken, die apparaten in één aanroep opsomt, toegang vraagt ​​en opent:

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

wat gelijk is aan:

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-overdracht en het ontvangen van gegevens van een apparaat

Het USB-protocol definieert vier soorten overdrachten: controle , bulk , isochroon en interrupt . Deze overdrachten worden hieronder beschreven.

Overdrachten kunnen in beide richtingen plaatsvinden: apparaat-naar-host (inkomend) en host-naar-apparaat (uitgaand). Vanwege de aard van het USB-protocol moeten zowel inkomende als uitgaande berichten worden geïnitieerd door de host (de computer waarop de Chrome-app draait). Voor inkomende berichten (apparaat-naar-host) stuurt de host (geïnitieerd door uw JavaScript-code) een bericht met de vlag 'inkomend' naar het apparaat. De details van het bericht zijn afhankelijk van het apparaat, maar bevatten meestal enige identificatie van wat u ervan vraagt. Het apparaat reageert vervolgens met de gevraagde gegevens. De reactie van het apparaat wordt afgehandeld door Chrome en asynchroon afgeleverd bij de callback die u opgeeft in de overdrachtsmethode. Een uitgaand bericht (host-naar-apparaat) is vergelijkbaar, maar het antwoord bevat geen gegevens die door het apparaat worden geretourneerd.

Voor elk bericht van het apparaat ontvangt de opgegeven callback een gebeurtenisobject met de volgende eigenschappen:

Eigendom Beschrijving
resultaatcode (geheel getal) 0 is succes; andere waarden duiden op een storing. Een foutreeks kan zijn
lees van chrome.extension.lastError wanneer er een fout is
aangeduid.
gegevens (arraybuffer) Bevat de gegevens die door het apparaat zijn verzonden als de overdracht inkomend was.

Voorbeeld:

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-overdrachten

Besturingsoverdrachten worden over het algemeen gebruikt om configuratie- of opdrachtparameters naar een USB-apparaat te verzenden of te ontvangen. De controlTransfer-methode verzendt altijd naar/leest vanaf eindpunt 0 en er is geen claimInterface vereist. De methode is eenvoudig en ontvangt drie parameters:

chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
Parameter (typen) Beschrijving
verbindingHandgreep Object ontvangen in usb.openDevice -callback.
overdrachtInfo Parameterobject met waarden uit de onderstaande tabel. Controleer de protocolspecificaties van uw USB-apparaat voor meer informatie.
overdrachtTerugbellen() Wordt aangeroepen wanneer de overdracht is voltooid.

Waarden voor transferInfo object:

Waarde Beschrijving
requestType (tekenreeks) "leverancier", "standaard", "klasse" of "gereserveerd".
ontvanger (tekenreeks) "apparaat", "interface", "eindpunt" of "anders".
richting (snaar) "in of uit". De "in"-richting wordt gebruikt om het apparaat hiervan op de hoogte te stellen
het moet informatie naar de host sturen. Alle communicatie op een USB
bus wordt door de host geïnitieerd, dus gebruik een "in"-overdracht om een ​​apparaat dit toe te staan
stuur informatie terug.
verzoek (geheel getal) Gedefinieerd door het protocol van uw apparaat.
waarde (geheel getal) Gedefinieerd door het protocol van uw apparaat.
index (geheel getal) Gedefinieerd door het protocol van uw apparaat.
lengte (geheel getal) Alleen gebruikt als de richting "in" is. Laat het apparaat weten dat dit de hoeveelheid gegevens is die de host als reactie verwacht.
gegevens (arraybuffer) Gedefinieerd door het protocol van uw apparaat, vereist wanneer de richting "uit" is.

Voorbeeld:

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

ISOCHRONEUZE overdrachten

Isochrone overdrachten zijn het meest complexe type USB-overdracht. Ze worden vaak gebruikt voor gegevensstromen, zoals video en geluid. Om een ​​isochrone overdracht (inkomend of uitgaand) te initiëren, moet u de methode usb.isochronousTransfer gebruiken:

chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transferCallback)
Parameter Beschrijving
verbindingHandgreep Object ontvangen in usb.openDevice -callback.
isochroonTransferInfo Parameterobject met de waarden in de onderstaande tabel.
overdrachtTerugbellen() Wordt aangeroepen wanneer de overdracht is voltooid.

Waarden voor isochronousTransferInfo -object:

Waarde Beschrijving
overdrachtInfo (object) Een object met de volgende kenmerken:
richting (string): "in" of "uit".
eindpunt (geheel getal): gedefinieerd door uw apparaat. Meestal kan dit worden gevonden door naar een USB-instrospectietool te kijken, zoals lsusb -v
lengte (geheel getal): alleen gebruikt als de richting "in" is. Laat het apparaat weten dat dit de hoeveelheid gegevens is die de host als reactie verwacht.
Moet MINSTENS packets × packetLength zijn.
gegevens (arraybuffer): gedefinieerd door het protocol van uw apparaat; alleen gebruikt als de richting "uit" is.
pakketten (geheel getal) Totaal aantal verwachte pakketten bij deze overdracht.
pakketlengte (geheel getal) Verwachte lengte van elk pakket in deze overdracht.

Voorbeeld:

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

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

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

BULK-overdrachten

Bulkoverdrachten worden doorgaans gebruikt om een ​​grote hoeveelheid niet-tijdgevoelige gegevens op een betrouwbare manier over te dragen. usb.bulkTransfer heeft drie parameters:

chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
Parameter Beschrijving
verbindingHandgreep Object ontvangen in usb.openDevice -callback.
overdrachtInfo Parameterobject met de waarden in de onderstaande tabel.
doorverbindenTerugbellen Wordt aangeroepen wanneer de overdracht is voltooid.

Waarden voor transferInfo object:

Waarde Beschrijving
richting (snaar) "in of uit".
eindpunt (geheel getal) Gedefinieerd door het protocol van uw apparaat.
lengte (geheel getal) Alleen gebruikt als de richting "in" is. Laat het apparaat weten dat dit de hoeveelheid gegevens is die de host als reactie verwacht.
gegevens (ArrayBuffer) Gedefinieerd door het protocol van uw apparaat; alleen gebruikt als de richting "uit" is.

Voorbeeld:

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

ONDERBREKEN overdrachten

Onderbrekende overdrachten worden gebruikt voor kleine hoeveelheden tijdgevoelige gegevens. Omdat alle USB-communicatie door de host wordt geïnitieerd, ondervraagt ​​de hostcode het apparaat gewoonlijk periodiek, waarbij interrupt IN-overdrachten worden verzonden, waardoor het apparaat gegevens terugstuurt als er iets in de interruptwachtrij staat (die door het apparaat wordt onderhouden). usb.interruptTransfer heeft drie parameters:

chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
Parameter Beschrijving
verbindingHandgreep Object ontvangen in usb.openDevice -callback.
overdrachtInfo Parameterobject met de waarden in de onderstaande tabel.
doorverbindenTerugbellen Wordt aangeroepen wanneer de overdracht is voltooid. Merk op dat deze callback niet het antwoord van het apparaat bevat. Het doel van de callback is eenvoudigweg om uw code te laten weten dat de asynchrone overdrachtsverzoeken zijn verwerkt.

Waarden voor transferInfo object:

Waarde Beschrijving
richting (snaar) "in of uit".
eindpunt (geheel getal) Gedefinieerd door het protocol van uw apparaat.
lengte (geheel getal) Alleen gebruikt als de richting "in" is. Laat het apparaat weten dat dit de hoeveelheid gegevens is die de host als reactie verwacht.
gegevens (ArrayBuffer) Gedefinieerd door het protocol van uw apparaat; alleen gebruikt als de richting "uit" is.

Voorbeeld:

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

Waarschuwingen

Niet alle apparaten zijn toegankelijk via de USB API. Over het algemeen zijn apparaten niet toegankelijk omdat de kernel van het besturingssysteem of een eigen stuurprogramma ze afhoudt van de gebruikersruimtecode. Enkele voorbeelden zijn apparaten met HID-profielen op OSX-systemen en USB-sticks.

Op de meeste Linux-systemen worden USB-apparaten standaard toegewezen met alleen-lezen-rechten. Om een ​​apparaat via deze API te openen, moet uw gebruiker er ook schrijftoegang toe hebben. Een eenvoudige oplossing is het instellen van een udev-regel. Maak een bestand /etc/udev/rules.d/50-yourdevicename.rules met de volgende inhoud:

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

Start vervolgens de udev-daemon opnieuw op: service udev restart . U kunt controleren of de apparaatmachtigingen correct zijn ingesteld door deze stappen te volgen:

  • Voer lsusb uit om de bus- en apparaatnummers te vinden.
  • Voer ls -al /dev/bus/usb/[bus]/[device] uit. Dit bestand moet eigendom zijn van de groep "plugdev" en moet groepsschrijfrechten hebben.

Uw app kan dit niet automatisch doen, omdat deze procedure root-toegang vereist. We raden u aan instructies te geven aan eindgebruikers en naar de sectie Waarschuwingen op deze pagina te linken voor uitleg.

Op ChromeOS roept u eenvoudigweg usb.requestAccess aan. De toestemmingsmakelaar doet dit voor u.