Signatur
Beschreibung
USBInTransferResult gehört zur WebUSB API. Ein Objekt dieses Typs bekommst du, wenn das Promise von USBDevice.transferIn() (Bulk- oder Interrupt-Transfer) bzw. USBDevice.controlTransferIn() (Control-Transfer) erfüllt wird. Es bündelt die Daten, die das Gerät zum Host geschickt hat, und den Status des Transfers.
Das Interface hat zwei schreibgeschützte Eigenschaften:
data– eineDataViewauf die empfangenen Bytes. Istundefinedodernull, wenn keine Daten angekommen sind. Die Länge kann kleiner sein als die angeforderte Länge.status– ein String:"ok"(Transfer erfolgreich),"stall"(das Gerät hat einen Stall gemeldet, der Endpunkt muss mitclearHalt()zurückgesetzt werden) oder"babble"(das Gerät hat mehr Daten geschickt als angefordert).
In der Praxis prüfst du nach jedem Transfer zuerst status und liest die Bytes dann mit den DataView-Methoden wie getUint8() oder getUint16() aus, oder du dekodierst sie mit TextDecoder. Mit new USBInTransferResult(status, data) kannst du auch selbst ein Objekt erzeugen, zum Beispiel für Tests oder Mocks.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $status Pflicht | "ok" | "stall" | "babble" | Nur beim Konstruktor new USBInTransferResult(status, data): der Status des Transfers. |
|
| $data | DataView | null | Nur beim Konstruktor: die empfangenen Daten als DataView. |
Rückgabewert
data (DataView | undefined) und status ("ok" | "stall" | "babble").Beispiele
Bulk-Daten lesen und Status prüfen
// Muss durch eine Nutzeraktion ausgelöst werden (z. B. Klick)
const connectAndRead = async () => {
const device = await navigator.usb.requestDevice({
filters: [{ vendorId: 0x2341 }]
});
await device.open();
if (device.configuration === null) await device.selectConfiguration(1);
await device.claimInterface(0);
// Bis zu 64 Bytes von Endpunkt 1 lesen
const result = await device.transferIn(1, 64);
if (result.status === 'ok' && result.data) {
const text = new TextDecoder().decode(result.data);
console.log(`Empfangen (${result.data.byteLength} Bytes):`, text);
} else if (result.status === 'stall') {
console.warn('Endpunkt blockiert – setze zurück');
await device.clearHalt('in', 1);
}
};
document.querySelector('#connect').addEventListener('click', connectAndRead);
Control-Transfer: Gerätedeskriptor auslesen
const readDeviceDescriptor = async (device) => {
const result = await device.controlTransferIn({
requestType: 'standard',
recipient: 'device',
request: 0x06, // GET_DESCRIPTOR
value: 0x0100, // Gerätedeskriptor, Index 0
index: 0x0000
}, 18);
if (result.status !== 'ok') {
throw new Error(`Transfer fehlgeschlagen: ${result.status}`);
}
const view = result.data;
return {
bcdUSB: view.getUint16(2, true).toString(16),
vendorId: view.getUint16(8, true).toString(16),
productId: view.getUint16(10, true).toString(16)
};
};
// const info = await readDeviceDescriptor(device);
// console.log(info);
Ergebnis für Tests selbst erzeugen
const bytes = new Uint8Array([0x01, 0x02, 0xff]);
const fake = new USBInTransferResult('ok', new DataView(bytes.buffer));
console.log(fake.status); // 'ok'
console.log(fake.data.getUint8(2)); // 255
// Wichtig · Fallstricke
- Kompatibilität: WebUSB gibt es nur in Chromium-Browsern (Chrome, Edge, Opera) auf dem Desktop und in Chrome für Android. Firefox und Safari unterstützen die API nicht. Prüfe deshalb vorher mit
'usb' in navigator, ob sie verfügbar ist. - Die API steht nur in sicheren Kontexten (HTTPS oder localhost) zur Verfügung. Du kannst sie per Permissions-Policy (
usb) sperren. Außerdem erfordertrequestDevice()eine Nutzeraktion. datakann kürzer sein als angefordert. Prüfe immerdata.byteLength, bevor du liest, sonst wirft dieDataVieweinenRangeError.- Bei
"stall"bleibt der Endpunkt blockiert, bis dudevice.clearHalt('in', endpointNumber)aufrufst. Ein Status"babble"deutet auf einen zu kleinen Puffer oder auf ein fehlerhaftes Gerät hin. - Die
DataViewkann auf einen größerenArrayBufferzeigen. Beachte daherbyteOffset, wenn du direkt aufdata.bufferzugreifst. - Mehrbyte-Werte in USB-Deskriptoren sind Little Endian. Übergib deshalb bei
getUint16()und ähnlichen Methodentrueals zweites Argument. - Transportfehler (Gerät getrennt, ungültiger Endpunkt) führen nicht zu einem Status, sondern zu einem abgelehnten Promise mit einer
DOMException. Fang sie mittry/catchab.