Ubuntu Suomen keskustelualueet
Muut alueet => Muut käyttöjärjestelmät ja Linux-jakelut => Aiheen aloitti: Tomin - 20.12.16 - klo:16.29
-
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:
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öä:
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:
sudo udevadm control --reload && sudo udevadm trigger
Silti 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 yritin tämmöistä säännöstöä:
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:
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
-
Viimeksi yritin tämmöistä säännöstöä:
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:
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ä:
$ 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:
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öä).
-
Hmm, joo, ei tee mitään eli jokin on pielessä. Olisikohan tästä tulosteesta jotain hyötyä:
$ udevadm info -a -n /dev/hidraw0
Joo. Noissa laitekohtaisissa listauksissa ei missään täyty kaikki asettamasi ehdot. Tämä on lähimpänä:
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:
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df"
-
udev-sääntö mätsää tuohon jos tipautat pois KERNEL="hidraw?" -ehdon ja vaihdat vendor-id:ksi 16c0:
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 (https://github.com/voidlinux/void-packages/issues/3117)):
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:
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
-
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.
-
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:
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.