How does my perl script respond to arbitrary devices using UDev rather than HAL?

I would like to use a simple Perl script to create some configurations every time I connect, for example. my bluetooth headset. I tried using Net :: DBus , but my OS / DE (Fedora 17, GNOME3) no longer uses HAL.

I really don't want to install HAL just for this, so what should I do? My ideas so far:

  • (Preferred): use DBus; just listen to UDev events instead of org.freedesktop.Hal . Problem: I cannot find the appropriate service, org.freedesktop.UDisks only seems to be monitoring drives (duh). UDev even sends DBus messages to other devices, and if not, can I configure it for this?
  • Use the UDev rule to run another script. I like to have my scripts in one place for easy transition to new OS installations, so I would prefer to avoid this.
  • Am I better off just using Python to listen directly to UDev ?
  • Or can I use Perl for this? Finding CPAN for "udev" did not bring anything useful.

Or I can be completely turned off, and UDev is not even what I need. Neither documents nor Google were really helpful in this regard. A workaround would be if anyone knew how to get GNOME3 to switch the audio output to a newly connected default Bluetooth headset, but I would still like to learn how to write such scripts.

Thanks in advance for any pointers! A.

PS: By the way, Google & Co. claim that UDev receives devices and sends a HAL message, which in turn notifies DBus. This is certainly not the case, since the HAL does not even exist in Fedora Repos.

+4
source share
3 answers

You can use Udev :: FFI (cpanm Udev :: FFI)

For instance:

 use Udev::FFI; my $udev = Udev::FFI->new() or die "Can't create udev context."; my $monitor = $udev->new_monitor() or die "Can't create udev monitor."; $monitor->filter_by_subsystem_devtype('usb', 'usb_device'); $monitor->start() or die "Can't start monitor."; for(;;) { if(defined(my $device = $monitor->poll())) { my $action = $device->get_action(); if($action eq 'add') { #work with $device ... 
+1
source

No, udev does not send D-Bus events on its own. Programs such as Xorg, PuslseAudio, and udisks directly control uevents (some of which come from the kernel, and some of them are generated by udev). For many uevents, there is nothing that reflects them on the D-Bus.

udevadm monitor print the uevents stream. It is easy to read like a pipe in Perl. For instance,

 open my $udev, '-|', qw(udevadm monitor); while (<$udev>) { my ($source, $ts, $action, $dev, $sys) = split; if ($action eq 'add') { # etc. 

However, Bluetooth is handled via BlueZ on most distributions, and BlueZ provides a D-Bus interface. For example, you can track the org.bluez.Device1.Connected property of the /org/bluez/hciX/dev_XX_XX_XX_XX_XX_XX in the well-known name of the org.bluez system bus if you are interested in a specific device.

0
source

Have you checked Device :: USB?

http://metacpan.org/pod/Device::USB

You can use it to test your device in a loop.

It contains examples to get you started: https://metacpan.org/pod/distribution/Device-USB/dump_usb.pl

Hello,

-1
source

All Articles