After much trial and error, false starts and...so much log reading, I managed to get a keyboard over Bluetooth classic (not BLE) working on my PW5/PW6 running jailbroken 5.18. (Older versions may also work, I just don't have any devices to test on.)
This definitely requires a jailbroken device and some kinda dangerous operations.
Enabling Bluetooth HID devices
This requires a small udev rule to keep things working after reboots, reconnects, or
btmanagerd crashes
The Kindle comes with a version of the X server (v1.8.2, from 2010) that requires
udev 148 or newer to support "hot plugged" input devices, because the X server looks for certain properties on the devices that older versions don't set. Unfortunately, the Kindle firmware ships udev 146, so we have to do that part manually. Since Bluetooth keyboards will basically
always be hot plugged (you don't want to restart the X server every time it connects), this is an important step.
Create a small shell script (e.g.
/usr/local/bin/dev_is_keyboard.sh, and don't forget to
chmod +x) that detects whether an attached device is capable of keyboard input.
Code:
#!/bin/sh
DEVICE=$1
if evtest info $DEVICE | grep -q 'Event type 1 (Key)'; then
if evtest info $DEVICE | grep -q 'Event code 16 (Q)'; then
# Don't set these just because Key is supported -- that will
# detect the touchscreen as a keyboard which breaks the UI
echo ID_INPUT=1
echo ID_INPUT_KEY=1
echo ID_INPUT_KEYBOARD=1
fi
fi
Now, we need a file to run this as part of a udev rule, and fix up some file permissions. Create one, like
/etc/udev/rules.d/99-bt-keyboard.rules:
Code:
KERNEL=="uhid", MODE="0660", GROUP="bluetooth"
ACTION=="add", SUBSYSTEM=="input", IMPORT+="/usr/local/bin/dev_is_keyboard.sh %N"
The first rule is necessary as restarts of
btmanagerd seem to reset it to being owned by root. The second one runs the script and adds its output to the properties of the device.
Run
udevadm control --reload-rules once this is in place.
Pairing a device
The
ace_bt_cli tool can be used to manipulate the Bluetooth (classic and BLE) system.
Code:
ACEBTCLI BT Client :: start
p_data (size:27) = 1B 00 00 00 00 00 00 00 00 00 00 61 63 65 5F 62
74 5F 63 6C 69 00 00 00 00 00 00
ACEBTCLI BT Client :: opened session with 0x19b9550
>:
Check if bluetooth is enabled
Run
radiostate; you should see
ACEBTCLI getRadioState() state:1 status:0.
If it's not enabled, run
enable.
Run
help to see all the options, but we're mostly just interested in
pair here.
Finding your Bluetooth address
You can try
classic scan here, but it also filters out non-audio devices. You'll need to know the Bluetooth address of your keyboard. (On macOS, you can find it in the Bluetooth settings: option-click on the icon for your keyboard in the device list. Alternately,
install blueutil and run
blueutil inquiry. I'm not sure how to do this on Windows or Linux, sorry.)
Pairing
Once you have the address, pair it -- the address must be colon separated (or no separator at all):
Code:
>: pair 19:18:17:16:15:14
At this point, if everything went correctly, you should have a connected keyboard that can type in applications like kterm, the built-in browser, etc.
If it didn't work, you'll have some debugging to do.
Debugging
Spoiler:
Check if the device is connected:
Code:
# ace_bt_cli
>: connectedlist
ACEBTCLI Got 1 devices for getConnectedDevices
ACEBTCLI xx:15:14
ACEBTCLI aceBT_freeDeviceList with status 0
Check that
/dev/uhid is accessible to the Bluetooth software:
Code:
[root@kindle us]# ls -l /dev/uhid
crw-rw---- 1 root bluetoot 10, 239 Aug 30 22:44 /dev/uhid
Check that your device exists:
Code:
[root@kindle us]# cat /proc/bus/input/devices
...
I: Bus=0005 Vendor=0abc Product=0123 Version=0001
N: Name="BT keyboard"
P: Phys=
S: Sysfs=/devices/virtual/misc/uhid/0005:0ABC:0123.0003/input/input4
U: Uniq=19:18:17:16:15:14
H: Handlers=leds event2 perfmgr
...
Note the event# here; check your Kindle is receiving keypresses (but may not be making it to the X server):
Code:
[root@kindle us]# evtest /dev/input/event2
...
Testing ... (interrupt to exit)
Event: time 1756676427.351791, type 4 (Misc), code 4 (ScanCode), value 7002c
Event: time 1756676427.351791, type 1 (Key), code 57 (Space), value 1
Event: time 1756676427.351791, -------------- Report Sync ------------
If that works, then the Bluetooth parts are all fine and it's the X server device detection that is not working.
Check
/tmp/x.err for any relevant logs.
Check
/var/log/messages for any logs related to
ace or mention the redacted address of your device (a device address "19:18:17:16:15:14" may be logged as "xx:15:14").
Run
udevadm monitor while connecting your device. Confirm that
udevadm info --query=property --name /dev/input/event2 shows
IS_INPUT=1 and
IS_INPUT_KEY=1.
While this is probably a bit more invasive than most would hope, I thought I'd share what I found and document the debugging steps for any future determined souls