Udev – Making Rule for Bluetooth Keyboard

bluetoothkeyboardudev

I'm using a logitech k810 bluetooth keyboard with my laptop running Debian Wheezy. (I got the keyboard working by following this guide.)

By default the F1-12 keys are multimedia keys unless the FN key is pressed. I prefer the keys to be F1-12 by default.

Luckily this guy made a program that reverses the key functions. Running the program works to get the keys as I like and it survives reboot.

Unfortunately the program doesn't survive if I turn the keyboard off and on again (to save power.)

For this reason I'm trying to make a udev rule to run the key reversal program when the keyboard connects.

I've been trying the the following solution which is proposed in both the above links. So far it's not working.

andreas@crunchbang:/etc/udev/rules.d$ cat 00-k810.rules
KERNEL==”hidraw*”, SUBSYSTEM==”hidraw”, ATTRS{address}==”00:1F:20:76:41:30”, RUN+=”/srv/scripts/k810.sh %p”

andreas@crunchbang:/srv/scripts$ cat k810.sh
#! /bin/bash
line=`dmesg | grep -i k810 | grep hidraw`
[[ $line =~ (.*)(hidraw+[^:])(.*) ]]
device=${BASH_REMATCH[2]}
/srv/bin/k810_conf -d /dev/${device} -f on

The /srv/bin/ folder does indeed contain the program for key reversal (k810_conf). I don't know exactly what the program does but running it with the script like this works:

sudo /srv/scripts/k810.sh

So the problem has to be with udev not detecting the device properly.
The MAC address is the one i get if I do:

hcitool scan

… while the keyboard is in pairing mode. It's also the one I see in Blueman.

Not sure if it's relevant but this is the output of udevadm monitor when the keyboard is turned on:

KERNEL[31976.490290] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/0005:046D:B319.001C
(hid) KERNEL[31976.491464] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/input39
(input) KERNEL[31976.491689] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/input39/event12
(input) KERNEL[31976.491885] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/0005:046D:B319.001C/hidraw/hidraw0
(hidraw) UDEV  [31976.496400] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/0005:046D:B319.001C
(hid) UDEV  [31976.497196] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/input39
(input) UDEV  [31976.499496] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/0005:046D:B319.001C/hidraw/hidraw0
(hidraw) UDEV  [31976.500679] add     
/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/bluetooth/hci0/hci0:12/input39/event12
(input)

Any ideas on why the above udev rule isn't working – and how I can make a working one?

Best Answer

At least in my case, the problem was that the address needs to be in lower case! So, in your case, change ATTRS{address}=="00:1F:20:76:41:30" to the following:

ATTRS{address}=="00:1f:20:76:41:30"

In case that doesn't do it, I'd double check the permissions.

Also, udev should set a DEVNAME variable (among others) which you can use, so you don't really need the grep the logs (another possible candidate for a permission issue). To troubleshoot further, you could just create a log file every time the script is run (from the script) - that way, you will know if the script was run at all - i.e. if the udev rule triggered at all, or if the error is somewhere later on.

So, the authors script solution (on the page you have already linked) is better IMO. I've adapted it as such:

Permissions:

# ls -l /etc/udev/rules.d/50-k810.rules /opt/bin/k810*
-rw-r--r-- 1 root root   106 2014-07-16 19:21 /etc/udev/rules.d/50-k810.rules
-rwxr-xr-x 1 root root   304 2014-07-16 19:39 /opt/bin/k810.sh
-rwxr-xr-x 1 root root 13102 2014-06-07 22:05 /opt/bin/k810_conf

50-k810.rules:

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{address}=="my:k8:10:ad:re:ss" \
 RUN+="/opt/bin/k810.sh %p"

k810.sh:

#!/bin/sh
LOGFILE=/tmp/logfilek810sh.log
echo "RUN: at `date` by `whoami` act $ACTION \$1 $1 DEVPATH $DEVPATH DEVNAME $DEVNAME" >> ${LOGFILE}
echo "Setting F-keys on for your K810!"

if [ "$ACTION" == "add" ];
then
    # configure k810 ($DEVPATH) at $DEVNAME.
    /opt/bin/k810_conf -d $DEVNAME -f on
fi

Also, one little thing: You can use udevadm info -a -n /dev/hidraw1 to get the right address instead of hcitool (replace with the right hidraw). It should match, but just to double check (that's how I figured udev is seeing a lower case address).

Related Question