2016-05-11 28 views
2

上でバイトを調べることによって、私はリアルタイムのデータを抽出しようとしているWacom InklingHIDハンドシェイクをUSB

から

ロエル・ヤンセンは既にパケットにhereを検討しています

// 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); 

私は非常に最小限のAPIを持つHID APIを使用してこのコードを書き換えようとしています(here

今はhid_writeを使用しようとしていますが、 akeはfeature reportを送信しています...?

そのバイストストリームを見て、何が起こっているのか見ることができる人がいますか?

EDIT:予感がFlashDriveのとHIDインターフェースを公開表示されますので、私はこのバイトコードは、HIDインターフェイスを選択し、データの送信を開始するように指示する必要があります推測しています。しかし、よりエレガントな/人間が読める形式でそれをコーディングすることはできますか?

編集:私はそれが働いている! hid_writehid_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); 

...しかし、私はまだ何が起こっているのか理解したいと思います。これはかなりハッキリです。

EDIT:lsusbがの出力(ロエルから、私が手に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) 

答えて

2

1)暗示がHID USBデバイスクラスを使用していることを確認します。 lsusb -vを試して、の出力でbDeviceClassまたはbInterfaceClassフィールドを確認してください()。USBヒューマンインターフェイスデバイスクラスは、デバイスクラスとインターフェイスクラスの両方を表すために使用できます。 )マニュアル(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 bmRequestTypeフィールドが 0x80の標準 GET_DESCRIPTOR リクエストを作成します。 DT_REPORT ディスクリプタ要求が は、受信者が 0x81となるように bmRequestTypeが必要インターフェースであることを示さなければなりません。

2つの選択肢があります。レポートディスクリプタはすべてコンフィグレーションディスクリプタ に含まれているため、 コンフィグレーションディスクリプタ全体をフェッチし、解析してレポート 記述子を抽出できるはずです。また

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"ようなすべてのバイト配列は、コマンドコードでありますインクリメント(「ハンドシェイク」)を設定するために使用され、インクリングとワコムの人々だけが理解しています。

+0

ありがとうございます。私はここで情報をダイジェストしていますが、主にあなたがlsusbに関するあなたの意見を確認するために質問を更新しました。 –

+0

更新済みの回答... –

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回に1バイト(それのように解釈されなければならないことを言います意味は私が推測するドライバーまでです)。これは、制御エンドポイントを介してGET_FEATURE/SET_FEATUREレポートを介してデバイスを設定できることを意味する機能です。

このディスクリプタの解釈方法の詳細については、http://www.usb.org/developers/hidpage/のHID v1.1仕様を参照してください。

関連する問題