1 /*
2 *
3 * BlueZ - Bluetooth protocol stack for Linux
4 *
5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
6 *
7 *
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.
12 *
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.
17 *
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
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <sys/types.h>
34
35 #include <bluetooth/bluetooth.h>
36 #include <bluetooth/hidp.h>
37 #include <bluetooth/sdp.h>
38
39 #include <glib.h>
40 #include <dbus/dbus.h>
41
42 #include "../src/adapter.h"
43 #include "../src/device.h"
44
45 #include "log.h"
46 #include "device.h"
47 #include "fakehid.h"
48 #include "uinput.h"
49
50 #define PS3_FLAGS_MASK 0xFFFFFF00
51
52 enum ps3remote_special_keys {
53 PS3R_BIT_PS = 0,
54 PS3R_BIT_ENTER = 3,
55 PS3R_BIT_L2 = 8,
56 PS3R_BIT_R2 = 9,
57 PS3R_BIT_L1 = 10,
58 PS3R_BIT_R1 = 11,
59 PS3R_BIT_TRIANGLE = 12,
60 PS3R_BIT_CIRCLE = 13,
61 PS3R_BIT_CROSS = 14,
62 PS3R_BIT_SQUARE = 15,
63 PS3R_BIT_SELECT = 16,
64 PS3R_BIT_L3 = 17,
65 PS3R_BIT_R3 = 18,
66 PS3R_BIT_START = 19,
67 PS3R_BIT_UP = 20,
68 PS3R_BIT_RIGHT = 21,
69 PS3R_BIT_DOWN = 22,
70 PS3R_BIT_LEFT = 23,
71 };
72
73 static unsigned int ps3remote_bits[] = {
74 [PS3R_BIT_ENTER] = 0x0b,
75 [PS3R_BIT_PS] = 0x43,
76 [PS3R_BIT_SQUARE] = 0x5f,
77 [PS3R_BIT_CROSS] = 0x5e,
78 [PS3R_BIT_CIRCLE] = 0x5d,
79 [PS3R_BIT_TRIANGLE] = 0x5c,
80 [PS3R_BIT_R1] = 0x5b,
81 [PS3R_BIT_L1] = 0x5a,
82 [PS3R_BIT_R2] = 0x59,
83 [PS3R_BIT_L2] = 0x58,
84 [PS3R_BIT_LEFT] = 0x57,
85 [PS3R_BIT_DOWN] = 0x56,
86 [PS3R_BIT_RIGHT] = 0x55,
87 [PS3R_BIT_UP] = 0x54,
88 [PS3R_BIT_START] = 0x53,
89 [PS3R_BIT_R3] = 0x52,
90 [PS3R_BIT_L3] = 0x51,
91 [PS3R_BIT_SELECT] = 0x50,
92 };
93
94 static unsigned int ps3remote_keymap[] = {
95 [0x16] = KEY_EJECTCD,
96 [0x64] = KEY_AUDIO,
97 [0x65] = KEY_ANGLE,
98 [0x63] = KEY_SUBTITLE,
99 [0x0f] = KEY_CLEAR,
100 [0x28] = KEY_TIME,
101 [0x00] = KEY_1,
102 [0x01] = KEY_2,
103 [0x02] = KEY_3,
104 [0x03] = KEY_4,
105 [0x04] = KEY_5,
106 [0x05] = KEY_6,
107 [0x06] = KEY_7,
108 [0x07] = KEY_8,
109 [0x08] = KEY_9,
110 [0x09] = KEY_0,
111 [0x81] = KEY_RED,
112 [0x82] = KEY_GREEN,
113 [0x80] = KEY_BLUE,
114 [0x83] = KEY_YELLOW,
115 [0x70] = KEY_INFO, /* display */
116 [0x1a] = KEY_MENU, /* top menu */
117 [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
118 [0x0e] = KEY_ESC, /* return */
119 [0x5c] = KEY_OPTION, /* options/triangle */
120 [0x5d] = KEY_BACK, /* back/circle */
121 [0x5f] = KEY_SCREEN, /* view/square */
122 [0x5e] = BTN_0, /* cross */
123 [0x54] = KEY_UP,
124 [0x56] = KEY_DOWN,
125 [0x57] = KEY_LEFT,
126 [0x55] = KEY_RIGHT,
127 [0x0b] = KEY_ENTER,
128 [0x5a] = BTN_TL, /* L1 */
129 [0x58] = BTN_TL2, /* L2 */
130 [0x51] = BTN_THUMBL, /* L3 */
131 [0x5b] = BTN_TR, /* R1 */
132 [0x59] = BTN_TR2, /* R2 */
133 [0x52] = BTN_THUMBR, /* R3 */
134 [0x43] = KEY_HOMEPAGE, /* PS button */
135 [0x50] = KEY_SELECT,
136 [0x53] = BTN_START,
137 [0x33] = KEY_REWIND, /* scan back */
138 [0x32] = KEY_PLAY,
139 [0x34] = KEY_FORWARD, /* scan forward */
140 [0x30] = KEY_PREVIOUS,
141 [0x38] = KEY_STOP,
142 [0x31] = KEY_NEXT,
143 [0x60] = KEY_FRAMEBACK, /* slow/step back */
144 [0x39] = KEY_PAUSE,
145 [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
146 [0xff] = KEY_MAX,
147 };
148
ps3remote_decode(char * buff,int size,unsigned int * value)149 static int ps3remote_decode(char *buff, int size, unsigned int *value)
150 {
151 static unsigned int lastkey = 0;
152 static unsigned int lastmask = 0;
153 unsigned int i, mask;
154 int retval;
155 guint8 key;
156
157 if (size < 12) {
158 error("Got a shorter packet! (size %i)\n", size);
159 return KEY_RESERVED;
160 }
161
162 mask = (buff[2] << 16) + (buff[3] << 8) + buff[4];
163 key = buff[5];
164
165 /* first, check flags */
166 for (i = 0; i < 24; i++) {
167 if ((lastmask & (1 << i)) == (mask & (1 << i)))
168 continue;
169 if (ps3remote_bits[i] == 0)
170 goto error;
171 retval = ps3remote_keymap[ps3remote_bits[i]];
172 if (mask & (1 << i))
173 /* key pressed */
174 *value = 1;
175 else
176 /* key released */
177 *value = 0;
178
179 goto out;
180 }
181
182 *value = buff[11];
183 if (buff[11] == 1) {
184 retval = ps3remote_keymap[key];
185 } else
186 retval = lastkey;
187
188 if (retval == KEY_RESERVED)
189 goto error;
190 if (retval == KEY_MAX)
191 return retval;
192
193 lastkey = retval;
194
195 out:
196 fflush(stdout);
197
198 lastmask = mask;
199
200 return retval;
201
202 error:
203 error("ps3remote: unrecognized sequence [%#x][%#x][%#x][%#x] [%#x],"
204 "last: [%#x][%#x][%#x][%#x]",
205 buff[2], buff[3], buff[4], buff[5], buff[11],
206 lastmask >> 16, lastmask >> 8 & 0xff,
207 lastmask & 0xff, lastkey);
208 return -1;
209 }
210
ps3remote_event(GIOChannel * chan,GIOCondition cond,gpointer data)211 static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond,
212 gpointer data)
213 {
214 struct fake_input *fake = data;
215 struct uinput_event event;
216 unsigned int key, value = 0;
217 ssize_t size;
218 char buff[50];
219 int fd;
220
221 if (cond & G_IO_NVAL)
222 return FALSE;
223
224 if (cond & (G_IO_HUP | G_IO_ERR)) {
225 error("Hangup or error on rfcomm server socket");
226 goto failed;
227 }
228
229 fd = g_io_channel_unix_get_fd(chan);
230
231 memset(buff, 0, sizeof(buff));
232 size = read(fd, buff, sizeof(buff));
233 if (size < 0) {
234 error("IO Channel read error");
235 goto failed;
236 }
237
238 key = ps3remote_decode(buff, size, &value);
239 if (key == KEY_RESERVED) {
240 error("Got invalid key from decode");
241 goto failed;
242 } else if (key == KEY_MAX)
243 return TRUE;
244
245 memset(&event, 0, sizeof(event));
246 gettimeofday(&event.time, NULL);
247 event.type = EV_KEY;
248 event.code = key;
249 event.value = value;
250 if (write(fake->uinput, &event, sizeof(event)) != sizeof(event)) {
251 error("Error writing to uinput device");
252 goto failed;
253 }
254
255 memset(&event, 0, sizeof(event));
256 gettimeofday(&event.time, NULL);
257 event.type = EV_SYN;
258 event.code = SYN_REPORT;
259 if (write(fake->uinput, &event, sizeof(event)) != sizeof(event)) {
260 error("Error writing to uinput device");
261 goto failed;
262 }
263
264 return TRUE;
265
266 failed:
267 ioctl(fake->uinput, UI_DEV_DESTROY);
268 close(fake->uinput);
269 fake->uinput = -1;
270 g_io_channel_unref(fake->io);
271
272 return FALSE;
273 }
274
ps3remote_setup_uinput(struct fake_input * fake,struct fake_hid * fake_hid)275 static int ps3remote_setup_uinput(struct fake_input *fake,
276 struct fake_hid *fake_hid)
277 {
278 struct uinput_dev dev;
279 int i;
280
281 fake->uinput = open("/dev/input/uinput", O_RDWR);
282 if (fake->uinput < 0) {
283 fake->uinput = open("/dev/uinput", O_RDWR);
284 if (fake->uinput < 0) {
285 fake->uinput = open("/dev/misc/uinput", O_RDWR);
286 if (fake->uinput < 0) {
287 error("Error opening uinput device file");
288 return 1;
289 }
290 }
291 }
292
293 memset(&dev, 0, sizeof(dev));
294 snprintf(dev.name, sizeof(dev.name), "%s", "PS3 Remote Controller");
295 dev.id.bustype = BUS_BLUETOOTH;
296 dev.id.vendor = fake_hid->vendor;
297 dev.id.product = fake_hid->product;
298
299 if (write(fake->uinput, &dev, sizeof(dev)) != sizeof(dev)) {
300 error("Error creating uinput device");
301 goto err;
302 }
303
304 /* enabling key events */
305 if (ioctl(fake->uinput, UI_SET_EVBIT, EV_KEY) < 0) {
306 error("Error enabling uinput device key events");
307 goto err;
308 }
309
310 /* enabling keys */
311 for (i = 0; i < 256; i++)
312 if (ps3remote_keymap[i] != KEY_RESERVED)
313 if (ioctl(fake->uinput, UI_SET_KEYBIT,
314 ps3remote_keymap[i]) < 0) {
315 error("Error enabling uinput key %i",
316 ps3remote_keymap[i]);
317 goto err;
318 }
319
320 /* creating the device */
321 if (ioctl(fake->uinput, UI_DEV_CREATE) < 0) {
322 error("Error creating uinput device");
323 goto err;
324 }
325
326 return 0;
327
328 err:
329 close(fake->uinput);
330 return 1;
331 }
332
fake_hid_common_connect(struct fake_input * fake,GError ** err)333 static gboolean fake_hid_common_connect(struct fake_input *fake, GError **err)
334 {
335 return TRUE;
336 }
337
fake_hid_common_disconnect(struct fake_input * fake)338 static int fake_hid_common_disconnect(struct fake_input *fake)
339 {
340 return 0;
341 }
342
343 static struct fake_hid fake_hid_table[] = {
344 /* Sony PS3 remote device */
345 {
346 .vendor = 0x054c,
347 .product = 0x0306,
348 .connect = fake_hid_common_connect,
349 .disconnect = fake_hid_common_disconnect,
350 .event = ps3remote_event,
351 .setup_uinput = ps3remote_setup_uinput,
352 .devices = NULL,
353 },
354
355 { },
356 };
357
fake_hid_match_device(uint16_t vendor,uint16_t product,struct fake_hid * fhid)358 static inline int fake_hid_match_device(uint16_t vendor, uint16_t product,
359 struct fake_hid *fhid)
360 {
361 return vendor == fhid->vendor && product == fhid->product;
362 }
363
get_fake_hid(uint16_t vendor,uint16_t product)364 struct fake_hid *get_fake_hid(uint16_t vendor, uint16_t product)
365 {
366 int i;
367
368 for (i = 0; fake_hid_table[i].vendor != 0; i++)
369 if (fake_hid_match_device(vendor, product, &fake_hid_table[i]))
370 return &fake_hid_table[i];
371
372 return NULL;
373 }
374
fake_hid_connadd(struct fake_input * fake,GIOChannel * intr_io,struct fake_hid * fake_hid)375 struct fake_input *fake_hid_connadd(struct fake_input *fake,
376 GIOChannel *intr_io,
377 struct fake_hid *fake_hid)
378 {
379 GList *l;
380 struct fake_input *old = NULL;
381
382 /* Look for an already setup device */
383 for (l = fake_hid->devices; l != NULL; l = l->next) {
384 old = l->data;
385 if (old->idev == fake->idev) {
386 g_free(fake);
387 fake = old;
388 fake_hid->connect(fake, NULL);
389 break;
390 }
391 old = NULL;
392 }
393
394 /* New device? Add it to the list of known devices,
395 * and create the uinput necessary */
396 if (old == NULL) {
397 if (fake_hid->setup_uinput(fake, fake_hid)) {
398 error("Error setting up uinput");
399 g_free(fake);
400 return NULL;
401 }
402 fake_hid->devices = g_list_append(fake_hid->devices, fake);
403 }
404
405 fake->io = g_io_channel_ref(intr_io);
406 g_io_channel_set_close_on_unref(fake->io, TRUE);
407 g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
408 (GIOFunc) fake_hid->event, fake);
409
410 return fake;
411 }
412