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