poll static method
Try to poll a WebUSB device according to our protocol.
Implementation
static Future<String> poll(int timeout, bool probeMagic) async {
// request WebUSB device with custom classcode
if (!_deviceAvailable()) {
var devicePromise = _USB.requestDevice(_USBDeviceRequestOptions(
filters: [_USBDeviceFilter(classCode: USB_CLASS_CODE_VENDOR_SPECIFIC)]
.toJS));
dynamic device = await promiseToFuture(devicePromise);
try {
await promiseToFuture(callMethod(device, 'open', List.empty()))
.then((_) =>
promiseToFuture(callMethod(device, 'claimInterface', [1])))
.timeout(Duration(milliseconds: timeout));
_device = device;
_USB.ondisconnect = () {
_device = null;
onDisconnect?.call();
}.toJS;
log.info("WebUSB device opened", _device);
} on TimeoutException catch (_) {
log.severe("Polling tag timeout");
throw PlatformException(code: "408", message: "Polling tag timeout");
} on Exception catch (e) {
log.severe("Poll error", e);
throw PlatformException(
code: "500", message: "WebUSB API error", details: e);
}
if (probeMagic) {
try {
// PROBE request
var promise = callMethod(_device, 'controlTransferIn', [
_USBControlTransferParameters(
requestType: 'vendor',
recipient: 'interface',
request: 0xff,
value: 0,
index: 1),
1
]);
var resp = await promiseToFuture(promise);
if (getProperty(resp, 'status') == 'stalled') {
throw PlatformException(
code: "500", message: "Device error: transfer stalled");
}
var result =
(getProperty(resp, 'data').buffer as ByteBuffer).asUint8List();
if (result.length < USB_PROBE_MAGIC.length ||
result.sublist(0, USB_PROBE_MAGIC.length) !=
Uint8List.fromList(USB_PROBE_MAGIC.codeUnits)) {
throw PlatformException(
code: "500",
message:
"Device error: invalid probe response: ${hex.encode(result)}, should begin with $USB_PROBE_MAGIC");
}
customProbeData = hex.encode(result.sublist(USB_PROBE_MAGIC.length));
} on Exception catch (e) {
log.severe("Probe error", e);
throw PlatformException(
code: "500", message: "WebUSB API error", details: e);
}
} else {
customProbeData = "";
}
}
// get VID & PID
int vendorId = getProperty(_device, 'vendorId');
int productId = getProperty(_device, 'productId');
String id =
'${vendorId.toRadixString(16).padLeft(4, '0')}:${productId.toRadixString(16).padLeft(4, '0')}';
return json.encode({
'type': 'webusb',
'id': id,
'standard': 'nfc-im-webusb-protocol',
'customProbeData': customProbeData
});
}