detectPrinterConfiguration method
Implementation
Future<Map<String, dynamic>> detectPrinterConfiguration(
int vendorId, int productId) async {
final Pointer<libusb_device_handle>? handleNullable =
openDevice(vendorId, productId);
if (handleNullable == nullptr || handleNullable == null) {
return {'success': false, 'error': 'Could not open device'};
}
final handle = handleNullable;
try {
final device = _bindings.libusb_get_device(handle);
final deviceDescriptor = calloc<libusb_device_descriptor>();
final descResult =
_bindings.libusb_get_device_descriptor(device, deviceDescriptor);
if (descResult < 0) {
calloc.free(deviceDescriptor);
return {
'success': false,
'error': 'Could not obtain device descriptor',
'errorCode': descResult
};
}
final configDescPtr = calloc<Pointer<libusb_config_descriptor>>();
final configResult =
_bindings.libusb_get_active_config_descriptor(device, configDescPtr);
if (configResult < 0) {
calloc.free(deviceDescriptor);
calloc.free(configDescPtr);
return {
'success': false,
'error': 'Could not obtain configuration descriptor',
'errorCode': configResult
};
}
final config = configDescPtr.value;
final numInterfaces = config.ref.bNumInterfaces;
Map<String, dynamic> deviceInfo = {
'vendorId': deviceDescriptor.ref.idVendor,
'productId': deviceDescriptor.ref.idProduct,
'deviceClass': deviceDescriptor.ref.bDeviceClass,
'deviceSubClass': deviceDescriptor.ref.bDeviceSubClass,
'deviceProtocol': deviceDescriptor.ref.bDeviceProtocol,
'busNumber': _bindings.libusb_get_bus_number(device),
'deviceAddress': _bindings.libusb_get_device_address(device),
'numInterfaces': numInterfaces,
'interfaces': <Map<String, dynamic>>[]
};
for (int i = 0; i < numInterfaces; i++) {
if (Platform.isLinux || Platform.isMacOS) {
try {
final hasKernelDriver =
_bindings.libusb_kernel_driver_active(handle, i);
if (hasKernelDriver == 1) {
_bindings.libusb_detach_kernel_driver(handle, i);
}
} catch (e) {
log("Error checking/detaching kernel driver for interface $i: $e");
}
}
int claimResult = _bindings.libusb_claim_interface(handle, i);
if (claimResult < 0) {
log("Could not claim interface $i: $claimResult");
continue;
}
Map<String, dynamic> interfaceInfo = {
'number': i,
'canClaim': true,
'endpoints': <Map<String, dynamic>>[]
};
List<int> commonEndpoints = [0x01, 0x02, 0x03, 0x81, 0x82, 0x83];
for (int epAddress in commonEndpoints) {
bool isOutput = (epAddress & 0x80) == 0;
interfaceInfo['endpoints'].add({
'address': epAddress,
'type': 'bulk',
'direction': isOutput ? 'output' : 'input'
});
}
_bindings.libusb_release_interface(handle, i);
if (Platform.isLinux || Platform.isMacOS) {
try {
final hasKernelDriver =
_bindings.libusb_kernel_driver_active(handle, i);
if (hasKernelDriver == 1) {
_bindings.libusb_attach_kernel_driver(handle, i);
}
} catch (e) {
log("Error reconnecting kernel driver for interface $i: $e");
}
}
deviceInfo['interfaces'].add(interfaceInfo);
}
_bindings.libusb_free_config_descriptor(config);
calloc.free(configDescPtr);
calloc.free(deviceDescriptor);
return {
'success': true,
'deviceInfo': deviceInfo,
'note':
'The listed endpoints are common endpoints for printers and may not correspond exactly to the actual endpoints of the device.'
};
} catch (e) {
return {
'success': false,
'error': 'Error detecting configuration',
'exception': e.toString()
};
} finally {
closeDevice(handle);
}
}