Signatur
Beschreibung
Die Eigenschaft deviceSubclass eines USBDevice-Objekts enthält den Unterklassen-Code des Geräts. Er stammt aus dem Feld bDeviceSubClass des USB-Gerätedeskriptors. Zusammen mit deviceClass und deviceProtocol bildet er das Tripel, über das ein Betriebssystem entscheidet, welcher Klassentreiber zum Gerät passt.
Der Wert gilt immer nur zusammen mit deviceClass: Welche Unterklasse eine Zahl bezeichnet, legt das USB Implementers Forum (USB-IF) für jede Klasse getrennt fest. Ein Beispiel ist die Klasse 0xEF (Verschiedenes) mit Unterklasse 0x02 und Protokoll 0x01. Dieses Tripel kennzeichnet ein Verbundgerät, dessen Funktionen über eine Interface Association gebündelt sind.
Bei sehr vielen Geräten stehen Klasse und Unterklasse auf 0. Das heißt, die eigentliche Einordnung steht nicht im Gerätedeskriptor, sondern in den einzelnen Interfaces, erreichbar über USBAlternateInterface.interfaceClass und interfaceSubclass. In der Praxis nutzt man deviceSubclass vor allem für Diagnosen, zum Protokollieren und für Filter in navigator.usb.requestDevice() (Filterschlüssel subclassCode).
Rückgabewert
0 bis 255 (Oktett), nämlich der USB-Unterklassen-Code des Geräts. Die Eigenschaft ist nur lesbar.Beispiele
Klassen-Tripel eines gewählten Geräts ausgeben
const btn = document.querySelector('#connect');
btn.addEventListener('click', async () => {
try {
const device = await navigator.usb.requestDevice({ filters: [] });
const hex = (n) => '0x' + n.toString(16).padStart(2, '0');
console.log(`${device.productName}: Klasse ${hex(device.deviceClass)}, ` +
`Unterklasse ${hex(device.deviceSubclass)}, Protokoll ${hex(device.deviceProtocol)}`);
} catch (err) {
console.warn('Keine Geräteauswahl:', err.message);
}
});
Nach Klasse und Unterklasse filtern
// Nur Verbundgeräte mit Interface Association (Klasse 0xEF, Unterklasse 0x02) anbieten
const device = await navigator.usb.requestDevice({
filters: [{ classCode: 0xef, subclassCode: 0x02, protocolCode: 0x01 }]
});
console.log(device.deviceClass, device.deviceSubclass, device.deviceProtocol);
Auf Interface-Ebene zurückfallen, wenn der Gerätedeskriptor 0 meldet
const describeDevice = async () => {
const [device] = await navigator.usb.getDevices();
if (!device) return console.log('Kein freigegebenes Gerät');
if (device.deviceClass === 0 && device.deviceSubclass === 0) {
// Einordnung steckt in den Interfaces
for (const iface of device.configuration?.interfaces ?? []) {
const alt = iface.alternate;
console.log(`Interface ${iface.interfaceNumber}: Klasse ${alt.interfaceClass}, Unterklasse ${alt.interfaceSubclass}`);
}
} else {
console.log('Geräte-Unterklasse:', device.deviceSubclass);
}
};
describeDevice();
// Wichtig · Fallstricke
- Nur zusammen mit
deviceClassauswerten: Ein Unterklassen-Code hat allein keine Bedeutung.0x01steht zum Beispiel je nach Klasse für etwas völlig anderes. - Häufig 0: Viele Geräte melden Klasse und Unterklasse
0und legen die Einordnung auf Interface-Ebene fest. Werte danninterfaceSubclassaus. - Geschützte Klassen: Chromium sperrt einige Interface-Klassen für WebUSB, darunter HID, Massenspeicher, Audio und Video. Auch wenn
deviceSubclasslesbar ist, lassen sich solche Interfaces nicht mitclaimInterface()belegen. Für HID-Geräte gibt es stattdessen die WebHID-API. - Kompatibilität: WebUSB gibt es nur in Chromium-Browsern (Chrome, Edge, Opera) und nur in sicheren Kontexten (HTTPS oder
localhost). Firefox und Safari unterstützen die API nicht. Prüfe vorher mit'usb' in navigator. Die Eigenschaft steht bereits zur Verfügung, bevor das Gerät mitopen()geöffnet wurde. requestDevice()braucht eine Nutzergeste (etwa einen Klick). Eine Permissions Policy (usb) kann den Zugriff in iframes sperren.