Created
December 3, 2019 04:26
-
-
Save devanlai/4aba1c2d4000bdcfc5ec71584491e19f to your computer and use it in GitHub Desktop.
WebUSB descriptor read test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>WebUSB Control Transfer Request to Device Endpoint while unconfigured</title> | |
<script> | |
async function readDeviceDescriptor(device) { | |
const GET_DESCRIPTOR = 0x06; | |
const DT_DEVICE = 0x01; | |
const wValue = (DT_DEVICE << 8); | |
let result = await device.controlTransferIn({ | |
"requestType": "standard", | |
"recipient": "device", | |
"request": GET_DESCRIPTOR, | |
"value": wValue, | |
"index": 0 | |
}, 18); | |
return result; | |
} | |
function parseDeviceDescriptor(data) { | |
return { | |
bLength: data.getUint8(0), | |
bDescriptorType: data.getUint8(1), | |
bcdUSB: data.getUint16(2, true), | |
bDeviceClass: data.getUint8(4), | |
bDeviceSubClass: data.getUint8(5), | |
bDeviceProtocol: data.getUint8(6), | |
bMaxPacketSize: data.getUint8(7), | |
idVendor: data.getUint16(8, true), | |
idProduct: data.getUint16(10, true), | |
bcdDevice: data.getUint16(12, true), | |
iManufacturer: data.getUint8(14), | |
iProduct: data.getUint8(15), | |
iSerialNumber: data.getUint8(16), | |
bNumConfigurations: data.getUint8(17), | |
}; | |
} | |
document.addEventListener("DOMContentLoaded", function (event) { | |
let status = document.getElementById("status"); | |
function log(msg) { | |
console.log(msg); | |
let div = document.createElement("div"); | |
div.textContent = msg; | |
status.appendChild(div); | |
} | |
function logPreformatted(msg) { | |
console.log(msg); | |
let div = document.createElement("div"); | |
div.textContent = msg; | |
div.style = "white-space: pre; font-family: monospace"; | |
status.appendChild(div); | |
} | |
function displayDeviceDescriptor(desc) { | |
const names = "bLength bDescriptorType bcdUSB bDeviceClass bDeviceSubClass bDeviceProtocol bMaxPacketSize idVendor idProduct bcdDevice iManufacturer iProduct iSerialNumber bNumConfigurations".split(" "); | |
for (let name of names) { | |
logPreformatted((name + ':').padEnd(20) + desc[name]); | |
} | |
} | |
async function runTest(withConfiguration) { | |
const usb_options = { filters: [] }; | |
let device = await navigator.usb.requestDevice(usb_options); | |
try { | |
await device.open(); | |
} catch (err) { | |
log("Failed to open USB device: " + err); | |
if (err.toString().startsWith("NotFoundError")) { | |
log("Make sure you're running this test from a secure context (e.g. localhost or HTTPS, not a file:/// URI)"); | |
} | |
return; | |
} | |
try { | |
if (withConfiguration !== undefined && withConfiguration !== null) { | |
log("Selecting configuration " + withConfiguration); | |
try { | |
await device.selectConfiguration(withConfiguration); | |
} catch (err) { | |
log("Failed to select configuration " + withConfiguration + ": " + err); | |
} | |
} else { | |
log("Proceeding without selecting configuration"); | |
} | |
let result = await readDeviceDescriptor(device); | |
if (result.status == "ok") { | |
log("Successfully read device descriptor"); | |
let desc = parseDeviceDescriptor(result.data); | |
displayDeviceDescriptor(desc); | |
} else { | |
log("Control transfer failed: " + result.status); | |
} | |
} catch (err) { | |
log("Failed to initiate control transfer: " + err); | |
} | |
} | |
document.getElementById("testButton").addEventListener("click", async function (event) { | |
// Test without setting the configuration explicitly | |
runTest(null); | |
}); | |
document.getElementById("testWithConfigButton").addEventListener("click", async function (event) { | |
// Test explicitly setting configuration to 1 | |
runTest(1); | |
}); | |
}); | |
</script> | |
</head> | |
<body> | |
<button id="testButton">Test w/o setting configuration</button> | |
<button id="testWithConfigButton">Test with setting configuration</button> | |
<div id="status"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment