2

我正在尝试从Wacom Inkling中提取实时数据

Roel Janssen 已经检查了这里的数据包:

// Some kind of handshaking.
// Values obtained by sniffing the USB connection between SketchManager and the device.
unsigned char usb_data[33];
memset (&usb_data, '\0', 33);
int bytes = 0;

memcpy (&usb_data, "\x80\x01\x03\x01\x02\x00\x00\x00", 8);
bytes += libusb_control_transfer (handle,
                                  0x21,         // bmRequestType
                                  9,            // bRequest
                                  0x0380,       // wValue
                                  0,            // wIndex
                                  usb_data,     // data
                                  33,           // wLength
                                  0);           // timeout

memcpy (&usb_data, "\x80\x01\x0a\x01\x01\x0b\x01\x00", 8);
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0);

memset (&usb_data, '\0', 33);
bytes += libusb_control_transfer (handle, 0xa1, 1, 0x0380, 0, usb_data, 33, 0);

memcpy (&usb_data, "\x80\x01\x0b\x01\x00\x00\x00\x00", 8);
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0);

memcpy (&usb_data, "\x80\x01\x02\x01\x01\x00\x00\x00", 8);
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0);

memcpy (&usb_data, "\x80\x01\x0a\x01\x01\x02\x01\x00", 8);
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0);

memset (&usb_data, '\0', 33);
bytes += libusb_control_transfer (handle, 0xa1, 1, 0x0380, 0, usb_data, 33, 0);

我正在尝试使用HID API重写此代码,该 API具有非常小的 API(此处

我现在打算尝试使用hid_write,但这次握手可能会发送功能报告......?

有没有人可以查看该字节流并了解发生了什么?

编辑:似乎 Inkling 公开了 FlashDrive 和 HID 接口,所以我猜这个字节码一定是选择了 HID 接口并告诉它开始发送数据。但是我可以用更优雅/人类可读的形式对其进行编码吗?

编辑:我有它的工作!和hid_write工作hid_send_feature_report

hid_device* handle = hid_open(inklingVendorId, inklingProductId, NULL);
jassert(handle != nullptr);

int bytes_written =
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x03\x01\x02\x00\x00\x00", 8) +
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x0a\x01\x01\x0b\x01\x00", 8) +
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x0b\x01\x00\x00\x00\x00", 8) +
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x02\x01\x01\x00\x00\x00", 8) +
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x0a\x01\x01\x02\x01\x00", 8);
jassert(bytes_written == 5*8);

const int enable_nonblocking = 1, disable_nonblocking = 0;
jassert( hid_set_nonblocking(handle, disable_nonblocking) != FAIL); // want to block

while(true) {
    int bytes_got = hid_read(handle, usb_data, 10);

...但是我仍然想了解发生了什么。这是相当hacky。

编辑: lsusb 的输出(来自 Roel,我手头没有 Linux):

Bus 003 Device 002: ID 056a:0221 Wacom Co., Ltd 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x056a Wacom Co., Ltd
  idProduct          0x0221 
  bcdDevice           12.56
  iManufacturer           1 (error)
  iProduct                2 MSC Device
  iSerial                 5 4833000045C5549C0002DD012DA5549C
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           57
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          3 USB/MSC Inkling
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     215
          Report Descriptor: (length is 215)
            Item(Global): Usage Page, data= [ 0x0d ] 13
                            Digitizer
            Item(Local ): Usage, data= [ 0x02 ] 2
                            Pen
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Global): Report ID, data= [ 0x02 ] 2
            Item(Local ): Usage, data= [ 0x02 ] 2
                            Pen
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x30 ] 48
                            Direction-X
            Item(Local ): Usage, data= [ 0x31 ] 49
                            Direction-Y
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x80 0x07 ] 1920
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0x00 0x78 ] 30720
            Item(Global): Unit, data= [ 0x11 ] 17
                            System: SI Linear, Unit: Centimeter
            Item(Global): Unit Exponent, data= [ 0x0e ] 14
                            Unit Exponent: 14
            Item(Global): Report Size, data= [ 0x10 ] 16
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x0d ] 13
                            Digitizer
            Item(Local ): Usage, data= [ 0x42 ] 66
                            Tip Switch
            Item(Local ): Usage, data= [ 0x45 ] 69
                            Eraser
            Item(Local ): Usage, data= [ 0x44 ] 68
                            Barrel Switch
            Item(Local ): Usage, data= [ 0x32 ] 50
                            In Range
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x04 ] 4
            Item(Global): Unit, data= [ 0x00 ] 0
                            System: None, Unit: (None)
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x09 ] 9
                            Buttons
            Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                            Button 1 (Primary)
            Item(Local ): Usage Maximum, data= [ 0x04 ] 4
                            Button 4
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x04 ] 4
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x0d ] 13
                            Digitizer
            Item(Local ): Usage, data= [ 0x30 ] 48
                            Tip Pressure
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x00 0x04 ] 1024
            Item(Global): Report Size, data= [ 0x10 ] 16
            Item(Global): Report Count, data= [ 0x01 ] 1
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x0d ] 13
                            Digitizer
            Item(Local ): Usage, data= [ 0x3d ] 61
                            X Tilt
            Item(Local ): Usage, data= [ 0x3e ] 62
                            Y Tilt
            Item(Global): Logical Minimum, data= [ 0x81 ] 129
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x00 ] 0
                            Undefined
            Item(Global): Report ID, data= [ 0x04 ] 4
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x0c ] 12
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x00 ] 0
                            Undefined
            Item(Global): Report ID, data= [ 0x08 ] 8
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x3b ] 59
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x01 ] 1
                            Pointer
            Item(Global): Report ID, data= [ 0x80 ] 128
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x20 ] 32
            Item(Main  ): Feature, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x02 ] 2
                            Mouse
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Global): Report ID, data= [ 0x01 ] 1
            Item(Local ): Usage, data= [ 0x01 ] 1
                            Pointer
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x30 ] 48
                            Direction-X
            Item(Local ): Usage, data= [ 0x31 ] 49
                            Direction-Y
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x80 0x07 ] 1920
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0x00 0x78 ] 30720
            Item(Global): Unit, data= [ 0x11 ] 17
                            System: SI Linear, Unit: Centimeter
            Item(Global): Unit Exponent, data= [ 0x0e ] 14
                            Unit Exponent: 14
            Item(Global): Report Size, data= [ 0x10 ] 16
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x09 ] 9
                            Buttons
            Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                            Button 1 (Primary)
            Item(Local ): Usage Maximum, data= [ 0x03 ] 3
                            Button 3 (Tertiary)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x03 ] 3
            Item(Global): Unit, data= [ 0x00 ] 0
                            System: None, Unit: (None)
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Report Count, data= [ 0x05 ] 5
            Item(Main  ): Input, data= [ 0x01 ] 1
                            Constant Array Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              4 USB/MSC Inkling
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      2
Device Status:     0x0000
  (Bus Powered)
4

2 回答 2

2

1) 验证 Inkling 使用 HID USB 设备类。尝试lsusb -v检查输出中的bDeviceClassorbInterfaceClass字段(USB 人机接口设备类可用于描述设备和接口类。当 USB 设备可以包含多个功能时使用接口类。来自https://en。 wikipedia.org/wiki/USB_human_interface_device_class)在手册(https://www.wacom.com/~/media/files/store-manuals/inkling-manual-english.pdf)中说它是一个USB闪存驱动器,在这种情况下,它使用 USB 大容量存储设备类(BULK 传输)

2) 如果是 USB HID 设备类,您可以尝试获取类似于此网站http://libusb.6.n5.nabble.com/How-to-get-HID的功能报告(如果有任何提示) -report-td4628.html

libusb_get_descriptor 发出标准的GET_DESCRIPTOR请求,其中 bmRequestType 字段为0x80。 DT_REPORT描述符请求必须表明接收方是一个接口,要求 bmRequestType 0x81。

你有两个不错的选择。报告描述符都包含在配置描述符中,因此您应该能够整体获取整个配置描述符并对其进行解析以提取报告描述符。

或者, libusb_get_descriptor 是一个非常薄的层 libusb_control_transfer ,所以你可以手动扩展它:

res = libusb_control_transfer( devh, LIBUSB_ENDPOINT_IN |
LIBUSB_RECIPIENT_INTERFACE,
LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8) | 0, 0, buf,
sizeof(buf), 1000);

更多链接:- http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/ http://www.beyondlogic.org/usbnutshell/usb1.shtml

---------------------------------------------------------------------------------

libusb_control_transfer执行USB 控制传输控制传输用于命令和状态操作,请参阅此http://libusb.sourceforge.net/api-1.0/group__syncio.html和此http://www.beyondlogic.org/usbnutshell/usb4.shtml#Control

USB 控制请求USB 请求的子类型,请参阅http://www.beyondlogic.org/usbnutshell/usb6.shtml

usb_data似乎是 USB 发送缓冲区,它总是充满数据字节,然后libusb_control_transfer发送

这是 USB 控制请求的注释形式 ( http://www.beyondlogic.org/usbnutshell/usb6.shtml )

memcpy (&usb_data, "\x80\x01\x03\x01\x02\x00\x00\x00", 8);
bytes += libusb_control_transfer (handle,
                                  0x21,         // bmRequestType
                                  9,            // bRequest
                                  0x0380,       // wValue
                                  0,            // wIndex
                                  usb_data,     // data
                                  33,           // wLength
                                  0);           // timeout

这是 USB 控制请求的缩写形式

memcpy (&usb_data, "\x80\x01\x0a\x01\x01\x0b\x01\x00", 8);
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0);

所以所有的字节序列"\x80\x01\x03\x01\x02\x00\x00\x00"都是用于配置 Inkling(“握手”)的命令代码,只有 Inkling 和 Wacom 的人才能理解......

于 2016-05-11T15:37:54.170 回答
1

这是您通过 USB 发送的一份报告:

 80 01 03 01 02 00 00 00 .... (in total the buffer is 1+32 = 33 bytes)
 ^^                       Report ID

这是 HID 描述符的相关部分:

...
Item(Global): Report ID, data= [ 0x80 ] 128
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x20 ] 32
Item(Main  ): Feature, data= [ 0x02 ] 2
                Data Variable Absolute No_Wrap Linear
                Preferred_State No_Null_Position Non_Volatile Bitfield

这表示您的报告 ID 0x80 的数据必须被解释为 32 乘以一个字节(我猜它的含义取决于驱动程序)。这是一项功能,这意味着它可以通过控制端点GET_FEATURE/报告来配置设备。SET_FEATURE

有关如何解释此描述符的更多信息,请参阅http://www.usb.org/developers/hidpage/中的 HID v1.1 规范。

于 2016-05-12T14:36:09.937 回答