Kirjoittaja Aihe: Udev säännöt ja omatekoinen USB HID -laite [RATKAISTU]  (Luettu 5476 kertaa)

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11481
    • Profiili
    • Tomin kotisivut
Olen tässä yrittänyt keksiä millä keinoin saan estettyä hidrawia nappaamasta rakentamaani USB-laitetta (AtTiny85, jossa VUSB-kirjasto ja käynnistyslataajana micronucleus).  Laite toimii ihan ok, mutta en pysty käyttämään sitä, koska hidraw-ajuri vie ohjauksen. Laite näkyy näin lsusb-listauksessa:
Koodia: [Valitse]
Bus 005 Device 012: ID 16c0:05df Van Ooijen Technische Informatica HID device except mice, keyboards, and joysticks
Viimeksi yritin tämmöistä säännöstöä:
Koodia: [Valitse]
KERNEL=="hidraw?", SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="05df", RUN="/bin/sh -c 'echo -n $id:1.0 > /sys/bus/usb/drivers/usbhid/unbind'"Laitoin nuo tiedostoon /etc/udev/rules.d/10-power-switcher.rules ja komentelin:
Koodia: [Valitse]
sudo udevadm control --reload && sudo udevadm triggerSilti tuolle syntyy /dev/hidraw?-laite, kun kytken sen kiinni.

Jossain ehdotettiin greppaamaan tuo id $devpath-muuttujasta ja jossain muualla oli käytetty jotain muuta säätöä, joka ei sekään vaikuttanut toimivan. Kytkettäessä tuo laite menee ensimmäisenä tilaan, jossa se tarkistaa ollaanko sille syöttämässä ohjelmaa (micronucleus-käynnistyslataaja) ja sitten se "irrottaa" itsensä hetkeksi ja lopulta kytkee itsensä tuollaisena kuin lsusb-listauksesta näkyy. Voin laittaa pitemmänkin listauksen, jos se on tarpeen. Ongelma on varmaan jotain yksinkertaista, mutta en jaksa enää yksinäni tapella tämän kanssa, joten kysyn neuvoa.

Ja tietokoneessa alla on siis Fedora 25 (Linux 4.8.14 ja systemd/udev 231).

Muokkaus: Lisätty RATKAISTU-merkintä, sillä alkuperäinen ongelma on selvinnyt.
« Viimeksi muokattu: 21.12.16 - klo:15.47 kirjoittanut Tomin »
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

nm

  • Käyttäjä
  • Viestejä: 16428
    • Profiili
Vs: Udev säännöt ja omatekoinen USB HID -laite
« Vastaus #1 : 20.12.16 - klo:18.05 »
Viimeksi yritin tämmöistä säännöstöä:
Koodia: [Valitse]
KERNEL=="hidraw?", SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="05df", RUN="/bin/sh -c 'echo -n $id:1.0 > /sys/bus/usb/drivers/usbhid/unbind'"

Voisi kokeilla, laukeaako tuo sääntö lainkaan, eli ohjaa echon tuloste tavalliseen tiedostostoon:

Koodia: [Valitse]
KERNEL=="hidraw?", SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="05df", RUN="/bin/sh -c 'echo -n $id:1.0 > /unbind.log'"
Samalla näkee mitä $id sisältää.


Yksi vaihtoehto olisi irrottaa ajuri libusb:n funktiolla usb_detach_kernel_driver_np(): http://unix.stackexchange.com/questions/13964/prevent-claiming-of-novelty-usb-device-by-usbhid-so-i-can-control-it-with-libusb/14023#14023

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11481
    • Profiili
    • Tomin kotisivut
Vs: Udev säännöt ja omatekoinen USB HID -laite
« Vastaus #2 : 20.12.16 - klo:18.32 »
Viimeksi yritin tämmöistä säännöstöä:
Koodia: [Valitse]
KERNEL=="hidraw?", SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="05df", RUN="/bin/sh -c 'echo -n $id:1.0 > /sys/bus/usb/drivers/usbhid/unbind'"

Voisi kokeilla, laukeaako tuo sääntö lainkaan, eli ohjaa echon tuloste tavalliseen tiedostostoon:

Koodia: [Valitse]
KERNEL=="hidraw?", SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="05df", RUN="/bin/sh -c 'echo -n $id:1.0 > /unbind.log'"
Samalla näkee mitä $id sisältää.

Hmm, joo, ei tee mitään eli jokin on pielessä. Olisikohan tästä tulosteesta jotain hyötyä:
Koodia: [Valitse]
$ udevadm info -a -n /dev/hidraw0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:13.0/usb5/5-2/5-2:1.0/0003:16C0:05DF.000F/hidraw/hidraw0':
    KERNEL=="hidraw0"
    SUBSYSTEM=="hidraw"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:13.0/usb5/5-2/5-2:1.0/0003:16C0:05DF.000F':
    KERNELS=="0003:16C0:05DF.000F"
    SUBSYSTEMS=="hid"
    DRIVERS=="hid-generic"
    ATTRS{country}=="00"

  looking at parent device '/devices/pci0000:00/0000:00:13.0/usb5/5-2/5-2:1.0':
    KERNELS=="5-2:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usbhid"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="03"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="00"
    ATTRS{bInterfaceSubClass}=="00"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:13.0/usb5/5-2':
    KERNELS=="5-2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{bMaxPower}=="50mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bmAttributes}=="80"
    ATTRS{busnum}=="5"
    ATTRS{configuration}==""
    ATTRS{devnum}=="20"
    ATTRS{devpath}=="2"
    ATTRS{idProduct}=="05df"
    ATTRS{idVendor}=="16c0"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="hardware.tomin.site"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="USB Power Switcher"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="0000"
    ATTRS{speed}=="1.5"
    ATTRS{urbnum}=="16"
    ATTRS{version}==" 1.10"

  looking at parent device '/devices/pci0000:00/0000:00:13.0/usb5':
    KERNELS=="usb5"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0408"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="5"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0001"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Linux 4.8.14-300.fc25.x86_64 ohci_hcd"
    ATTRS{maxchild}=="5"
    ATTRS{product}=="OHCI PCI host controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="0000:00:13.0"
    ATTRS{speed}=="12"
    ATTRS{urbnum}=="556"
    ATTRS{version}==" 1.10"

  looking at parent device '/devices/pci0000:00/0000:00:13.0':
    KERNELS=="0000:00:13.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="ohci-pci"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x0c0310"
    ATTRS{consistent_dma_mask_bits}=="32"
    ATTRS{d3cold_allowed}=="0"
    ATTRS{device}=="0x4397"
    ATTRS{dma_mask_bits}=="32"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{irq}=="18"
    ATTRS{local_cpulist}=="0-3"
    ATTRS{local_cpus}=="0f"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="0"
    ATTRS{subsystem_device}=="0x8443"
    ATTRS{subsystem_vendor}=="0x1043"
    ATTRS{vendor}=="0x1002"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Yksi vaihtoehto olisi irrottaa ajuri libusb:n funktiolla usb_detach_kernel_driver_np(): http://unix.stackexchange.com/questions/13964/prevent-claiming-of-novelty-usb-device-by-usbhid-so-i-can-control-it-with-libusb/14023#14023

Haluaisin jättää option sille ettei ole pakko käyttää root-käyttäjää. Tosin tuli mieleen, että onnistuukohan se jos otan tuon hidrawin pois ja olisiko kuitenkin parempi käyttää laitetta sen läpi. Siltikin tuo matchays pitäisi saada toimimaan.

Muokkaus: Tuo jälkimmäinen kikka helpottaa kyllä sen verran, että nyt voin:
Koodia: [Valitse]
    for cfg in dev:
        for i in range(cfg.bNumInterfaces):
            if dev.is_kernel_driver_active(i):
                dev.detach_kernel_driver(i)
Missä dev on pyusb:n laite.
http://stackoverflow.com/questions/23203563/pyusb-device-claimed-detach-kernel-driver-return-entity-not-found
Ei välttämättä nätein tapa, mutta nopeasti kyhättynä tuntuu toimivan. Vaatii root-käyttäjän (no nyt ei ole muutenkaan vielä sitä udev-sääntöä).
« Viimeksi muokattu: 20.12.16 - klo:18.40 kirjoittanut Tomin »
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

nm

  • Käyttäjä
  • Viestejä: 16428
    • Profiili
Vs: Udev säännöt ja omatekoinen USB HID -laite
« Vastaus #3 : 20.12.16 - klo:18.48 »
Hmm, joo, ei tee mitään eli jokin on pielessä. Olisikohan tästä tulosteesta jotain hyötyä:
Koodia: [Valitse]
$ udevadm info -a -n /dev/hidraw0

Joo. Noissa laitekohtaisissa listauksissa ei missään täyty kaikki asettamasi ehdot. Tämä on lähimpänä:

Lainaus
looking at parent device '/devices/pci0000:00/0000:00:13.0/usb5/5-2':
    KERNELS=="5-2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{bMaxPower}=="50mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bmAttributes}=="80"
    ATTRS{busnum}=="5"
    ATTRS{configuration}==""
    ATTRS{devnum}=="20"
    ATTRS{devpath}=="2"
    ATTRS{idProduct}=="05df"
    ATTRS{idVendor}=="16c0"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="hardware.tomin.site"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="USB Power Switcher"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="0000"
    ATTRS{speed}=="1.5"
    ATTRS{urbnum}=="16"
    ATTRS{version}==" 1.10"

udev-sääntö mätsää tuohon jos tipautat pois KERNEL="hidraw?" -ehdon ja vaihdat vendor-id:ksi 16c0:

Koodia: [Valitse]
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df"

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11481
    • Profiili
    • Tomin kotisivut
Vs: Udev säännöt ja omatekoinen USB HID -laite
« Vastaus #4 : 20.12.16 - klo:19.07 »
udev-sääntö mätsää tuohon jos tipautat pois KERNEL="hidraw?" -ehdon ja vaihdat vendor-id:ksi 16c0:

Koodia: [Valitse]
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df"

Vai oli siellä kuitenkin typo... Kiitos. 8)

Muokkaus: Tällä näkyy saavan hidrawin pois, mutta rootin oikeuksia kaivataan edelleen (mukailtu vähän tuota):
Koodia: [Valitse]
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df", MODE="0666", RUN="/bin/sh -c 'echo -n $devpath | grep -o [0-9]-[0-9]:[0-9].[0-9] > /sys/bus/usb/drivers/usbhid/unbind'"Pitäisikö valmistajan lukeminen onnistua ilman root-käyttäjää? Ilman rootia nimittäin tulee seuraavaa:
Koodia: [Valitse]
Traceback (most recent call last):
  File "./switcher.py", line 100, in <module>
    sys.exit(main())
  File "./switcher.py", line 82, in main
    devs = get_devices()
  File "./switcher.py", line 39, in get_devices
    vendor_name = usb.util.get_string(dev, dev.iManufacturer)
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/util.py", line 314, in get_string
    raise ValueError("The device has no langid")
ValueError: The device has no langid
« Viimeksi muokattu: 20.12.16 - klo:19.17 kirjoittanut Tomin »
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

nm

  • Käyttäjä
  • Viestejä: 16428
    • Profiili
Vs: Udev säännöt ja omatekoinen USB HID -laite
« Vastaus #5 : 20.12.16 - klo:20.08 »
Pitäisikö valmistajan lukeminen onnistua ilman root-käyttäjää?

Pitäisi onnistua ainakin MODE="0666":n kanssa, joka tuossa on asetettuna. Ilmeisesti ongelma voi olla myös laitteen puolella, jos langid:tä ei ole määritelty siellä: https://github.com/walac/pyusb/issues/139

Halutun langid:n voi antaa myös usb.util.get_string -funktiolle parametrina.

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11481
    • Profiili
    • Tomin kotisivut
Vs: Udev säännöt ja omatekoinen USB HID -laite
« Vastaus #6 : 20.12.16 - klo:20.47 »
Pitäisikö valmistajan lukeminen onnistua ilman root-käyttäjää?

Pitäisi onnistua ainakin MODE="0666":n kanssa, joka tuossa on asetettuna. Ilmeisesti ongelma voi olla myös laitteen puolella, jos langid:tä ei ole määritelty siellä: https://github.com/walac/pyusb/issues/139

Juu, tuohon törmäsinkin jo aiemmin. Jotenkin ymmärrys oli ettei noita tarvita, mutta ei myöskään selvinnyt miten nuo asetetaan. Tutkiskelenpa lisää ja selvitän josko tuosta olisi hyötyä.

Halutun langid:n voi antaa myös usb.util.get_string -funktiolle parametrina.

Ei tuntunut tehoavan. Jos antaa langid=0x0809 saa saman virheen ja jos laittaa ensin dev._langids=(0x0809, ) niin sitten tulee toisenlainen virhe:
Koodia: [Valitse]
Traceback (most recent call last):
  File "./switcher.py", line 101, in <module>
    sys.exit(main())
  File "./switcher.py", line 83, in main
    devs = get_devices()
  File "./switcher.py", line 40, in get_devices
    vendor_name = usb.util.get_string(dev, dev.iManufacturer)
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/util.py", line 325, in get_string
    langid
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/control.py", line 173, in get_descriptor
    data_or_wLength = desc_size)
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/core.py", line 1025, in ctrl_transfer
    self._ctx.managed_open()
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/core.py", line 120, in managed_open
    self.handle = self.backend.open_device(self.dev)
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/backend/libusb1.py", line 786, in open_device
    return _DeviceHandle(dev)
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/backend/libusb1.py", line 643, in __init__
    _check(_lib.libusb_open(self.devid, byref(self.handle)))
  File "/home/tomi/.local/lib/python2.7/site-packages/usb/backend/libusb1.py", line 595, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 13] Access denied (insufficient permissions)

Pohdin kyllä sitäkin, että pitäisiköhän suosiolla säilyttää tuo hidraw-ajurina ja sitten käyttää laitetta sen kautta. Voisi olla helpompaa. Siihen ei taida kuitenkaan olla mitään yleisesti käytettyä Python-kirjastoa, Google-haku antaa useamman vaihtoehdon.
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.