Signatur
Beschreibung
USBInterface gehört zur WebUSB API und beschreibt eine einzelne Schnittstelle (Interface) innerhalb einer USBConfiguration eines Geräts. Ein USB-Gerät kann mehrere Schnittstellen anbieten, zum Beispiel eine für Daten und eine für Steuerbefehle oder Firmware-Updates. Jede Schnittstelle hat eigene Endpunkte, über die Daten fließen.
Man bekommt USBInterface-Objekte meistens über device.configuration.interfaces oder device.configurations[n].interfaces. Die wichtigsten Eigenschaften:
interfaceNumber: Nummer der Schnittstelle (bInterfaceNumber), die man anUSBDevice.claimInterface()übergibt.alternate: die gerade aktiveUSBAlternateInterfacemit Klasse, Unterklasse, Protokoll und Endpunkten.alternates: ein Array mit allen möglichen Alternativeinstellungen.claimed:true, wenn die Seite die Schnittstelle gerade überclaimInterface()belegt hat.
Vor jedem Datentransfer (transferIn(), transferOut(), isochronousTransferIn() …) muss die passende Schnittstelle belegt werden. Mit USBInterface findet man vorher heraus, welche Schnittstelle die richtige ist, meist anhand von alternate.interfaceClass (z. B. 0xFF für herstellerspezifisch) und den Endpunkt-Richtungen.
Einen Konstruktor gibt es auch (new USBInterface(configuration, interfaceNumber)). In der Praxis braucht man ihn aber kaum, weil der Browser die Objekte selbst anlegt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $configuration Pflicht | USBConfiguration | Nur beim Konstruktor: die Konfiguration, zu der die Schnittstelle gehört. | |
| $interfaceNumber Pflicht | number | Nur beim Konstruktor: Nummer der Schnittstelle innerhalb der Konfiguration. Gibt es die Nummer nicht, wird ein RangeError geworfen. |
Rückgabewert
interfaceNumber (number), alternate (USBAlternateInterface), alternates (USBAlternateInterface[]) und claimed (boolean).Beispiele
Schnittstellen eines Geräts auflisten
// Muss durch eine Nutzeraktion ausgelöst werden (z. B. Klick)
document.querySelector('#connect').addEventListener('click', async () => {
const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] });
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, ${iface.alternates.length} Alternativen, belegt: ${iface.claimed}`
);
}
});
Herstellerspezifische Schnittstelle finden, belegen und Daten senden
const connectVendorInterface = async (device) => {
await device.open();
if (device.configuration === null) await device.selectConfiguration(1);
// Schnittstelle mit Klasse 0xFF (herstellerspezifisch) suchen
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);
console.log('Belegt:', iface.claimed);
const outEndpoint = iface.alternate.endpoints.find((e) => e.direction === 'out');
const data = new TextEncoder().encode('LED ON');
const result = await device.transferOut(outEndpoint.endpointNumber, data);
console.log('Gesendet:', result.bytesWritten, 'Bytes');
await device.releaseInterface(iface.interfaceNumber);
console.log('Belegt:', iface.claimed);
};
Alternativeinstellung wechseln
const selectBestAlternate = async (device, iface) => {
await device.claimInterface(iface.interfaceNumber);
// Die Alternative mit den meisten Endpunkten wählen
const best = iface.alternates.reduce((a, b) =>
b.endpoints.length > a.endpoints.length ? b : a
);
await device.selectAlternateInterface(iface.interfaceNumber, best.alternateSetting);
console.log('Aktive Alternative:', iface.alternate.alternateSetting);
};
Konstruktor direkt verwenden
// Selten nötig: Objekt für eine bekannte Schnittstellennummer erzeugen
const [device] = await navigator.usb.getDevices();
await device.open();
const iface = new USBInterface(device.configuration, 0);
console.log(iface.interfaceNumber, iface.alternates.length);
// 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. Vorher mit
'usb' in navigatorprüfen. - Sicherer Kontext: Die API funktioniert nur über HTTPS oder
localhost. In iframes muss die Permissions Policyusberlaubt sein. - Geschützte Klassen: Schnittstellen mit geschützten Klassen wie HID, Massenspeicher, Audio, Video oder Smartcard lassen sich nicht belegen.
claimInterface()wirft dann einenSecurityError. Für HID-Geräte gibt es stattdessen die WebHID API. - Treiberkonflikte: Hat das Betriebssystem schon einen Treiber an die Schnittstelle gebunden (z. B. CDC-ACM unter Linux oder ein Windows-Treiber ohne WinUSB), schlägt
claimInterface()mitNetworkErrorfehl. device.configurationistnull, solange keine Konfiguration gewählt wurde. Dann zuerstselectConfiguration()aufrufen.alternateist eine Live-Ansicht: NachselectAlternateInterface()zeigt die Eigenschaft die neue Einstellung. Endpunkt-Nummern deshalb nach dem Wechsel neu auslesen.- Schnittstellen nach der Nutzung mit
releaseInterface()freigeben und das Gerät mitclose()schließen, sonst bleiben sie für andere Tabs blockiert.