Home | History | Annotate | Download | only in compat
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2003-2010  Marcel Holtmann <marcel (at) 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 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 
     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 - 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 
    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 }
    670