Start · Sprachen · JavaScript · Referenz · USBDevice.claimInterface()

USBDevice.claimInterface()

Methode

Beansprucht ein USB-Interface des Geräts für exklusiven Zugriff und gibt ein <code>Promise</code> zurück, das nach erfolgreicher Übernahme erfüllt wird.

seit JavaScript WebUSB: Chrome/Edge 61+, Opera; nicht in Firefox u Kategorie: webapi

Signatur

USBDevice.prototype.claimInterface(interfaceNumber)

Beschreibung

Mit claimInterface() übernimmt eine Web-Anwendung die exklusive Kontrolle über ein bestimmtes Interface eines USB-Geräts. Erst danach kann sie Datenübertragungen über die Endpunkte dieses Interfaces ausführen, etwa mit transferIn(), transferOut() oder isochronen Übertragungen. Auch Control-Transfers mit dem Empfänger "interface" oder "endpoint" setzen ein beanspruchtes Interface voraus.

Die übliche Reihenfolge sieht so aus: Mit navigator.usb.requestDevice() das Gerät auswählen, mit device.open() eine Sitzung öffnen, bei Bedarf mit selectConfiguration() eine Konfiguration wählen und anschließend claimInterface() aufrufen. Die Interface-Nummer steht in device.configuration.interfaces[i].interfaceNumber.

Ist die Übernahme erfolgreich, steht die Eigenschaft claimed des passenden USBInterface-Objekts auf true. Wenn Sie das Interface nicht mehr brauchen, geben Sie es mit releaseInterface() wieder frei. Beim Aufruf von close() werden alle Interfaces automatisch freigegeben.

Parameter

Name Typ Default Beschreibung
$interfaceNumber Pflicht number Die Nummer des Interfaces (bInterfaceNumber) in der aktiven Konfiguration, das beansprucht werden soll.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das ohne Wert erfüllt wird, sobald das Interface beansprucht ist. Es wird mit einer DOMException abgelehnt, wenn das Gerät nicht geöffnet ist (InvalidStateError), die Interface-Nummer nicht existiert (NotFoundError), der Zugriff blockiert ist (SecurityError) oder das Betriebssystem bzw. ein anderer Treiber das Interface belegt (NetworkError).

Beispiele

Gerät öffnen und Interface 0 beanspruchen

const connect = async () => {
  // Gerät auswählen (muss durch eine Nutzeraktion ausgelöst werden)
  const device = await navigator.usb.requestDevice({
    filters: [{ vendorId: 0x2341 }]
  });

  await device.open();
  if (device.configuration === null) {
    await device.selectConfiguration(1);
  }
  await device.claimInterface(0);

  console.log('Interface beansprucht:', device.configuration.interfaces[0].claimed);
  return device;
};

document.querySelector('#connect').addEventListener('click', connect);
Interface beansprucht: true

Passendes Interface anhand der Klasse suchen (herstellerspezifisch, 0xFF)

const claimVendorInterface = async (device) => {
  const iface = device.configuration.interfaces.find((i) =>
    i.alternates.some((alt) => alt.interfaceClass === 0xff)
  );
  if (!iface) throw new Error('Kein herstellerspezifisches Interface gefunden');

  await device.claimInterface(iface.interfaceNumber);
  console.log(`Interface ${iface.interfaceNumber} gehört jetzt uns`);
  return iface.interfaceNumber;
};
Interface 2 gehört jetzt uns

Fehler behandeln, Daten senden und Interface wieder freigeben

const sendCommand = async (device, ifaceNumber, endpoint, bytes) => {
  try {
    await device.claimInterface(ifaceNumber);
  } catch (err) {
    if (err.name === 'NetworkError') {
      console.error('Interface ist von einem anderen Treiber belegt.');
    } else {
      console.error('Übernahme fehlgeschlagen:', err.name, err.message);
    }
    return;
  }

  try {
    const result = await device.transferOut(endpoint, new Uint8Array(bytes));
    console.log('Status:', result.status, '– gesendet:', result.bytesWritten);
  } finally {
    await device.releaseInterface(ifaceNumber);
  }
};
Status: ok – gesendet: 3

// Wichtig · Fallstricke

  • Browser-Unterstützung: WebUSB gibt es nur in Chromium-basierten Browsern (Chrome, Edge, Opera). Firefox und Safari unterstützen die API nicht. Prüfen Sie vorher mit 'usb' in navigator, ob sie vorhanden ist.
  • Sicherer Kontext: Die API funktioniert nur über HTTPS (oder localhost). In Cross-Origin-iframes ist sie nur verfügbar, wenn die Permissions Policy usb sie freigibt.
  • Vom Betriebssystem belegte Interfaces: Interfaces, die schon ein Treiber des Betriebssystems nutzt, lassen sich meist nicht beanspruchen. Das betrifft vor allem HID, Massenspeicher und unter Windows oft CDC-ACM. Die Folge ist ein NetworkError. Unter Windows braucht das Gerät häufig einen WinUSB-Treiber. Für HID-Geräte eignet sich die WebHID-API besser.
  • Geschützte Klassen: Chrome sperrt bestimmte Interface-Klassen wie Audio, Video, HID, Massenspeicher und Smartcard. Der Aufruf endet dann mit einem SecurityError.
  • Das Gerät muss vorher mit open() geöffnet sein. Sonst gibt es einen InvalidStateError.
  • Die Exklusivität gilt auch zwischen Tabs: Hat ein anderer Tab oder ein anderes Programm das Interface schon beansprucht, schlägt der Aufruf fehl.
  • Nach selectConfiguration() mit einer anderen Konfiguration verlieren Sie alle beanspruchten Interfaces und müssen sie neu beanspruchen.