3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <sys/types.h>
35 #include <bluetooth/bluetooth.h>
39 #include "../src/adapter.h"
40 #include "../src/device.h"
47 enum ps3remote_special_keys {
54 PS3R_BIT_TRIANGLE = 12,
68 static unsigned int ps3remote_bits[] = {
69 [PS3R_BIT_ENTER] = 0x0b,
71 [PS3R_BIT_SQUARE] = 0x5f,
72 [PS3R_BIT_CROSS] = 0x5e,
73 [PS3R_BIT_CIRCLE] = 0x5d,
74 [PS3R_BIT_TRIANGLE] = 0x5c,
79 [PS3R_BIT_LEFT] = 0x57,
80 [PS3R_BIT_DOWN] = 0x56,
81 [PS3R_BIT_RIGHT] = 0x55,
83 [PS3R_BIT_START] = 0x53,
86 [PS3R_BIT_SELECT] = 0x50,
89 static unsigned int ps3remote_keymap[] = {
93 [0x63] = KEY_SUBTITLE,
110 [0x70] = KEY_INFO, /* display */
111 [0x1a] = KEY_MENU, /* top menu */
112 [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
113 [0x0e] = KEY_ESC, /* return */
114 [0x5c] = KEY_OPTION, /* options/triangle */
115 [0x5d] = KEY_BACK, /* back/circle */
116 [0x5f] = KEY_SCREEN, /* view/square */
117 [0x5e] = BTN_0, /* cross */
123 [0x5a] = BTN_TL, /* L1 */
124 [0x58] = BTN_TL2, /* L2 */
125 [0x51] = BTN_THUMBL, /* L3 */
126 [0x5b] = BTN_TR, /* R1 */
127 [0x59] = BTN_TR2, /* R2 */
128 [0x52] = BTN_THUMBR, /* R3 */
129 [0x43] = KEY_HOMEPAGE, /* PS button */
132 [0x33] = KEY_REWIND, /* scan back */
134 [0x34] = KEY_FORWARD, /* scan forward */
135 [0x30] = KEY_PREVIOUS,
138 [0x60] = KEY_FRAMEBACK, /* slow/step back */
140 [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
144 static int ps3remote_decode(char *buff, int size, unsigned int *value)
146 static unsigned int lastkey = 0;
147 static unsigned int lastmask = 0;
148 unsigned int i, mask;
153 error("Got a shorter packet! (size %i)\n", size);
157 mask = (buff[2] << 16) + (buff[3] << 8) + buff[4];
160 /* first, check flags */
161 for (i = 0; i < 24; i++) {
162 if ((lastmask & (1 << i)) == (mask & (1 << i)))
164 if (ps3remote_bits[i] == 0)
166 retval = ps3remote_keymap[ps3remote_bits[i]];
179 retval = ps3remote_keymap[key];
183 if (retval == KEY_RESERVED)
185 if (retval == KEY_MAX)
198 error("ps3remote: unrecognized sequence [%#x][%#x][%#x][%#x] [%#x],"
199 "last: [%#x][%#x][%#x][%#x]",
200 buff[2], buff[3], buff[4], buff[5], buff[11],
201 lastmask >> 16, lastmask >> 8 & 0xff,
202 lastmask & 0xff, lastkey);
206 static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond,
209 struct fake_input *fake = data;
210 struct uinput_event event;
211 unsigned int key, value = 0;
216 if (cond & G_IO_NVAL)
219 if (cond & (G_IO_HUP | G_IO_ERR)) {
220 error("Hangup or error on rfcomm server socket");
224 fd = g_io_channel_unix_get_fd(chan);
226 memset(buff, 0, sizeof(buff));
227 size = read(fd, buff, sizeof(buff));
229 error("IO Channel read error");
233 key = ps3remote_decode(buff, size, &value);
234 if (key == KEY_RESERVED) {
235 error("Got invalid key from decode");
237 } else if (key == KEY_MAX)
240 memset(&event, 0, sizeof(event));
241 gettimeofday(&event.time, NULL);
245 if (write(fake->uinput, &event, sizeof(event)) != sizeof(event)) {
246 error("Error writing to uinput device");
250 memset(&event, 0, sizeof(event));
251 gettimeofday(&event.time, NULL);
253 event.code = SYN_REPORT;
254 if (write(fake->uinput, &event, sizeof(event)) != sizeof(event)) {
255 error("Error writing to uinput device");
262 ioctl(fake->uinput, UI_DEV_DESTROY);
265 g_io_channel_unref(fake->io);
270 static int ps3remote_setup_uinput(struct fake_input *fake,
271 struct fake_hid *fake_hid)
273 struct uinput_dev dev;
276 fake->uinput = open("/dev/input/uinput", O_RDWR);
277 if (fake->uinput < 0) {
278 fake->uinput = open("/dev/uinput", O_RDWR);
279 if (fake->uinput < 0) {
280 fake->uinput = open("/dev/misc/uinput", O_RDWR);
281 if (fake->uinput < 0) {
282 error("Error opening uinput device file");
288 memset(&dev, 0, sizeof(dev));
289 snprintf(dev.name, sizeof(dev.name), "%s", "PS3 Remote Controller");
290 dev.id.bustype = BUS_BLUETOOTH;
291 dev.id.vendor = fake_hid->vendor;
292 dev.id.product = fake_hid->product;
294 if (write(fake->uinput, &dev, sizeof(dev)) != sizeof(dev)) {
295 error("Error creating uinput device");
299 /* enabling key events */
300 if (ioctl(fake->uinput, UI_SET_EVBIT, EV_KEY) < 0) {
301 error("Error enabling uinput device key events");
306 for (i = 0; i < 256; i++)
307 if (ps3remote_keymap[i] != KEY_RESERVED)
308 if (ioctl(fake->uinput, UI_SET_KEYBIT,
309 ps3remote_keymap[i]) < 0) {
310 error("Error enabling uinput key %i",
311 ps3remote_keymap[i]);
315 /* creating the device */
316 if (ioctl(fake->uinput, UI_DEV_CREATE) < 0) {
317 error("Error creating uinput device");
328 static gboolean fake_hid_common_connect(struct fake_input *fake, GError **err)
333 static int fake_hid_common_disconnect(struct fake_input *fake)
338 static struct fake_hid fake_hid_table[] = {
339 /* Sony PS3 remote device */
343 .connect = fake_hid_common_connect,
344 .disconnect = fake_hid_common_disconnect,
345 .event = ps3remote_event,
346 .setup_uinput = ps3remote_setup_uinput,
353 static inline int fake_hid_match_device(uint16_t vendor, uint16_t product,
354 struct fake_hid *fhid)
356 return vendor == fhid->vendor && product == fhid->product;
359 struct fake_hid *get_fake_hid(uint16_t vendor, uint16_t product)
363 for (i = 0; fake_hid_table[i].vendor != 0; i++)
364 if (fake_hid_match_device(vendor, product, &fake_hid_table[i]))
365 return &fake_hid_table[i];
370 struct fake_input *fake_hid_connadd(struct fake_input *fake,
372 struct fake_hid *fake_hid)
375 struct fake_input *old = NULL;
377 /* Look for an already setup device */
378 for (l = fake_hid->devices; l != NULL; l = l->next) {
380 if (old->idev == fake->idev) {
383 fake_hid->connect(fake, NULL);
389 /* New device? Add it to the list of known devices,
390 * and create the uinput necessary */
391 if (old == NULL || old->uinput < 0) {
392 if (fake_hid->setup_uinput(fake, fake_hid)) {
393 error("Error setting up uinput");
400 fake_hid->devices = g_list_append(fake_hid->devices, fake);
402 fake->io = g_io_channel_ref(intr_io);
403 g_io_channel_set_close_on_unref(fake->io, TRUE);
404 g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
405 (GIOFunc) fake_hid->event, fake);