HID 设备无法获取实际值

HID device cannot able to get actual value

我最近从中国买了一个二维条码扫描模块。根据他们的数据表,当我打开记事本时,它可以很好地扫描条形码。我需要做的就是尝试使用 libusb 并读取我的 c 代码上的条形码。我将英特尔爱迪生与配置为 USB 主机的 Ad运行io 分线板一起使用。

我已经安装了 libusb-1.0.20,不幸的是我无法安装 libusb-1.0.20-devel。请注意,我在这里没有使用 libusbx 和 libusbx-devel。

因为它是条形码扫描仪设备,所以它应该被检测为 HID 键盘。是的。

Bus 001 Device 003: ID 1eab:8203
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1eab
  idProduct          0x8203
  bcdDevice            1.00
  iManufacturer           1 NewLand
  iProduct                2 HidKeyBoard
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      63
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
Device Status:     0x0001
  Self Powered

而我的 C 代码是:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//gcc -o usbtest usbtest.c -lusb-1.0
//libusbx-devel, libusbx
#include <libusb-1.0/libusb.h>
void print_devices(libusb_device *dev)
{
    struct libusb_device_descriptor desc;
    struct libusb_config_descriptor *config;
    const struct libusb_interface *inter;
    const struct libusb_interface_descriptor *interdesc;
    const struct libusb_endpoint_descriptor *endpointdesc;

int ret;
int i,j,k;

ret = libusb_get_device_descriptor(dev, & desc);
if(ret < 0)
{
    fprintf(stderr, "error in getting device descriptor\n");
    return;
}

printf("Number of possible configs is %d\n",desc.bNumConfigurations);
printf("Vendor ID  : 0x%x\n", desc.idVendor);
printf("Product ID : 0x%x\n", desc.idProduct);

libusb_get_config_descriptor(dev, 0, &config);

printf("Interface %d\n", config->bNumInterfaces);

for(i=0; i < config->bNumInterfaces; i++)
{
    inter = &config->interface[i];
    printf("Number of alternate settings : %d\n", inter->num_altsetting);
    for(j=0; j < inter->num_altsetting; j++)
    {
        interdesc = &inter->altsetting[j];
        printf("   Interface number : %d, ", interdesc->bInterfaceNumber);
        printf("   Num of endpoints : %d\n", interdesc->bNumEndpoints);
        for(k=0; k < interdesc->bNumEndpoints; k++)
        {
            endpointdesc = &interdesc->endpoint[k];
            printf("     Desc type : %d ",endpointdesc->bDescriptorType);
            printf("      EP Addr: %d\n", endpointdesc->bEndpointAddress);
        }
    }
}
printf("\n\n");
libusb_free_config_descriptor(config);
}


int main(int argc, char *argv[])
{
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
    libusb_context *context = NULL; //a libusb session
    libusb_device_handle *dev_handle; //a device handle

size_t list;
size_t iter;
int retVal;
int kernelDriverDetached     = 0;  /* Set to 1 if kernel driver detached */

retVal = libusb_init(&context);
if(retVal < 0)
{
    perror("libusb_init");
    exit(1);
}

libusb_set_debug(context, 3); //set verbosity level to 3, as suggested in the documentation

list = libusb_get_device_list(context, &devs);
if(list < 0){
    fprintf(stderr, "Error in getting device list\n");
    libusb_free_device_list(devs, 1);
    libusb_exit(context);
    exit(1);
}

printf("There are %d devices found\n",list);

for(iter = 0; iter < list; iter++)
{
    /* print devices specs */
    print_devices(devs[iter]);
}

dev_handle = libusb_open_device_with_vid_pid(context, 0x1eab, 0x8203/*0x1d6b,0x0002*/); //these are vendorID and productID I found for my usb device
    if(dev_handle == NULL) {
    fprintf(stderr, "Unable to open device.\n");
        return 1;

}

/* Check whether a kernel driver is attached to interface #0. If so, we'll 
 * need to detach it.
 */
if (libusb_kernel_driver_active(dev_handle, 0))
{
        retVal = libusb_detach_kernel_driver(dev_handle, 0);
        if (retVal == 0)
        {
            kernelDriverDetached = 1;
        }
        else
        {
            fprintf(stderr, "Error detaching kernel driver.\n");
            return 1;
        }
}

/* Claim interface #0. */
retVal = libusb_claim_interface(dev_handle, 0);
if (retVal != 0)
{
        fprintf(stderr, "Error claiming interface.\n");
        return 1;
}

printf("Scanner Device Opened\n");

    struct libusb_transfer *transfer = libusb_alloc_transfer(0);
char buf[24];
int actualbytes;    
retVal = libusb_interrupt_transfer(dev_handle, /*0x84*/(4 | LIBUSB_ENDPOINT_IN), buf, 24, &actualbytes, 0);
if(retVal == 0) {
    printf("Received %d bytes\n",actualbytes);
}
else
{
    fprintf(stderr, "Error Receiving message. retVal : %d, Actual : %d\n",retVal,actualbytes);
}

for(iter = 0; iter < actualbytes; iter++){
    printf("Data[%d] = %d\n",iter,buf[iter]);
}

/* Release interface #0. */
retVal = libusb_release_interface(dev_handle, 0);
if (0 != retVal)
{
        fprintf(stderr, "Error releasing interface.\n");
}

/* If we detached a kernel driver from interface #0 earlier, we'll now 
 * need to attach it again.  */
if (kernelDriverDetached)
{
        libusb_attach_kernel_driver(dev_handle, 0);
}

/* Shutdown libusb. */
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
libusb_exit(context);


return 0;
}

我可以编译和 运行 代码、扫描、打开、读取设备。但是我能读到的数据都是零。尽管它说 wMaxPacketSize 0x0008 1x 8 bytesbLength 18 当我尝试将长度设置为 8,16,18 时它给了我错误。所以我改为24。我的实际条码(一维)数据大小是12bytes。

代码有问题吗?还是我需要添加更多核心才能读取实际的 bardcode。

我知道因为它检测为 HID 键盘设备,所以我收到的数据不会是 ASCII 格式(这是我所期望的)。我根据https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html

修改了代码

尽管文档说的是 16 位键码,但我只有在读取 16 字节时才能获得正确的数据。基于键码,我创建了一个 table 将 HID 键码转换为 ASCII。

但这在我的 Windows 机器上仍然不起作用,因为它说它无法打开设备。