#include "usbhandler.h" UsbHandler::UsbHandler(QObject *parent) : QObject(parent), context(nullptr), deviceList(nullptr), deviceCount(0), handle(nullptr) { // Initialize libusb context if (libusb_init(&context) < 0) { emit errorOccurred("Failed to initialize libusb."); } } UsbHandler::~UsbHandler() { if (handle) { libusb_close(handle); } if (deviceList) { libusb_free_device_list(deviceList, 1); } libusb_exit(context); } bool UsbHandler::initialize() { // Initialize the libusb context and check for errors if (libusb_init(&context) < 0) { emit errorOccurred("Failed to initialize libusb."); return false; } return true; } void UsbHandler::listDevices() { // Retrieve the list of connected USB devices deviceCount = libusb_get_device_list(context, &deviceList); if (deviceCount < 0) { emit errorOccurred("Failed to get USB device list."); return; }else{ productList = new QMap[deviceCount]; } for (ssize_t i = 0; i < deviceCount; ++i) { productList->insert(i,printDeviceInfo(deviceList[i])); // Optionally add more detailed device information here } emit productListUpdate(productList); } bool UsbHandler::openDevice(int deviceIndex) { if (deviceIndex < 0 || deviceIndex >= deviceCount) { emit errorOccurred("Invalid device index."); return false; } // Open the selected device libusb_device_handle *devHandle; int status = libusb_open(deviceList[deviceIndex], &devHandle); LOG_DEBUG("status is %d",status); if (status < 0) { emit errorOccurred("Failed to open USB device."); return false; } // Store the device handle for further operations handle = devHandle; LOG_DEBUG("open deviceindex %d success",deviceIndex); return true; } bool UsbHandler::sendControlTransfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t length) { if (handle == nullptr) { emit errorOccurred("No device handle."); return false; } int status = libusb_control_transfer(handle, bmRequestType, bRequest, wValue, wIndex, data, length, 1000); if (status < 0) { emit errorOccurred("Control transfer failed."); return false; } return true; } bool UsbHandler::sendBulkTransfer(uint8_t endpoint, uint8_t *data, int length,int interfaceNum) { int status; if (handle == nullptr) { emit errorOccurred("No device handle."); return false; } // 获取接口权限(可选,部分系统如Linux必须) if (libusb_kernel_driver_active(handle, interfaceNum)) { libusb_detach_kernel_driver(handle, interfaceNum); } status = libusb_claim_interface(handle, interfaceNum); if (status < 0) { LOG_ERROR("Failed to claim interface: %d",interfaceNum); return false; } int actualLength; status = libusb_bulk_transfer(handle, endpoint, data, length, &actualLength, 1000); if (status < 0) { emit errorOccurred("Bulk transfer failed."); libusb_release_interface(handle, interfaceNum); return false; } libusb_release_interface(handle, interfaceNum); return true; } //主要用在数据读,从设备到主机 // bool UsbHandler::sendInterruptTransfer(uint8_t endpoint, uint8_t *data, int length) // { // if (handle == nullptr) { // emit errorOccurred("No device handle."); // return false; // } // int actualLength; // int status = libusb_interrupt_transfer(handle, endpoint, data, length, &actualLength, 1000); // if (status < 0) { // emit errorOccurred("Interrupt transfer failed."); // return false; // } // return true; // } bool UsbHandler::sendAsyncTransfer(uint8_t endpoint, uint8_t *data, int length,int interfaceNum) { int status; if (handle == nullptr) { emit errorOccurred("No device handle."); return false; } // 1. 创建 libusb_transfer 对象 libusb_transfer *transfer = libusb_alloc_transfer(0); // 0 表示默认的最大传输包大小 if (transfer == nullptr) { emit errorOccurred("Failed to allocate transfer."); return false; } // 获取接口权限(可选,部分系统如Linux必须) if (libusb_kernel_driver_active(handle, interfaceNum)) { libusb_detach_kernel_driver(handle, interfaceNum); } status = libusb_claim_interface(handle, interfaceNum); if (status < 0) { LOG_ERROR("Failed to claim interface: %d",interfaceNum); return false; } // 2. 设置传输类型和参数 if (endpoint & LIBUSB_ENDPOINT_IN) { // 如果是输入端点 (IN) libusb_fill_bulk_transfer(transfer, handle, endpoint, data, length, [](libusb_transfer *transfer) { // 回调函数,当传输完成时调用 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { LOG_DEBUG("Async Transfer completed successfully."); } else { LOG_ERROR("Async Transfer failed with status:0x%x",transfer->status); } libusb_free_transfer(transfer); // 释放传输资源 }, nullptr, 0); } else { // 如果是输出端点 (OUT) libusb_fill_bulk_transfer(transfer, handle, endpoint, data, length, [](libusb_transfer *transfer) { // 回调函数,当传输完成时调用 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { LOG_DEBUG("Async Transfer completed successfully."); } else { LOG_ERROR("Async Transfer failed with status:0x%x",transfer->status); } libusb_free_transfer(transfer); // 释放传输资源 }, nullptr, 0); } // 3. 提交传输 status = libusb_submit_transfer(transfer); if (status < 0) { emit errorOccurred("Failed to submit async transfer."); libusb_free_transfer(transfer); libusb_release_interface(handle, interfaceNum); return false; } libusb_release_interface(handle, interfaceNum); // libusb_handle_events(context); // 确保事件循环能处理异步传输 return true; } QString UsbHandler::printDeviceInfo(libusb_device *device) { libusb_device_descriptor desc; QString tmp={}; if (libusb_get_device_descriptor(device, &desc) == 0) { tmp= "Vendor ID: 0x"+QString::number(desc.idVendor,16)+",Product ID: 0x"+QString::number(desc.idProduct,16); LOG_DEBUG("Vendor ID: 0x%x, Product ID: 0x%x", desc.idVendor, desc.idProduct); } else { LOG_ERROR("Failed to retrieve device descriptor."); } return tmp; } void UsbHandler::listInterfaces(int deviceIndex) { if (deviceIndex < 0 || deviceIndex >= deviceCount) { emit errorOccurred("无效的设备索引"); return; } libusb_device *device = deviceList[deviceIndex]; libusb_config_descriptor *config = nullptr; if (libusb_get_active_config_descriptor(device, &config) != 0) { emit errorOccurred("获取配置描述符失败"); return; } LOG_DEBUG("接口总数: %d",config->bNumInterfaces); interfaceList = new QMap[config->bNumInterfaces]; for (int i = 0; i < config->bNumInterfaces; ++i) { const libusb_interface &interface = config->interface[i]; QString tmp; for (int j = 0; j < interface.num_altsetting; ++j) { const libusb_interface_descriptor &alt = interface.altsetting[j]; tmp += QString("Interface #[%1]: %2, Class: %3, SubClass: %4, Protocol: %5") .arg(i) .arg(alt.bInterfaceNumber) .arg(alt.bInterfaceClass) .arg(alt.bInterfaceSubClass) .arg(alt.bInterfaceProtocol); } interfaceList->insert(i, tmp); } libusb_free_config_descriptor(config); emit interfaceListUpdate(interfaceList); } void UsbHandler::listInterfaceEndpoints(int deviceIndex, int interfaceNumber) { LOG_DEBUG("devivceIdx is %d,interfaceiIdx is %d",deviceIndex,interfaceNumber); if (deviceIndex < 0 || deviceIndex >= deviceCount) { qDebug() << "无效的设备索引"; return; } libusb_device *device = deviceList[deviceIndex]; libusb_config_descriptor *config = nullptr; if (libusb_get_active_config_descriptor(device, &config) != 0) { qDebug() << "获取配置描述符失败"; return; } if (interfaceNumber < 0 || interfaceNumber >= config->bNumInterfaces) { qDebug() << "无效的接口编号"; libusb_free_config_descriptor(config); return; } const libusb_interface &interface = config->interface[interfaceNumber]; if (interface.num_altsetting < 1) { qDebug() << "接口无 altsetting"; libusb_free_config_descriptor(config); return; } endPointList = new QMap; for(int j=0;jinsert(k, info); } } libusb_free_config_descriptor(config); emit endPointListUpdate(endPointList); } bool UsbHandler::closeDevice() { if (handle) { libusb_close(handle); handle = nullptr; LOG_DEBUG("设备关闭成功"); return true; } else { LOG_DEBUG("无打开的设备"); return false; } }