• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2003-2008  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 
52 static volatile sig_atomic_t __io_canceled = 0;
53 
sig_hup(int sig)54 static void sig_hup(int sig)
55 {
56 }
57 
sig_term(int sig)58 static void sig_term(int sig)
59 {
60 	__io_canceled = 1;
61 }
62 
send_event(int fd,uint16_t type,uint16_t code,int32_t value)63 static 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 
uinput_create(char * name,int keyboard,int mouse)79 static 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);
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 
rfcomm_connect(const bdaddr_t * src,const bdaddr_t * dst,uint8_t channel)145 static 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 
func(int fd)183 static void func(int fd)
184 {
185 }
186 
back(int fd)187 static void back(int fd)
188 {
189 }
190 
next(int fd)191 static void next(int fd)
192 {
193 }
194 
button(int fd,unsigned int button,int is_press)195 static 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 
move(int fd,unsigned int direction)209 static 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 
epox_decode(int fd,unsigned char event)224 static 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 
epox_presenter(const bdaddr_t * src,const bdaddr_t * dst,uint8_t channel)285 int 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 
headset_presenter(const bdaddr_t * src,const bdaddr_t * dst,uint8_t channel)355 int 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 
364 static 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 
jthree_decode(int fd,unsigned char event)378 static 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 
jthree_keyboard(const bdaddr_t * src,const bdaddr_t * dst,uint8_t channel)386 int 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 
456 static 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 
460 static 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 
celluon_xlate(int c)466 static 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 
547 struct 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 
celluon_decode(int fd,struct celluon_state * s,uint8_t c)554 static 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 
celluon_keyboard(const bdaddr_t * src,const bdaddr_t * dst,uint8_t channel)598 int 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