sendDataToPrinter method
Implementation
Future<Map<String, dynamic>> sendDataToPrinter(
int vendorId,
int productId,
Uint8List data, {
int interfaceNumber = 0,
int timeout = 10000,
bool expectResponse = false,
int maxResponseLength = 256,
}) 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;
// 🔹 2️⃣ Obtener los endpoints correctos
final device = getDevice(vendorId, productId);
if (device == null) {
log("❌ No se pudo encontrar el dispositivo USB");
return {'success': false, 'error': 'No se pudo encontrar el dispositivo'};
}
final endpoints = getDeviceEndpoints(device);
if (endpoints.isEmpty) {
return {'success': false, 'error': 'No se encontraron endpoints válidos'};
}
// Detectar OUT (escritura) e IN (lectura)
int endpointOut =
endpoints.firstWhere((e) => e & 0x80 == 0, orElse: () => 0x01);
int endpointIn =
endpoints.firstWhere((e) => e & 0x80 != 0, orElse: () => 0x82);
//log("✔️ Endpoint OUT: ${endpointOut.toRadixString(16)}");
//log("✔️ Endpoint IN: ${endpointIn.toRadixString(16)}");
try {
int hasKernelDriver = 0;
if (Platform.isLinux || Platform.isMacOS) {
try {
hasKernelDriver =
_bindings.libusb_kernel_driver_active(handle, interfaceNumber);
if (hasKernelDriver == 1) {
log("Detaching kernel driver...");
final detachResult =
_bindings.libusb_detach_kernel_driver(handle, interfaceNumber);
if (detachResult < 0) {
log("Could not detach kernel driver: $detachResult");
} else {
log("Kernel driver detached successfully");
}
}
} catch (e) {
log("Error checking/detaching kernel driver: $e");
}
}
final configResult = _bindings.libusb_set_configuration(handle, 1);
if (configResult < 0) {
log("Warning: Could not set configuration: $configResult");
}
int claimResult = -1;
int attempts = 0;
const maxAttempts = 3;
while (attempts < maxAttempts) {
claimResult = _bindings.libusb_claim_interface(handle, interfaceNumber);
if (claimResult == 0) break;
log("Attempt ${attempts + 1} failed with error $claimResult. Retrying...");
await Future.delayed(Duration(milliseconds: 500));
attempts++;
}
if (claimResult < 0) {
return {
'success': false,
'error': 'Could not claim interface after $maxAttempts attempts',
'errorCode': claimResult,
'errorDescription': _getUsbErrorDescription(claimResult)
};
}
final buffer = calloc<Uint8>(data.length);
final bufferList = buffer.asTypedList(data.length);
bufferList.setAll(0, data);
final transferredPtr = calloc<Int>();
log("Sending ${data.length} bytes to endpoint $endpointOut...");
int transferResult = _bindings.libusb_bulk_transfer(handle, endpointOut,
buffer.cast<UnsignedChar>(), data.length, transferredPtr, timeout);
await Future.delayed(Duration(milliseconds: 5000));
final bytesSent = transferredPtr.value;
calloc.free(buffer);
calloc.free(transferredPtr);
if (transferResult < 0) {
return {
'success': false,
'error': 'Error in data transfer',
'errorCode': transferResult,
'errorDescription': _getUsbErrorDescription(transferResult)
};
}
log("Transfer successful: $bytesSent bytes sent");
Map<String, dynamic> result = {
'success': true,
'bytesSent': bytesSent,
};
if (expectResponse) {
final responseBuffer = calloc<Uint8>(maxResponseLength);
final responseTransferredPtr = calloc<Int>();
await Future.delayed(Duration(milliseconds: 800));
log("Reading response from endpoint $endpointIn...");
final responseResult = _bindings.libusb_bulk_transfer(
handle,
endpointIn,
responseBuffer.cast<UnsignedChar>(),
maxResponseLength,
responseTransferredPtr,
timeout);
await Future.delayed(Duration(milliseconds: 100));
if (responseResult >= 0) {
final bytesReceived = responseTransferredPtr.value;
log("Response received: $bytesReceived bytes");
if (bytesReceived > 0) {
final responseList = List<int>.filled(bytesReceived, 0);
for (var i = 0; i < bytesReceived; i++) {
responseList[i] = responseBuffer[i];
}
result['responseData'] = responseList;
result['bytesReceived'] = bytesReceived;
} else {
result['responseData'] = [];
result['bytesReceived'] = 0;
}
} else {
log("Error reading response: $responseResult");
result['responseError'] = _getUsbErrorDescription(responseResult);
}
calloc.free(responseBuffer);
calloc.free(responseTransferredPtr);
}
_bindings.libusb_release_interface(handle, interfaceNumber);
if (hasKernelDriver == 1 && (Platform.isLinux || Platform.isMacOS)) {
_bindings.libusb_attach_kernel_driver(handle, interfaceNumber);
}
return result;
} catch (e) {
return {
'success': false,
'error': 'Error communicating with the printer',
'exception': e.toString()
};
} finally {
closeDevice(handle);
}
}