Fix build break for rpm
[framework/connectivity/bluez.git] / compat / fakehid.c
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
52 static volatile sig_atomic_t __io_canceled = 0;
53
54 static void sig_hup(int sig)
55 {
56 }
57
58 static void sig_term(int sig)
59 {
60         __io_canceled = 1;
61 }
62
63 static int send_event(int fd, uint16_t type, uint16_t code, int32_t value)
64 {
65         struct uinput_event event;
66
67         if (fd <= fileno(stderr))
68                 return -EINVAL;
69
70         memset(&event, 0, sizeof(event));
71         event.type = type;
72         event.code = code;
73         event.value = value;
74
75         return write(fd, &event, sizeof(event));
76 }
77
78 static int uinput_create(char *name, int keyboard, int mouse)
79 {
80         struct uinput_dev dev;
81         int fd, aux;
82
83         fd = open("/dev/uinput", O_RDWR);
84         if (fd < 0) {
85                 fd = open("/dev/input/uinput", O_RDWR);
86                 if (fd < 0) {
87                         fd = open("/dev/misc/uinput", O_RDWR);
88                         if (fd < 0) {
89                                 fprintf(stderr, "Can't open input device: %s (%d)\n",
90                                                         strerror(errno), errno);
91                                 return -1;
92                         }
93                 }
94         }
95
96         memset(&dev, 0, sizeof(dev));
97
98         if (name)
99                 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1);
100
101         dev.id.bustype = BUS_BLUETOOTH;
102         dev.id.vendor  = 0x0000;
103         dev.id.product = 0x0000;
104         dev.id.version = 0x0000;
105
106         if (write(fd, &dev, sizeof(dev)) < 0) {
107                 fprintf(stderr, "Can't write device information: %s (%d)\n",
108                                                         strerror(errno), errno);
109                 close(fd);
110                 return -1;
111         }
112
113         if (mouse) {
114                 ioctl(fd, UI_SET_EVBIT, EV_REL);
115
116                 for (aux = REL_X; aux <= REL_MISC; aux++)
117                         ioctl(fd, UI_SET_RELBIT, aux);
118         }
119
120         if (keyboard) {
121                 ioctl(fd, UI_SET_EVBIT, EV_KEY);
122                 ioctl(fd, UI_SET_EVBIT, EV_LED);
123                 ioctl(fd, UI_SET_EVBIT, EV_REP);
124
125                 for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++)
126                         ioctl(fd, UI_SET_KEYBIT, aux);
127                 /*
128                  *for (aux = LED_NUML; aux <= LED_MISC; aux++)
129                  *      ioctl(fd, UI_SET_LEDBIT, aux);
130                  */
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
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
183 static void func(int fd)
184 {
185 }
186
187 static void back(int fd)
188 {
189 }
190
191 static void next(int fd)
192 {
193 }
194
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
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
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
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
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
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
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
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
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
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 }