Perangkat USB HID hanya menjalankan 1 peristiwa

11

Saya memiliki eDIO USB Multi Remote Controller (Penerima Inframerah) yang datang dengan ASUS PSR 2000 Web Surfing Remote Control.

Saya mencoba untuk menghubungkan COntroller Remote ke pi saya sehingga ia menerima penekanan tombol yang dikirim oleh remote.

Pengontrol terdeteksi sebagai perangkat HID. Berikut ini rincian dari perintah lsusb -v

    Bus 001 Device 007: ID 147a:e001 Formosa Industrial Computing, Inc.
    Couldn't open device, some information will be missing
    Device Descriptor:
    bLength                18
    bDescriptorType         1
    bcdUSB               1.10
    bDeviceClass            0 (Defined at Interface level)
   bDeviceSubClass         0
   bDeviceProtocol         0
   bMaxPacketSize0         8
   idVendor           0x147a Formosa Industrial Computing, Inc.
   idProduct          0xe001
   bcdDevice            1.22
   iManufacturer           1
   iProduct                2
   iSerial                 0
   bNumConfigurations      1
  Configuration Descriptor:
  bLength                 9
  bDescriptorType         2
wTotalLength           34
bNumInterfaces          1
bConfigurationValue     1
iConfiguration          4
bmAttributes         0xa0
  (Bus Powered)
  Remote Wakeup
MaxPower              300mA
Interface Descriptor:
  bLength                 9
  bDescriptorType         4
  bInterfaceNumber        0
  bAlternateSetting       0
  bNumEndpoints           1
  bInterfaceClass         3 Human Interface Device
  bInterfaceSubClass      1 Boot Interface Subclass
  bInterfaceProtocol      2 Mouse
  iInterface              0
    HID Device Descriptor:
      bLength                 9
      bDescriptorType        33
      bcdHID               1.10
      bCountryCode            0 Not supported
      bNumDescriptors         1
      bDescriptorType        34 Report
      wDescriptorLength      20
     Report Descriptors:
       ** UNAVAILABLE **
  Endpoint Descriptor:
    bLength                 7
    bDescriptorType         5
    bEndpointAddress     0x81  EP 1 IN
    bmAttributes            3
      Transfer Type            Interrupt
      Synch Type               None
      Usage Type               Data
    wMaxPacketSize     0x0004  1x 4 bytes
    bInterval              10

Saya juga dapat melihat perangkat target di folder dev dengan acara yang dibuat

    pi@raspberrypi /dev/input/by-id $ dir
    usb-Cypress_Semiconductor_eDio_USB_Multi_Remote_Controlle-event-if00

Event handler yang terkait dengannya adalah sebagai berikut seperti terlihat dari perintah berikut.

pi@raspberrypi /proc/bus/input $ cat devices
I: Bus=0003 Vendor=147a Product=e001 Version=0110
N: Name="Cypress Semiconductor eDio USB Multi Remote Controlle"
P: Phys=usb-bcm2708_usb-1.2/input0
S: Sysfs=/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/input/input2
U: Uniq=
H: Handlers=event0
B: PROP=0
B: EV=1

Masalahnya adalah ketika saya mencoba membaca output dari event handler yang dibuat untuk perangkat. Keystroke pertama terdaftar tetapi stroke tombol berikutnya tidak ditampilkan oleh perintah CAT.

 pi@raspberrypi /dev/input $ cat event0 | xxd
 0000000: e007 9450 9476 0900 0000 0000 0000 0000  ...P.v..........

Tolong sarankan saya apa yang bisa saya lakukan agar perangkat berfungsi. Menekan tombol apa saja setelah penekanan tombol pertama tidak mengembalikan apa pun kecuali perangkat dipasang kembali.

Harap sarankan apa yang perlu dilakukan untuk memperbaiki masalah ini.

SteveIrwin
sumber
Ada yang lain ??? Saya tidak mengerti apa yang terjadi dengan perangkat ini. Mungkin seorang moderator dapat membantu saya membingkai pertanyaan dengan lebih baik jika itu masalah di sini?
SteveIrwin
Pertanyaannya bagus. Namun, ini sangat terlokalisasi, jadi saya yakin tidak banyak orang akan memiliki masalah yang sama. Mungkin menenangkan Anda untuk mengetahui bahwa saya telah melihat sesuatu yang sangat mirip digunakan oleh perahu berbicara Chris Wallace sehingga Anda bisa melihatnya. Hal pertama yang akan saya tanyakan untuk mendiagnosis masalah adalah; apakah Anda menggunakan hub berdaya sendiri, karena itu bisa menjadi masalah daya.
Jivings
Sudahkah Anda mencoba tanpa |xxd? Ini buffer output. Saya menggunakan irwdari paket lircuntuk mendapatkan kode kunci yang dikirim oleh remote saya.
macrojames
driver kustom berarti Patch Kernel Linux. Opsi yang lebih mudah adalah menggunakan libusb karena libusb memberikan akses langsung ke USB Endpoints.
Lars Pötter

Jawaban:

5

Masalahnya adalah Descrioptors USB yang tidak lengkap:

  Couldn't open device, some information will be missing
  Report Descriptors:
  ** UNAVAILABLE **

Deskriptor yang dapat dibaca mengatakan bahwa ini adalah Mouse.

  bInterfaceProtocol      2 Mouse

Dan akan ada Descriptor sebesar 20 Bytes yang menjelaskan format data:

  bDescriptorType        34 Report
  wDescriptorLength      20

Tapi yang itu hilang.

Ada Masalah aneh dengan kombinasi spesifik Perangkat Keras dan Perangkat Lunak Anda atau Programmernya malas dan tidak mengimplementasikan Penjelasan Laporan, karena Pengemudi mereka sendiri mungkin tidak memerlukannya. Tetapi kemungkinan besar yang mendapat Driver yang membuat perangkat input bingung.

Anda dapat mencoba menggunakan libusb untuk membaca 4 byte dari titik akhir. Mungkin hasil polling. Atau lihat komunikasi USB ketika Anda menggunakan perangkat dengan driver asli. Dan ya ini sangat sulit jika Anda tidak memiliki salah satu Penebang USB mahal yang ada. Tetapi Kernel Linux memiliki dukungan untuk Logging USB Perangkat Lunak dan ada beberapa Logger perangkat lunak untuk Windows tersedia.

Lars Pötter
sumber
4

Akhirnya saya punya waktu untuk menulis implementasi saya sendiri menggunakan perpustakaan PyUSB yang merupakan pembungkus untuk Libusb.

Saya memposting kode di sini. Tolong bantu seseorang.

Saya memiliki sepotong kode lain yang membuat file konfigurasi yang digunakan di sini. Saya tidak memetakan semua tombol jarak jauh karena saya tidak membutuhkan semuanya.

import usb.core
import usb.util
import ConfigParser 
import shlex
import subprocess
import logging

# find our device
diction={
  6402315641282315:'1',
  6402415641282415:'2',
  6402515641282515:'3',
  6402615641282615:'4',
  6402715641282715:'5',
  6402815641282815:'6',
  6402915641282915:'7',
  6403015641283015:'8',
  6403115641283115:'9',
  }



def load_config():
    dict={}
    config = ConfigParser.RawConfigParser()
    config.read('/codes/remote/remote.cfg')

    dict['vendor']=config.getint('Settings','idVendor')

    dict['product']=config.getint('Settings','idProduct')

    dict['interface']=config.getint('Settings', 'interface')

    r=config.options('Key Mappings')

    for item in r:
        if config.get('Key Mappings',item)!='': 
            dict[item]=config.get('Key Mappings',item)
            #print config.get('Key Mappings',item)
    return dict

def pyus():

    try:
        load_log()
        dict=load_config()
        join_int = lambda nums: int(''.join(str(i) for i in nums))
        #print dict

        dev = usb.core.find(idVendor=dict['vendor'], idProduct=dict['product'])
        interface=dict['interface']

        if dev is None:
            raise ValueError('Device not found')

        if dev.is_kernel_driver_active(interface) is True:
                #print "but we need to detach kernel driver"
                dev.detach_kernel_driver(interface)
        #dev.detatch_kernel_driver(interface) 
        # set the active configuration. With no arguments, the first
        # configuration will be the active one
        dev.set_configuration()

        # get an endpoint instance
        cfg = dev.get_active_configuration()
        interface_number = cfg[(0,0)].bInterfaceNumber
        alternate_setting = usb.control.get_interface(dev,interface_number)
        intf = usb.util.find_descriptor(
            cfg, bInterfaceNumber = interface_number,
            bAlternateSetting = alternate_setting
        )

        ep = usb.util.find_descriptor(
            intf,
            # match the first IN endpoint
            custom_match = \
            lambda e: \
                usb.util.endpoint_direction(e.bEndpointAddress) == \
                usb.util.ENDPOINT_IN
        )

        assert ep is not None
        #print 'packet details',ep.bEndpointAddress , ep.wMaxPacketSize

        while 1:
            try:
                data = dev.read(ep.bEndpointAddress, ep.wMaxPacketSize*2,interface,1000)
                data=data.tolist()
                key=join_int(data)
                #print "Key is " , key
                if  key in diction:

                    try:
                        args=shlex.split(dict[diction[key]])
                        #print args
                        p=subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
                        #print "Pressed key is ",diction[key]
                    except:
                        pass


            except usb.core.USBError as e:
                pass
    except:
        pass

pyus()
SteveIrwin
sumber