1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2003-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#define _GNU_SOURCE
29#include <stdio.h>
30#include <errno.h>
31#include <fcntl.h>
32#include <unistd.h>
33#include <stdlib.h>
34#include <signal.h>
35#include <sys/poll.h>
36#include <sys/ioctl.h>
37#include <sys/socket.h>
38
39#include <bluetooth/bluetooth.h>
40#include <bluetooth/rfcomm.h>
41#include <bluetooth/hidp.h>
42
43#include "hidd.h"
44#include "uinput.h"
45
46#include <math.h>
47
48#ifdef NEED_PPOLL
49#include "ppoll.h"
50#endif
51
52static volatile sig_atomic_t __io_canceled = 0;
53
54static void sig_hup(int sig)
55{
56}
57
58static void sig_term(int sig)
59{
60	__io_canceled = 1;
61}
62
63static void send_event(int fd, uint16_t type, uint16_t code, int32_t value)
64{
65	struct uinput_event event;
66	int len;
67
68	if (fd <= fileno(stderr))
69		return;
70
71	memset(&event, 0, sizeof(event));
72	event.type = type;
73	event.code = code;
74	event.value = value;
75
76	len = write(fd, &event, sizeof(event));
77}
78
79static int uinput_create(char *name, int keyboard, int mouse)
80{
81	struct uinput_dev dev;
82	int fd, aux;
83
84	fd = open("/dev/uinput", O_RDWR);
85	if (fd < 0) {
86		fd = open("/dev/input/uinput", O_RDWR);
87		if (fd < 0) {
88			fd = open("/dev/misc/uinput", O_RDWR);
89			if (fd < 0) {
90				fprintf(stderr, "Can't open input device: %s (%d)\n",
91							strerror(errno), errno);
92				return -1;
93			}
94		}
95	}
96
97	memset(&dev, 0, sizeof(dev));
98
99	if (name)
100		strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1);
101
102	dev.id.bustype = BUS_BLUETOOTH;
103	dev.id.vendor  = 0x0000;
104	dev.id.product = 0x0000;
105	dev.id.version = 0x0000;
106
107	if (write(fd, &dev, sizeof(dev)) < 0) {
108		fprintf(stderr, "Can't write device information: %s (%d)\n",
109							strerror(errno), errno);
110		close(fd);
111		return -1;
112	}
113
114	if (mouse) {
115		ioctl(fd, UI_SET_EVBIT, EV_REL);
116
117		for (aux = REL_X; aux <= REL_MISC; aux++)
118			ioctl(fd, UI_SET_RELBIT, aux);
119	}
120
121	if (keyboard) {
122		ioctl(fd, UI_SET_EVBIT, EV_KEY);
123		ioctl(fd, UI_SET_EVBIT, EV_LED);
124		ioctl(fd, UI_SET_EVBIT, EV_REP);
125
126		for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++)
127			ioctl(fd, UI_SET_KEYBIT, aux);
128
129		//for (aux = LED_NUML; aux <= LED_MISC; aux++)
130		//	ioctl(fd, UI_SET_LEDBIT, aux);
131	}
132
133	if (mouse) {
134		ioctl(fd, UI_SET_EVBIT, EV_KEY);
135
136		for (aux = BTN_LEFT; aux <= BTN_BACK; aux++)
137			ioctl(fd, UI_SET_KEYBIT, aux);
138	}
139
140	ioctl(fd, UI_DEV_CREATE);
141
142	return fd;
143}
144
145static int rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
146{
147	struct sockaddr_rc addr;
148	int sk;
149
150	sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
151	if (sk < 0) {
152		fprintf(stderr, "Can't create socket: %s (%d)\n",
153							strerror(errno), errno);
154		return -1;
155	}
156
157	memset(&addr, 0, sizeof(addr));
158	addr.rc_family = AF_BLUETOOTH;
159	bacpy(&addr.rc_bdaddr, src);
160
161	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
162		fprintf(stderr, "Can't bind socket: %s (%d)\n",
163							strerror(errno), errno);
164		close(sk);
165		return -1;
166	}
167
168	memset(&addr, 0, sizeof(addr));
169	addr.rc_family = AF_BLUETOOTH;
170	bacpy(&addr.rc_bdaddr, dst);
171	addr.rc_channel = channel;
172
173	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
174		fprintf(stderr, "Can't connect: %s (%d)\n",
175							strerror(errno), errno);
176		close(sk);
177		return -1;
178	}
179
180	return sk;
181}
182
183static void func(int fd)
184{
185}
186
187static void back(int fd)
188{
189}
190
191static void next(int fd)
192{
193}
194
195static void button(int fd, unsigned int button, int is_press)
196{
197	switch (button) {
198	case 1:
199		send_event(fd, EV_KEY, BTN_LEFT, is_press);
200		break;
201	case 3:
202		send_event(fd, EV_KEY, BTN_RIGHT, is_press);
203		break;
204	}
205
206	send_event(fd, EV_SYN, SYN_REPORT, 0);
207}
208
209static void move(int fd, unsigned int direction)
210{
211	double angle;
212	int32_t x, y;
213
214	angle = (direction * 22.5) * 3.1415926 / 180;
215	x = (int) (sin(angle) * 8);
216	y = (int) (cos(angle) * -8);
217
218	send_event(fd, EV_REL, REL_X, x);
219	send_event(fd, EV_REL, REL_Y, y);
220
221	send_event(fd, EV_SYN, SYN_REPORT, 0);
222}
223
224static inline void epox_decode(int fd, unsigned char event)
225{
226	switch (event) {
227	case 48:
228		func(fd); break;
229	case 55:
230		back(fd); break;
231	case 56:
232		next(fd); break;
233	case 53:
234		button(fd, 1, 1); break;
235	case 121:
236		button(fd, 1, 0); break;
237	case 113:
238		break;
239	case 54:
240		button(fd, 3, 1); break;
241	case 120:
242		button(fd, 3, 0); break;
243	case 112:
244		break;
245	case 51:
246		move(fd, 0); break;
247	case 97:
248		move(fd, 1); break;
249	case 65:
250		move(fd, 2); break;
251	case 98:
252		move(fd, 3); break;
253	case 50:
254		move(fd, 4); break;
255	case 99:
256		move(fd, 5); break;
257	case 67:
258		move(fd, 6); break;
259	case 101:
260		move(fd, 7); break;
261	case 52:
262		move(fd, 8); break;
263	case 100:
264		move(fd, 9); break;
265	case 66:
266		move(fd, 10); break;
267	case 102:
268		move(fd, 11); break;
269	case 49:
270		move(fd, 12); break;
271	case 103:
272		move(fd, 13); break;
273	case 57:
274		move(fd, 14); break;
275	case 104:
276		move(fd, 15); break;
277	case 69:
278		break;
279	default:
280		printf("Unknown event code %d\n", event);
281		break;
282	}
283}
284
285int epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
286{
287	unsigned char buf[16];
288	struct sigaction sa;
289	struct pollfd p;
290	sigset_t sigs;
291	char addr[18];
292	int i, fd, sk, len;
293
294	sk = rfcomm_connect(src, dst, channel);
295	if (sk < 0)
296		return -1;
297
298	fd = uinput_create("Bluetooth Presenter", 0, 1);
299	if (fd < 0) {
300		close(sk);
301		return -1;
302	}
303
304	ba2str(dst, addr);
305
306	printf("Connected to %s on channel %d\n", addr, channel);
307	printf("Press CTRL-C for hangup\n");
308
309	memset(&sa, 0, sizeof(sa));
310	sa.sa_flags   = SA_NOCLDSTOP;
311	sa.sa_handler = SIG_IGN;
312	sigaction(SIGCHLD, &sa, NULL);
313	sigaction(SIGPIPE, &sa, NULL);
314
315	sa.sa_handler = sig_term;
316	sigaction(SIGTERM, &sa, NULL);
317	sigaction(SIGINT,  &sa, NULL);
318
319	sa.sa_handler = sig_hup;
320	sigaction(SIGHUP, &sa, NULL);
321
322	sigfillset(&sigs);
323	sigdelset(&sigs, SIGCHLD);
324	sigdelset(&sigs, SIGPIPE);
325	sigdelset(&sigs, SIGTERM);
326	sigdelset(&sigs, SIGINT);
327	sigdelset(&sigs, SIGHUP);
328
329	p.fd = sk;
330	p.events = POLLIN | POLLERR | POLLHUP;
331
332	while (!__io_canceled) {
333		p.revents = 0;
334		if (ppoll(&p, 1, NULL, &sigs) < 1)
335			continue;
336
337		len = read(sk, buf, sizeof(buf));
338		if (len < 0)
339			break;
340
341		for (i = 0; i < len; i++)
342			epox_decode(fd, buf[i]);
343	}
344
345	printf("Disconnected\n");
346
347	ioctl(fd, UI_DEV_DESTROY);
348
349	close(fd);
350	close(sk);
351
352	return 0;
353}
354
355int headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
356{
357	printf("Not implemented\n");
358	return -1;
359}
360
361/* The strange meta key close to Ctrl has been assigned to Esc,
362   Fn key to CtrlR and the left space to Alt*/
363
364static unsigned char jthree_keycodes[63] = {
365	KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
366	KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T,
367	KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
368	KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B,
369	KEY_LEFTALT, KEY_TAB, KEY_CAPSLOCK, KEY_ESC,
370	KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE,
371	KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE,
372	KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER,
373	KEY_N, KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, KEY_UP,
374	KEY_SPACE, KEY_COMPOSE, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
375	KEY_LEFTCTRL, KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_DELETE, KEY_RIGHTCTRL, KEY_RIGHTALT,
376};
377
378static inline void jthree_decode(int fd, unsigned char event)
379{
380	if (event > 63)
381		send_event(fd, EV_KEY, jthree_keycodes[event & 0x3f], 0);
382	else
383		send_event(fd, EV_KEY, jthree_keycodes[event - 1], 1);
384}
385
386int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
387{
388	unsigned char buf[16];
389	struct sigaction sa;
390	struct pollfd p;
391	sigset_t sigs;
392	char addr[18];
393	int i, fd, sk, len;
394
395	sk = rfcomm_connect(src, dst, channel);
396	if (sk < 0)
397		return -1;
398
399	fd = uinput_create("J-Three Keyboard", 1, 0);
400	if (fd < 0) {
401		close(sk);
402		return -1;
403	}
404
405	ba2str(dst, addr);
406
407	printf("Connected to %s on channel %d\n", addr, channel);
408	printf("Press CTRL-C for hangup\n");
409
410	memset(&sa, 0, sizeof(sa));
411	sa.sa_flags   = SA_NOCLDSTOP;
412	sa.sa_handler = SIG_IGN;
413	sigaction(SIGCHLD, &sa, NULL);
414	sigaction(SIGPIPE, &sa, NULL);
415
416	sa.sa_handler = sig_term;
417	sigaction(SIGTERM, &sa, NULL);
418	sigaction(SIGINT,  &sa, NULL);
419
420	sa.sa_handler = sig_hup;
421	sigaction(SIGHUP, &sa, NULL);
422
423	sigfillset(&sigs);
424	sigdelset(&sigs, SIGCHLD);
425	sigdelset(&sigs, SIGPIPE);
426	sigdelset(&sigs, SIGTERM);
427	sigdelset(&sigs, SIGINT);
428	sigdelset(&sigs, SIGHUP);
429
430	p.fd = sk;
431	p.events = POLLIN | POLLERR | POLLHUP;
432
433	while (!__io_canceled) {
434		p.revents = 0;
435		if (ppoll(&p, 1, NULL, &sigs) < 1)
436			continue;
437
438		len = read(sk, buf, sizeof(buf));
439		if (len < 0)
440			break;
441
442		for (i = 0; i < len; i++)
443			jthree_decode(fd, buf[i]);
444	}
445
446	printf("Disconnected\n");
447
448	ioctl(fd, UI_DEV_DESTROY);
449
450	close(fd);
451	close(sk);
452
453	return 0;
454}
455
456static const int celluon_xlate_num[10] = {
457	KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9
458};
459
460static const int celluon_xlate_char[26] = {
461	KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
462	KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
463	KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
464};
465
466static int celluon_xlate(int c)
467{
468	if (c >= '0' && c <= '9')
469		return celluon_xlate_num[c - '0'];
470
471	if (c >= 'A' && c <= 'Z')
472		return celluon_xlate_char[c - 'A'];
473
474	switch (c) {
475	case 0x08:
476		return KEY_BACKSPACE;
477	case 0x09:
478		return KEY_TAB;
479	case 0x0d:
480		return KEY_ENTER;
481	case 0x11:
482		return KEY_LEFTCTRL;
483	case 0x14:
484		return KEY_CAPSLOCK;
485	case 0x20:
486		return KEY_SPACE;
487	case 0x25:
488		return KEY_LEFT;
489	case 0x26:
490		return KEY_UP;
491	case 0x27:
492		return KEY_RIGHT;
493	case 0x28:
494		return KEY_DOWN;
495	case 0x2e:
496		return KEY_DELETE;
497	case 0x5b:
498		return KEY_MENU;
499	case 0xa1:
500		return KEY_RIGHTSHIFT;
501	case 0xa0:
502		return KEY_LEFTSHIFT;
503	case 0xba:
504		return KEY_SEMICOLON;
505	case 0xbd:
506		return KEY_MINUS;
507	case 0xbc:
508		return KEY_COMMA;
509	case 0xbb:
510		return KEY_EQUAL;
511	case 0xbe:
512		return KEY_DOT;
513	case 0xbf:
514		return KEY_SLASH;
515	case 0xc0:
516		return KEY_GRAVE;
517	case 0xdb:
518		return KEY_LEFTBRACE;
519	case 0xdc:
520		return KEY_BACKSLASH;
521	case 0xdd:
522		return KEY_RIGHTBRACE;
523	case 0xde:
524		return KEY_APOSTROPHE;
525	case 0xff03:
526		return KEY_HOMEPAGE;
527	case 0xff04:
528		return KEY_TIME;
529	case 0xff06:
530		return KEY_OPEN;
531	case 0xff07:
532		return KEY_LIST;
533	case 0xff08:
534		return KEY_MAIL;
535	case 0xff30:
536		return KEY_CALC;
537	case 0xff1a: /* Map FN to ALT */
538		return KEY_LEFTALT;
539	case 0xff2f:
540		return KEY_INFO;
541	default:
542		printf("Unknown key %x\n", c);
543		return c;
544	}
545}
546
547struct celluon_state {
548	int len;	/* Expected length of current packet */
549	int count;	/* Number of bytes received */
550	int action;
551	int key;
552};
553
554static void celluon_decode(int fd, struct celluon_state *s, uint8_t c)
555{
556	if (s->count < 2 && c != 0xa5) {
557		/* Lost Sync */
558		s->count = 0;
559		return;
560	}
561
562	switch (s->count) {
563	case 0:
564		/* New packet - Reset state */
565		s->len = 30;
566		s->key = 0;
567		break;
568	case 1:
569		break;
570	case 6:
571		s->action = c;
572		break;
573	case 28:
574		s->key = c;
575		if (c == 0xff)
576			s->len = 31;
577		break;
578	case 29:
579	case 30:
580		if (s->count == s->len - 1) {
581			/* TODO: Verify checksum */
582			if (s->action < 2) {
583				send_event(fd, EV_KEY, celluon_xlate(s->key),
584								s->action);
585			}
586			s->count = -1;
587		} else {
588			s->key = (s->key << 8) | c;
589		}
590		break;
591	}
592
593	s->count++;
594
595	return;
596}
597
598int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
599{
600	unsigned char buf[16];
601	struct sigaction sa;
602	struct pollfd p;
603	sigset_t sigs;
604	char addr[18];
605	int i, fd, sk, len;
606	struct celluon_state s;
607
608	sk = rfcomm_connect(src, dst, channel);
609	if (sk < 0)
610		return -1;
611
612	fd = uinput_create("Celluon Keyboard", 1, 0);
613	if (fd < 0) {
614		close(sk);
615		return -1;
616	}
617
618	ba2str(dst, addr);
619
620	printf("Connected to %s on channel %d\n", addr, channel);
621	printf("Press CTRL-C for hangup\n");
622
623	memset(&sa, 0, sizeof(sa));
624	sa.sa_flags   = SA_NOCLDSTOP;
625	sa.sa_handler = SIG_IGN;
626	sigaction(SIGCHLD, &sa, NULL);
627	sigaction(SIGPIPE, &sa, NULL);
628
629	sa.sa_handler = sig_term;
630	sigaction(SIGTERM, &sa, NULL);
631	sigaction(SIGINT,  &sa, NULL);
632
633	sa.sa_handler = sig_hup;
634	sigaction(SIGHUP, &sa, NULL);
635
636	sigfillset(&sigs);
637	sigdelset(&sigs, SIGCHLD);
638	sigdelset(&sigs, SIGPIPE);
639	sigdelset(&sigs, SIGTERM);
640	sigdelset(&sigs, SIGINT);
641	sigdelset(&sigs, SIGHUP);
642
643	p.fd = sk;
644	p.events = POLLIN | POLLERR | POLLHUP;
645
646	memset(&s, 0, sizeof(s));
647
648	while (!__io_canceled) {
649		p.revents = 0;
650		if (ppoll(&p, 1, NULL, &sigs) < 1)
651			continue;
652
653		len = read(sk, buf, sizeof(buf));
654		if (len < 0)
655			break;
656
657		for (i = 0; i < len; i++)
658			celluon_decode(fd, &s, buf[i]);
659	}
660
661	printf("Disconnected\n");
662
663	ioctl(fd, UI_DEV_DESTROY);
664
665	close(fd);
666	close(sk);
667
668	return 0;
669}
670