Logitech K810 Keyboard Configurator

Recently I bought a Logitech K810 Keyboard. The small bluetooth keyboard can connect wireless to PCs or other devices e.g. phones. It is equipped with backlight and supports 3 paired connections to devices.

Logitech K810

To use these extended functions and switch between profiles the function keys (F-keys) have a double meaning.

Logitech K810 function keys

After my purchase I found out that the default configuration uses the F-keys for the extended functionality on a direct key press. In order to use the regular F-keys the user has to hold down the FN-key in addition. As I want to use the keyboard mainly on a regular PC I could not live with it. Luckily Logitech offers a configuration tool for there range of mouses and keyboards under the name "SetPoint" for Microsoft Windows.

Logitech Setpoint software

However I was disappointed when I figured out that the configuration is not permanently stored in the keyboard and has to be sent everytime the keyboard is turned on. As I prefer Linux as operating system and do not use Microsoft Windows I could not use Logitech's software. I analyzed the communication to the HID device and created a small piece of software to sent the configuration message to the keyboard. In order to trace the bluetooth messages I executed SetPoint in a VirtualBox environment. The VM could connect trough an attached Bluetooth USB dongle to the keyboard. On the Linux host I loaded the usbmon kernel module in order to trace all messages on the USB layer to the CSR Bluetooth chip:

$ mount -t debugfs none_debugs /sys/kernel/debug
$ modprobe usbmon

As my Bluetooth dongle 0a12:0001 was attached to the 3rd bus I executed:

$ cat /sys/kernel/debug/usb/usbmon/3u

Linux shell - usbmon

When I toggled in SetPoint the flag 'Swap F key functions.' I figured out that the message payload was changing at a fixed position -> Found it!:

# Disable - Swap F key functions. -> use regular F key directly (OUT) 
ffff8803ea0853c0 3469985170 S Bo:3:003:2 -115 16 = 47000c00 08004200 a210ff06 15000000
# Response from Keyboard (IN)
ffff8803e6c36980 3470086675 C Bi:3:003:2 0 29 = 47201900 15004100 a111ff06 15000100 00000000 00000000 00000000 00

# Enable  - Swap F key functions. -> use regular F key together with FN key (OUT)
ffff8803277b0480 3483623889 S Bo:3:003:2 -115 16 = 47000c00 08004200 a210ff06 15010000
# Response from Keyboard (IN)
ffff8803e6c36980 3483991655 C Bi:3:003:2 0 29 = 47201900 15004100 a111ff06 15010100 00000000 00000000 00000000 00

The next steps were easy. Whenever the keyboard connects to BlueZ stack in Linux a 'hidraw' device is created:

[   65.632036] input: Logitech K810 as /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.4/3-1.4:1.0/bluetooth/hci0/hci0:11/input18
[   65.632268] generic-bluetooth 0005:046D:B319.0001: input,hidraw0: BLUETOOTH HID v12.01 Keyboard [Logitech K810] on XX:XX:XX:XX:XX:XX

Therefore I wrote a small program k810_conf to send the message sequence 0x10, 0xff, 0x06, 0x15, 0x00, 0x00, 0x00 to the keyboard's 'hidraw' device. My system is configured to automatically execute k810_conf whenever the keyboard connects.

The source of k810_conf was tested on Debian GNU Linux (Wheezy) and can be found here.

Update 2014-02-10:

In order to automate running the configuration everytime the keyboard connects the following udev rule can be used:

$ cat /etc/udev/rules.d/00-k810.rules
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{address}=="00:1F:AA:BB:CC:DD", \
  RUN+="/path/to/script/k810.sh %p"

you need to exchange 00:1F:AA:BB:CC:DD with your bluetooth id of the keyboard.

The script k810.sh can look like this:

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

$DEVNAME is automatically replaced by UDEV to the correct hidraw device path of the keyboard.