Start · Sprachen · JavaScript · Referenz · USBConfiguration.interfaces

USBConfiguration.interfaces

Eigenschaft

Schreibgeschütztes Array von <code>USBInterface</code>-Objekten, das jede Schnittstelle beschreibt, die eine USB-Konfiguration anbietet.

seit JavaScript WebUSB: Chromium-Browser (Chrome/Edge 61+, Opera); Kategorie: webapi

Signatur

USBConfiguration.interfaces

Beschreibung

Die schreibgeschützte Eigenschaft interfaces eines USBConfiguration-Objekts liefert ein Array mit USBInterface-Instanzen. Jede Instanz steht für eine Schnittstelle, die das Gerät in dieser Konfiguration bereitstellt, zum Beispiel eine herstellerspezifische Datenschnittstelle, eine HID- oder eine CDC-Schnittstelle.

Die Eigenschaft brauchst du, bevor du mit USBDevice.claimInterface() eine Schnittstelle beanspruchst. Über interfaceNumber, alternate bzw. alternates und deren endpoints findest du die passende Schnittstelle und die Endpunkt-Nummern für transferIn() und transferOut(). So musst du keine Nummern im Code festschreiben.

Normalerweise liest du die Schnittstellen der aktiven Konfiguration über device.configuration.interfaces. Alle möglichen Konfigurationen eines Geräts stehen in device.configurations. Das Array ist eine Momentaufnahme der Deskriptoren. Wenn du die Konfiguration wechselst (selectConfiguration()), musst du die Schnittstellen neu auslesen.

Rückgabewert

Typ
Array<USBInterface>
Beschreibung
Ein Array (FrozenArray) mit einem USBInterface-Objekt je Schnittstelle der Konfiguration. Wenn die Konfiguration keine Schnittstellen hat, ist das Array leer.

Beispiele

Schnittstellen der aktiven Konfiguration auflisten

// Muss durch eine Nutzeraktion (z. B. Klick) ausgelöst werden
const button = document.querySelector('#connect');

button.addEventListener('click', async () => {
  const device = await navigator.usb.requestDevice({ filters: [] });
  await device.open();
  if (device.configuration === null) {
    await device.selectConfiguration(1);
  }

  for (const iface of device.configuration.interfaces) {
    const alt = iface.alternate;
    console.log(
      `Interface ${iface.interfaceNumber}: Klasse 0x${alt.interfaceClass.toString(16)}, ` +
      `${alt.endpoints.length} Endpunkte, beansprucht: ${iface.claimed}`
    );
  }
});
Interface 0: Klasse 0xff, 2 Endpunkte, beansprucht: false

Herstellerspezifische Schnittstelle finden und beanspruchen

const connectVendorInterface = async (device) => {
  await device.open();
  if (device.configuration === null) await device.selectConfiguration(1);

  // Klasse 0xFF = herstellerspezifisch
  const iface = device.configuration.interfaces.find((i) =>
    i.alternates.some((a) => a.interfaceClass === 0xff)
  );
  if (!iface) throw new Error('Keine passende Schnittstelle gefunden');

  await device.claimInterface(iface.interfaceNumber);

  // Endpunkt-Nummern dynamisch ermitteln
  const { endpoints } = iface.alternate;
  const inEp = endpoints.find((e) => e.direction === 'in' && e.type === 'bulk');
  const outEp = endpoints.find((e) => e.direction === 'out' && e.type === 'bulk');

  return { iface, inEp: inEp.endpointNumber, outEp: outEp.endpointNumber };
};

const [device] = await navigator.usb.getDevices();
if (device) {
  const info = await connectVendorInterface(device);
  console.log(info.inEp, info.outEp);
}
1 2

Schnittstellen aller Konfigurationen vergleichen

const [device] = await navigator.usb.getDevices();

if (device) {
  const overview = device.configurations.map((config) => ({
    konfiguration: config.configurationValue,
    name: config.configurationName,
    schnittstellen: config.interfaces.map((i) => i.interfaceNumber)
  }));
  console.table(overview);
}
┌─────────┬───────────────┬──────┬────────────────┐ │ (index) │ konfiguration │ name │ schnittstellen │ │ 0 │ 1 │ null │ [0, 1] │ └─────────┴───────────────┴──────┴────────────────┘

// Wichtig · Fallstricke

  • Browser-Unterstützung: WebUSB gibt es nur in Chromium-Browsern (Chrome, Edge, Opera, außerdem Chrome für Android). Firefox und Safari unterstützen die API nicht. Prüfe deshalb vorher mit 'usb' in navigator.
  • Sicherer Kontext: Die API funktioniert nur über HTTPS (oder localhost). requestDevice() braucht eine Nutzeraktion. In iframes muss die Permissions-Policy usb erlaubt sein.
  • device.configuration kann null sein: Das passiert, solange noch keine Konfiguration ausgewählt ist. Wenn du dann device.configuration.interfaces liest, wirft das einen TypeError. Rufe vorher selectConfiguration() auf.
  • Geschützte Klassen: Schnittstellen mit geschützten Klassen (z. B. HID, Massenspeicher, Audio, Video) stehen zwar im Array, lassen sich aber nicht mit claimInterface() beanspruchen. Das Ergebnis ist ein SecurityError.
  • Bereits vom Betriebssystem belegte Schnittstellen (z. B. durch einen Kernel-Treiber) führen beim Beanspruchen zu einem NetworkError, besonders unter Windows ohne WinUSB-Treiber.
  • Das Array ist schreibgeschützt. Wenn du Einträge änderst, hat das keine Wirkung auf das Gerät.