diff options
Diffstat (limited to 'hidd/fakehid.c')
-rw-r--r-- | hidd/fakehid.c | 669 |
1 files changed, 0 insertions, 669 deletions
diff --git a/hidd/fakehid.c b/hidd/fakehid.c deleted file mode 100644 index feefe2a6..00000000 --- a/hidd/fakehid.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2003-2008 Marcel Holtmann <marcel@holtmann.org> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/poll.h> -#include <sys/ioctl.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/rfcomm.h> -#include <bluetooth/hidp.h> - -#include "hidd.h" -#include "uinput.h" - -#include <math.h> - -#ifdef NEED_PPOLL -#include "ppoll.h" -#endif - -static volatile sig_atomic_t __io_canceled = 0; - -static void sig_hup(int sig) -{ -} - -static void sig_term(int sig) -{ - __io_canceled = 1; -} - -static void send_event(int fd, uint16_t type, uint16_t code, int32_t value) -{ - struct uinput_event event; - int len; - - if (fd <= fileno(stderr)) - return; - - memset(&event, 0, sizeof(event)); - event.type = type; - event.code = code; - event.value = value; - - len = write(fd, &event, sizeof(event)); -} - -static int uinput_create(char *name, int keyboard, int mouse) -{ - struct uinput_dev dev; - int fd, aux; - - fd = open("/dev/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/input/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/misc/uinput", O_RDWR); - if (fd < 0) { - fprintf(stderr, "Can't open input device: %s (%d)\n", - strerror(errno), errno); - return -1; - } - } - } - - memset(&dev, 0, sizeof(dev)); - - if (name) - strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE); - - dev.id.bustype = BUS_BLUETOOTH; - dev.id.vendor = 0x0000; - dev.id.product = 0x0000; - dev.id.version = 0x0000; - - if (write(fd, &dev, sizeof(dev)) < 0) { - fprintf(stderr, "Can't write device information: %s (%d)\n", - strerror(errno), errno); - close(fd); - return -1; - } - - if (mouse) { - ioctl(fd, UI_SET_EVBIT, EV_REL); - - for (aux = REL_X; aux <= REL_MISC; aux++) - ioctl(fd, UI_SET_RELBIT, aux); - } - - if (keyboard) { - ioctl(fd, UI_SET_EVBIT, EV_KEY); - ioctl(fd, UI_SET_EVBIT, EV_LED); - ioctl(fd, UI_SET_EVBIT, EV_REP); - - for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++) - ioctl(fd, UI_SET_KEYBIT, aux); - - //for (aux = LED_NUML; aux <= LED_MISC; aux++) - // ioctl(fd, UI_SET_LEDBIT, aux); - } - - if (mouse) { - ioctl(fd, UI_SET_EVBIT, EV_KEY); - - for (aux = BTN_LEFT; aux <= BTN_BACK; aux++) - ioctl(fd, UI_SET_KEYBIT, aux); - } - - ioctl(fd, UI_DEV_CREATE); - - return fd; -} - -static int rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - struct sockaddr_rc addr; - int sk; - - sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); - if (sk < 0) { - fprintf(stderr, "Can't create socket: %s (%d)\n", - strerror(errno), errno); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.rc_family = AF_BLUETOOTH; - bacpy(&addr.rc_bdaddr, src); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - fprintf(stderr, "Can't bind socket: %s (%d)\n", - strerror(errno), errno); - close(sk); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.rc_family = AF_BLUETOOTH; - bacpy(&addr.rc_bdaddr, dst); - addr.rc_channel = channel; - - if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - fprintf(stderr, "Can't connect: %s (%d)\n", - strerror(errno), errno); - close(sk); - return -1; - } - - return sk; -} - -static void func(int fd) -{ -} - -static void back(int fd) -{ -} - -static void next(int fd) -{ -} - -static void button(int fd, unsigned int button, int is_press) -{ - switch (button) { - case 1: - send_event(fd, EV_KEY, BTN_LEFT, is_press); - break; - case 3: - send_event(fd, EV_KEY, BTN_RIGHT, is_press); - break; - } - - send_event(fd, EV_SYN, SYN_REPORT, 0); -} - -static void move(int fd, unsigned int direction) -{ - double angle; - int32_t x, y; - - angle = (direction * 22.5) * 3.1415926 / 180; - x = (int) (sin(angle) * 8); - y = (int) (cos(angle) * -8); - - send_event(fd, EV_REL, REL_X, x); - send_event(fd, EV_REL, REL_Y, y); - - send_event(fd, EV_SYN, SYN_REPORT, 0); -} - -static inline void epox_decode(int fd, unsigned char event) -{ - switch (event) { - case 48: - func(fd); break; - case 55: - back(fd); break; - case 56: - next(fd); break; - case 53: - button(fd, 1, 1); break; - case 121: - button(fd, 1, 0); break; - case 113: - break; - case 54: - button(fd, 3, 1); break; - case 120: - button(fd, 3, 0); break; - case 112: - break; - case 51: - move(fd, 0); break; - case 97: - move(fd, 1); break; - case 65: - move(fd, 2); break; - case 98: - move(fd, 3); break; - case 50: - move(fd, 4); break; - case 99: - move(fd, 5); break; - case 67: - move(fd, 6); break; - case 101: - move(fd, 7); break; - case 52: - move(fd, 8); break; - case 100: - move(fd, 9); break; - case 66: - move(fd, 10); break; - case 102: - move(fd, 11); break; - case 49: - move(fd, 12); break; - case 103: - move(fd, 13); break; - case 57: - move(fd, 14); break; - case 104: - move(fd, 15); break; - case 69: - break; - default: - printf("Unknown event code %d\n", event); - break; - } -} - -int epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - unsigned char buf[16]; - struct sigaction sa; - struct pollfd p; - sigset_t sigs; - char addr[18]; - int i, fd, sk, len; - - sk = rfcomm_connect(src, dst, channel); - if (sk < 0) - return -1; - - fd = uinput_create("Bluetooth Presenter", 0, 1); - if (fd < 0) { - close(sk); - return -1; - } - - ba2str(dst, addr); - - printf("Connected to %s on channel %d\n", addr, channel); - printf("Press CTRL-C for hangup\n"); - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - - sa.sa_handler = sig_hup; - sigaction(SIGHUP, &sa, NULL); - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p.fd = sk; - p.events = POLLIN | POLLERR | POLLHUP; - - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) < 1) - continue; - - len = read(sk, buf, sizeof(buf)); - if (len < 0) - break; - - for (i = 0; i < len; i++) - epox_decode(fd, buf[i]); - } - - printf("Disconnected\n"); - - ioctl(fd, UI_DEV_DESTROY); - - close(fd); - close(sk); - - return 0; -} - -int headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - printf("Not implemented\n"); - return -1; -} - -/* The strange meta key close to Ctrl has been assigned to Esc, - Fn key to CtrlR and the left space to Alt*/ - -static unsigned char jthree_keycodes[63] = { - KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, - KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, - KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, - KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, - KEY_LEFTALT, KEY_TAB, KEY_CAPSLOCK, KEY_ESC, - KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, - KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, - KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, - KEY_N, KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, KEY_UP, - KEY_SPACE, KEY_COMPOSE, KEY_LEFT, KEY_DOWN, KEY_RIGHT, - KEY_LEFTCTRL, KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_DELETE, KEY_RIGHTCTRL, KEY_RIGHTALT, -}; - -static inline void jthree_decode(int fd, unsigned char event) -{ - if (event > 63) - send_event(fd, EV_KEY, jthree_keycodes[event & 0x3f], 0); - else - send_event(fd, EV_KEY, jthree_keycodes[event - 1], 1); -} - -int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - unsigned char buf[16]; - struct sigaction sa; - struct pollfd p; - sigset_t sigs; - char addr[18]; - int i, fd, sk, len; - - sk = rfcomm_connect(src, dst, channel); - if (sk < 0) - return -1; - - fd = uinput_create("J-Three Keyboard", 1, 0); - if (fd < 0) { - close(sk); - return -1; - } - - ba2str(dst, addr); - - printf("Connected to %s on channel %d\n", addr, channel); - printf("Press CTRL-C for hangup\n"); - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - - sa.sa_handler = sig_hup; - sigaction(SIGHUP, &sa, NULL); - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p.fd = sk; - p.events = POLLIN | POLLERR | POLLHUP; - - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) < 1) - continue; - - len = read(sk, buf, sizeof(buf)); - if (len < 0) - break; - - for (i = 0; i < len; i++) - jthree_decode(fd, buf[i]); - } - - printf("Disconnected\n"); - - ioctl(fd, UI_DEV_DESTROY); - - close(fd); - close(sk); - - return 0; -} - -static const int celluon_xlate_num[10] = { - KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 -}; - -static const int celluon_xlate_char[26] = { - KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, - KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, - KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z -}; - -static int celluon_xlate(int c) -{ - if (c >= '0' && c <= '9') - return celluon_xlate_num[c - '0']; - - if (c >= 'A' && c <= 'Z') - return celluon_xlate_char[c - 'A']; - - switch (c) { - case 0x08: - return KEY_BACKSPACE; - case 0x09: - return KEY_TAB; - case 0x0d: - return KEY_ENTER; - case 0x11: - return KEY_LEFTCTRL; - case 0x14: - return KEY_CAPSLOCK; - case 0x20: - return KEY_SPACE; - case 0x25: - return KEY_LEFT; - case 0x26: - return KEY_UP; - case 0x27: - return KEY_RIGHT; - case 0x28: - return KEY_DOWN; - case 0x2e: - return KEY_DELETE; - case 0x5b: - return KEY_MENU; - case 0xa1: - return KEY_RIGHTSHIFT; - case 0xa0: - return KEY_LEFTSHIFT; - case 0xba: - return KEY_SEMICOLON; - case 0xbd: - return KEY_MINUS; - case 0xbc: - return KEY_COMMA; - case 0xbb: - return KEY_EQUAL; - case 0xbe: - return KEY_DOT; - case 0xbf: - return KEY_SLASH; - case 0xc0: - return KEY_GRAVE; - case 0xdb: - return KEY_LEFTBRACE; - case 0xdc: - return KEY_BACKSLASH; - case 0xdd: - return KEY_RIGHTBRACE; - case 0xde: - return KEY_APOSTROPHE; - case 0xff03: - return KEY_HOMEPAGE; - case 0xff04: - return KEY_TIME; - case 0xff06: - return KEY_OPEN; - case 0xff07: - return KEY_LIST; - case 0xff08: - return KEY_MAIL; - case 0xff30: - return KEY_CALC; - case 0xff1a: /* Map FN to ALT */ - return KEY_LEFTALT; - case 0xff2f: - return KEY_INFO; - default: - printf("Unknown key %x\n", c); - return c; - } -} - -struct celluon_state { - int len; /* Expected length of current packet */ - int count; /* Number of bytes received */ - int action; - int key; -}; - -static void celluon_decode(int fd, struct celluon_state *s, uint8_t c) -{ - if (s->count < 2 && c != 0xa5) { - /* Lost Sync */ - s->count = 0; - return; - } - - switch (s->count) { - case 0: - /* New packet - Reset state */ - s->len = 30; - s->key = 0; - break; - case 1: - break; - case 6: - s->action = c; - break; - case 28: - s->key = c; - if (c == 0xff) - s->len = 31; - break; - case 29: - case 30: - if (s->count == s->len - 1) { - /* TODO: Verify checksum */ - if (s->action < 2) { - send_event(fd, EV_KEY, celluon_xlate(s->key), - s->action); - } - s->count = -1; - } else { - s->key = (s->key << 8) | c; - } - break; - } - - s->count++; - - return; -} - -int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - unsigned char buf[16]; - struct sigaction sa; - struct pollfd p; - sigset_t sigs; - char addr[18]; - int i, fd, sk, len; - struct celluon_state s; - - sk = rfcomm_connect(src, dst, channel); - if (sk < 0) - return -1; - - fd = uinput_create("Celluon Keyboard", 1, 0); - if (fd < 0) { - close(sk); - return -1; - } - - ba2str(dst, addr); - - printf("Connected to %s on channel %d\n", addr, channel); - printf("Press CTRL-C for hangup\n"); - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - - sa.sa_handler = sig_hup; - sigaction(SIGHUP, &sa, NULL); - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p.fd = sk; - p.events = POLLIN | POLLERR | POLLHUP; - - memset(&s, 0, sizeof(s)); - - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) < 1) - continue; - - len = read(sk, buf, sizeof(buf)); - if (len < 0) - break; - - for (i = 0; i < len; i++) - celluon_decode(fd, &s, buf[i]); - } - - printf("Disconnected\n"); - - ioctl(fd, UI_DEV_DESTROY); - - close(fd); - close(sk); - - return 0; -} |