Friday, 28 January 2011

How to share a Bluetooth keyboard between Linux and Windows dual boots

I recently go myself the Microsoft Bluetooth Mobile Keyboard 6000. It is a really nice small little wireless keyboard (Bluetooth) with excellent tactile feel, which works in both Linux (Debian) and Windows.

However whenever I boot from Linux to Windows or back, I have to pair the keyboard again. This is rather inconvenient.

Just sharing the same Bluetooth pin between Windows and Linux is not sufficient. The keyboard and PC uses the pin to create a key. It is this key that is used to associate the keyboard with the PC.

For sharing to work, you need to copy this key from the one OS to the other. Here's how I did it.

.. a recent update: I wrote a small perl script: bluetoothkbkeys to help with this. It reads your registry, assuming windows drive is mounted under /c, /mnt/c, or mounted with ntfs-3g, and spits out the device ID and key if it finds it in the registry. The old steps are still listed below, and you still need to associate your keyboard under linux first, and then under windows, and then extract the key with the script:

eedesne:~/bin% ~/bin/bluetoothkbkeys 
* Trying to read file: /c/Windows/System32/config/SYSTEM as 'SYSTEM' registry.
* Seeing if this is the latest controlset...
* Latest controlset: CMI-CreateHive{xxxx}\ControlSet001 [2012-07-08T23:47:14Z]

        Bluetooth device: bb:bb:bb:bb:bb:bb key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Now, simply replace the key for bb:bb:bb:bb:bb:bb in /var/lib/bluetooth/xx:xx:xx:xx:xx:xx/linkkeys with the value found (displayed as XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX here).

As previously, I cannot guarantee any of this to work anywhere else, or even to work again. I cannot guarantee you won't lose data, completely corrupt your OS, etc. Use at your own risk.

* associate the device under Linux

I used blueman-manager, you may have other ways of doing this.

* Make a note of the device id

It should look something like this: 55:55:55:55:55:55 (with different hex numbers)

* Boot into, and associate the device with Windows

* Boot back into Linux, but do not associate the keyboard.

* Get the key from the Windows registry

I mounted my windows drive under /c, and exported the SYSTEM tree using the hivexml tool, which is part of the libhivex-bin package. It is probably safest to mount the windows drive read-only.

I found Windows to store the device id all in lower case, and without the colon characters between character pairs, so 555555555555.

  cd /c/Windows/System32/config
  hivexml SYSTEM | perl -ane 's/</\n</g; print' | grep -i 'key="555555555555"'
This should give you one or more lines similar to this:

  <value encoding="base64" key="555555555555" type="binary">XXXXXXXXXXXXXXXXXXXXXX==</value>
Where the 'XXXXXXXXXXXXXXXXXXXXXX==' part is your key base64 encoded.

* Decode and convert the key to hex

perl -MMIME::Base64 -e 'print unpack("H*", decode_base64("XXXXXXXXXXXXXXXXXXXXXX==")) . "\n";'
* Replace the Bluetooth key under Linux

The key should be stored under /var/lib/bluetooth/<host_id>/linkkeys

Just replace the key part with the hex format one you got from the registry. The key will be the same length, on a line staring with the keyboard's device id.

Restart bluetooth, and you should now have a working keyboard.

/etc/init.d/bluetooth restart
Also see:

No comments:

Post a Comment