diff options
Diffstat (limited to 'hidd')
-rw-r--r-- | hidd/fakehid.c | 150 | ||||
-rw-r--r-- | hidd/fakehid.txt | 15 | ||||
-rw-r--r-- | hidd/uinput.h | 65 |
3 files changed, 229 insertions, 1 deletions
diff --git a/hidd/fakehid.c b/hidd/fakehid.c index 1a0cc33f..226dcef2 100644 --- a/hidd/fakehid.c +++ b/hidd/fakehid.c @@ -453,6 +453,148 @@ int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) 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]; @@ -460,7 +602,8 @@ int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) struct pollfd p; sigset_t sigs; char addr[18]; - int fd, sk, len; + int i, fd, sk, len; + struct celluon_state s; sk = rfcomm_connect(src, dst, channel); if (sk < 0) @@ -500,6 +643,8 @@ int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) 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) @@ -508,6 +653,9 @@ int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) 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"); diff --git a/hidd/fakehid.txt b/hidd/fakehid.txt index 05f5be34..000d0ee2 100644 --- a/hidd/fakehid.txt +++ b/hidd/fakehid.txt @@ -117,3 +117,18 @@ Sequence UINT8 0x01 Attribute 0x0100 String Serial Port + +Packet format is as follows (all fields little-endian): + 0 uint16 magic # 0x5a5a + 2 uint32 unknown # ??? + 6 uint8 action # 0 = keyup, 1 = keydown, 2 = repeat + # 3, 4, 5, 6 = ??? (Mouse mode) + 7 uint8 unknown[9] # ??? + 16 uint8 action2 # ??? same as action + 17 uint16 x # Horizontal coordinate + 19 uint16 y # Vertical coordinate + 21 uint16 time # Some sort of timestamp + 23 uint8 unknown[5] # ??? + 28 uint8 key[] # single byte keycode or 0xff byte + # follwed by special keycode byte. + Each packet followed by a checksum byte. diff --git a/hidd/uinput.h b/hidd/uinput.h index d879c395..277f843b 100644 --- a/hidd/uinput.h +++ b/hidd/uinput.h @@ -341,6 +341,71 @@ extern "C" { #define BTN_GEAR_DOWN 0x150 #define BTN_GEAR_UP 0x151 +#define KEY_OK 0x160 +#define KEY_SELECT 0x161 +#define KEY_GOTO 0x162 +#define KEY_CLEAR 0x163 +#define KEY_POWER2 0x164 +#define KEY_OPTION 0x165 +#define KEY_INFO 0x166 +#define KEY_TIME 0x167 +#define KEY_VENDOR 0x168 +#define KEY_ARCHIVE 0x169 +#define KEY_PROGRAM 0x16a +#define KEY_CHANNEL 0x16b +#define KEY_FAVORITES 0x16c +#define KEY_EPG 0x16d +#define KEY_PVR 0x16e +#define KEY_MHP 0x16f +#define KEY_LANGUAGE 0x170 +#define KEY_TITLE 0x171 +#define KEY_SUBTITLE 0x172 +#define KEY_ANGLE 0x173 +#define KEY_ZOOM 0x174 +#define KEY_MODE 0x175 +#define KEY_KEYBOARD 0x176 +#define KEY_SCREEN 0x177 +#define KEY_PC 0x178 +#define KEY_TV 0x179 +#define KEY_TV2 0x17a +#define KEY_VCR 0x17b +#define KEY_VCR2 0x17c +#define KEY_SAT 0x17d +#define KEY_SAT2 0x17e +#define KEY_CD 0x17f +#define KEY_TAPE 0x180 +#define KEY_RADIO 0x181 +#define KEY_TUNER 0x182 +#define KEY_PLAYER 0x183 +#define KEY_TEXT 0x184 +#define KEY_DVD 0x185 +#define KEY_AUX 0x186 +#define KEY_MP3 0x187 +#define KEY_AUDIO 0x188 +#define KEY_VIDEO 0x189 +#define KEY_DIRECTORY 0x18a +#define KEY_LIST 0x18b +#define KEY_MEMO 0x18c +#define KEY_CALENDAR 0x18d +#define KEY_RED 0x18e +#define KEY_GREEN 0x18f +#define KEY_YELLOW 0x190 +#define KEY_BLUE 0x191 +#define KEY_CHANNELUP 0x192 +#define KEY_CHANNELDOWN 0x193 +#define KEY_FIRST 0x194 +#define KEY_LAST 0x195 +#define KEY_AB 0x196 +#define KEY_NEXT 0x197 +#define KEY_RESTART 0x198 +#define KEY_SLOW 0x199 +#define KEY_SHUFFLE 0x19a +#define KEY_BREAK 0x19b +#define KEY_PREVIOUS 0x19c +#define KEY_DIGITS 0x19d +#define KEY_TEEN 0x19e +#define KEY_TWEN 0x19f + #define KEY_MAX 0x1ff /* Relative axes */ |