About Blog Projects Papers Contact

I said I'd never blog

DeforaOS, NetBSD, reverse-engineering and stuff
Using the PS3 wireless keypad on NetBSD
Blog post by khorben
on Saturday, January 16 2010, 14:16

Member of

Name
bluetooth
netbsd
ps3
 
Just a few days ago, I took advantage of my short stopover in London to buy the official wireless keypad [1] for my PlayStation 3 (therefore with QWERTY layout, albeit UK). It's actually bluetooth-compliant (2.0), so I figured I'd be able to use it with my laptop or my Openmoko [2] for instance.

My laptop running NetBSD, and my being clueless about Bluetooth both indicated reading the NetBSD Guide's section about Bluetooth was a must [3]. I then figured I'd google a bit, and found this very interesting page about patches required for Linux [4]. First disappointing thing, it mentions that the device is not fully compliant with Bluetooth, and that pairing has to be done through the USB port, like on the PS3 itself.

Just in case, I tried a number of key combinations on the keypad to trigger pairing. I actually managed to obtain some useful information about the device. Here's how it goes:

1. Enable Bluetooth support on the laptop.
With the BIOS settings set on my T60, it means both disabling the wireless kill switch at the front, and pressing Fn+F5 to turn it on. The trademarked logo is lit, all is well.
$ dmesg | tail
[...]
ubt0 at uhub3 port 1
ubt0: Broadcom Corp BCM2045B, rev 2.00/1.00, addr 3
bthub0 at ubt0 local-bdaddr 00:YY:YY:YY:YY:YY
2. Enable the Bluetooth interface in NetBSD
Using the btconfig command, somewhat like ifconfig:
# btconfig ubt0 up
# btconfig ubt0
ubt0: bdaddr 00:YY:YY:YY:YY:YY flags 0x3<UP,RUNNING>
        num_cmd = 1
        num_acl = 8, acl_mtu = 1017
        num_sco = 1, sco_mtu = 64
# btconfig -v ubt0
ubt0: bdaddr 00:YY:YY:YY:YY:YY flags 0x3<UP,RUNNING>
        num_cmd = 1
        num_acl = 8, acl_mtu = 1017
        num_sco = 1, sco_mtu = 64
        HCI version: 2.0
        class: [0x000000]
        name: "IBM Callisto"
        voice: [0x0060]
        pin: variable
        options:
3. Enter discovery mode
According to the guide:
# btconfig ubt0 inquiry
Device Discovery from device: ubt0 .... 0 response
Repeat this while performing the next step.

4. Pair the device
Here's what I did:
  • maintain the "R1" button (double orange circles at the top right)
  • turn the device on
At this point the two LEDs on the left should blink as usual, but one after the other instead of together. It's a bingo:
# btconfig ubt0 inquiry 
Device Discovery from device: ubt0 ..... 1 response
  1: bdaddr 00:XX:XX:XX:XX:XX (keypad)
   : name "Wireless Keypad"
   : class: [0x002540] Peripheral Keyboard <Limited Discoverable>
   : page scan rep mode 0x01
   : clock offset 66
5. Notify the Bluetooth HID daemon
Add the address of the keypad to the /etc/bluetooth/hosts file:
00:XX:XX:XX:XX:XX       keypad
Add the device to the /etc/bluetooth/btdevctl.conf file:
HID             keypad                  ubt0
You would then be able to use it as a regular keyboard and mouse. Except it doesn't work for me yet. At this point, everything looks good:
# btdevctl -d ubt0 -a keypad -s HID
local bdaddr: 00:YY:YY:YY:YY:YY
remote bdaddr: 00:XX:XX:XX:XX:XX
link mode: encrypt
device type: bthidev
control psm: 0x0011
interrupt psm: 0x0013
Collection page=Generic_Desktop usage=Mouse
Collection page=Generic_Desktop usage=Pointer
  Input id=2 size=1 count=1 page=Button usage=Button_1 Variable, logical range 0..1
  Input id=2 size=1 count=1 page=Button usage=Button_2 Variable, logical range 0..1
  Input id=2 size=6 count=1 page=0x0000 usage=0x0000 Const Variable, logical range 0..1
  Input id=2 size=8 count=1 page=Generic_Desktop usage=X Variable Relative, logical range -127..127
  Input id=2 size=8 count=1 page=Generic_Desktop usage=Y Variable Relative, logical range -127..127
  Input id=2 size=8 count=1 page=0x0000 usage=0x0000 Const, logical range -127..127
  Input id=2 size=12 count=1 page=Microsoft usage=0x0020 Variable, logical range 0..4095
  Input id=2 size=12 count=1 page=Microsoft usage=0x0020 Variable, logical range 0..4095
  Input id=2 size=8 count=1 page=Microsoft usage=0x0021 Variable, logical range 0..255
End collection
End collection
Collection page=Generic_Desktop usage=Keyboard
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_LeftControl Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_LeftShift Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_LeftAlt Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_Left_GUI Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_RightControl Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_RightShift Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_RightAlt Variable, logical range 0..1
  Input id=1 size=1 count=1 page=Keyboard usage=Keyboard_Right_GUI Variable, logical range 0..1
  Input id=1 size=8 count=1 page=0x0000 usage=0x0000 Const, logical range 0..1
 Output id=1 size=1 count=1 page=LEDs usage=Num_Lock Variable, logical range 0..1
 Output id=1 size=1 count=1 page=LEDs usage=Caps_Lock Variable, logical range 0..1
 Output id=1 size=1 count=1 page=LEDs usage=Scroll_Lock Variable, logical range 0..1
 Output id=1 size=1 count=1 page=LEDs usage=Compose Variable, logical range 0..1
 Output id=1 size=1 count=1 page=LEDs usage=Kana Variable, logical range 0..1
 Output id=1 size=3 count=1 page=0x0000 usage=0x0000 Const, logical range 0..1
  Input id=1 size=8 count=6 page=Keyboard usage=No_Event, logical range 0..255
End collection
Collection page=0xff01 usage=0x0020
  Input id=3 size=8 count=1 page=0xff01 usage=0x0021 Variable, logical range 0..255
  Input id=3 size=8 count=1 page=0xff01 usage=0x0023 Variable, logical range 0..255
  Input id=3 size=8 count=6 page=0x0000 usage=0x0000 Const, logical range 0..255
 Output id=3 size=8 count=1 page=0xff01 usage=0x0024 Variable, logical range 0..1
End collection
Collection page=0xff02 usage=0x0020
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=4 size=8 count=1 page=0xff02 usage=0x0021 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
Feature id=5 size=8 count=1 page=0xff02 usage=0x0022 Variable, logical range 0..255
End collection
# btdevctl -d ubt0 -a keypad -s HID -A
# dmesg | tail
[...]
bthidev0 at bthub0 remote-bdaddr 00:XX:XX:XX:XX:XX link-mode encrypt
btkbd0 at bthidev0 reportid 1
wskbd1 at btkbd0 mux 1
wskbd1: connecting to wsdisplay0
btms0 at bthidev0 reportid 2: 2 buttons.
wsmouse1 at btms0 mux 0
bthidev0: reportid 3 not configured
bthidev0: reportid 4 not configured
bthidev0: reportid 5 not configured
But then it just doesn't work :(

Conclusion
It's quite sad that there isn't more official documentation in the box about the device. However, it's definitely possible to use the keyboard, although it'll probably require a couple patches to the NetBSD system. I'll let you know if I find enough time for this!

[1] http://en.wikipedia.org/wiki/PlayStation_3_accessories#Wireless_Keypad
[2] http://www.openmoko.org/
[3] http://www.netbsd.org/docs/guide/en/chap-bluetooth.html
[4] http://www.pabr.org/sixlinux/sixlinux.en.html

Come back...

Creative Commons License RSS