4 * Collin R. Mulliner <collin@betaversion.net>
6 * http://www.mulliner.org/bluetooth/
22 #include <sys/ioctl.h>
23 #include <sys/socket.h>
25 #include <linux/input.h>
27 #include <bluetooth/bluetooth.h>
28 #include <bluetooth/hci.h>
29 #include <bluetooth/hci_lib.h>
30 #include <bluetooth/l2cap.h>
31 #include <bluetooth/sdp.h>
32 #include <bluetooth/hidp.h>
60 int bthid_send(int key, int updown)
67 if (key == 0xffff) e.type = 0xff;
69 write(es[1], &e, sizeof(e));
73 static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int lm, int backlog)
75 struct sockaddr_l2 addr;
76 struct l2cap_options opts;
79 if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0)
82 memset(&addr, 0, sizeof(addr));
83 addr.l2_family = AF_BLUETOOTH;
84 bacpy(&addr.l2_bdaddr, bdaddr);
85 addr.l2_psm = htobs(psm);
87 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
92 setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm));
94 memset(&opts, 0, sizeof(opts));
95 opts.imtu = HIDP_DEFAULT_MTU;
96 opts.omtu = HIDP_DEFAULT_MTU;
97 opts.flush_to = 0xffff;
99 setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts));
101 if (listen(sk, backlog) < 0) {
109 static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm)
111 struct sockaddr_l2 addr;
112 struct l2cap_options opts;
115 if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0)
118 memset(&addr, 0, sizeof(addr));
119 addr.l2_family = AF_BLUETOOTH;
120 bacpy(&addr.l2_bdaddr, src);
122 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
127 memset(&opts, 0, sizeof(opts));
128 opts.imtu = HIDP_DEFAULT_MTU;
129 opts.omtu = HIDP_DEFAULT_MTU;
130 opts.flush_to = 0xffff;
132 setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts));
134 memset(&addr, 0, sizeof(addr));
135 addr.l2_family = AF_BLUETOOTH;
136 bacpy(&addr.l2_bdaddr, dst);
137 addr.l2_psm = htobs(psm);
139 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
147 static int l2cap_accept(int sk, bdaddr_t *bdaddr)
149 struct sockaddr_l2 addr;
153 memset(&addr, 0, sizeof(addr));
154 addrlen = sizeof(addr);
156 if ((nsk = accept(sk, (struct sockaddr *) &addr, &addrlen)) < 0)
160 bacpy(bdaddr, &addr.l2_bdaddr);
165 //int main(int argc, char **argv)
168 unsigned char pkg[12];
171 struct input_event ie;
174 unsigned char ib[1024];
175 unsigned char cb[1024];
177 unsigned char modifiers = 0;
178 unsigned char modifiers_old = 0;
181 int bitmask[8] = {0};
182 int is, iss, cs, css;
185 css = l2cap_listen(BDADDR_ANY, L2CAP_PSM_HIDP_CTRL, 0, 1);
187 iss = l2cap_listen(BDADDR_ANY, L2CAP_PSM_HIDP_INTR, 0, 1);
192 cs = l2cap_accept(css, NULL);
193 //cs = l2cap_connect(BDADDR_ANY, &dst, L2CAP_PSM_HIDP_CTRL);
195 is = l2cap_accept(iss, NULL);
196 //is = l2cap_connect(BDADDR_ANY, &dst, L2CAP_PSM_HIDP_INTR);
200 pf[0].events = POLLIN | POLLERR | POLLHUP;
202 pf[1].events = POLLIN | POLLERR | POLLHUP;
204 pf[2].events = POLLIN | POLLERR | POLLHUP;
211 if (poll(pf, 3, -1) <= 0) {
218 if (read(ip, &ie, sizeof(ie)) <= 0) {
222 if (ie.type == 0xff) {
224 if (ie.value == 0xffff) {
232 else if (ie.type == 0x01) {
235 modifiers_old = modifiers;
240 bitmask[1] = (ie.value ? 1 : 0);
243 bitmask[5] = (ie.value ? 1 : 0);
246 bitmask[2] = (ie.value ? 1 : 0);
249 bitmask[6] = (ie.value ? 1 : 0);
252 bitmask[0] = (ie.value ? 1 : 0);
255 bitmask[4] = (ie.value ? 1 : 0);
259 pkg[4] = keycode2hidp[ie.code];
260 //printf("keycode=%d, hidp=%d\n",ie.code,pkg[4]);
270 for (i = 0; i < 8; i++) {
271 modifiers |= (bitmask[i] << i);
273 //fprintf(stderr, "modifiers: 0x%02x\n", modifiers);
275 if (press != press_old || modifiers != modifiers_old) {
280 //pkg[4] = 0x00; // the key code
287 if (write(is, pkg, 10) <= 0) {
298 if ((size = read(cs, cb, sizeof(cb))) <= 0) {
303 //printf("cs(%d)\n", size);
305 /* for (i = 0; i < size; i++)
306 printf("%02x",cb[i]);
309 if (state == 0 && size == 1 && cb[0] == 0x70) {
310 //printf("got set_protocol BOOT\n");
319 if ((size = read(is, ib, sizeof(ib))) <= 0) {
324 /* printf("is(%d): ", size);
325 for (i = 0; i < size; i++)
326 printf("%02x",ib[i]);
332 printf("disconnected\n");
338 int bthid_process_keypress(button *active_but, int updown)
340 int new_state = active_but->kb->state;
343 if (active_but->modifier/* is a shift / ctrl / mod pressed */
344 && !(active_but->modifier & BUT_CAPS) ) {
345 if (active_but->kb->state_locked & active_but->modifier) {
346 /* was locked then unset & unlock */
347 active_but->kb->state_locked ^= active_but->modifier;
348 new_state ^= active_but->modifier;
350 else if (new_state & active_but->modifier) {
351 /* was set then lock */
352 active_but->kb->state_locked ^= active_but->modifier;
355 /* was unset then set */
356 new_state ^= active_but->modifier;
359 /* deal with caps key - maybe this can go above now ?*/
360 else if (active_but->modifier & BUT_CAPS) {
361 new_state ^= KB_STATE_CAPS; /* turn caps on/off */
363 else if ((active_but->kb->state & KB_STATE_SHIFT)
364 || (active_but->kb->state & KB_STATE_MOD)
365 || (active_but->kb->state & KB_STATE_CTRL)
366 || (active_but->kb->state & KB_STATE_META)
367 || (active_but->kb->state & KB_STATE_ALT) ) {
368 /* check if the kbd is already in a state and reset it
369 * leaving caps key state alone */
370 new_state &= KB_STATE_CAPS;
371 new_state |= active_but->kb->state_locked;
375 if (active_but->kb->state & KB_STATE_SHIFT) {
378 else if (active_but->kb->state & KB_STATE_CTRL) {
381 else if (active_but->kb->state & KB_STATE_ALT) {
387 if (active_but->scancode == 56) {
389 if (active_but->kb->bthid_state & KB_STATE_ALT_L) {
391 active_but->kb->bthid_state &= (!KB_STATE_ALT_L);
395 active_but->kb->bthid_state |= KB_STATE_ALT_L;
400 else if (active_but->scancode == 29) {
402 if (active_but->kb->bthid_state & KB_STATE_CTRL_L) {
404 active_but->kb->bthid_state &= (!KB_STATE_CTRL_L);
408 active_but->kb->bthid_state |= KB_STATE_CTRL_L;
413 else if (active_but->scancode == 42) {
415 if (active_but->kb->bthid_state & KB_STATE_SHIFT_L) {
417 active_but->kb->bthid_state &= (!KB_STATE_SHIFT_L);
421 active_but->kb->bthid_state |= KB_STATE_SHIFT_L;
425 // release shift/ctrl/alt when pressing other key
428 bthid_send(active_but->scancode, updown);
429 if (active_but->scancode == 0xffff) {
431 kill(bthid_pid, SIGTERM);
435 if (active_but->kb->bthid_state & KB_STATE_ALT_L) {
437 active_but->kb->bthid_state &= (!KB_STATE_ALT_L);
439 if (active_but->kb->bthid_state & KB_STATE_CTRL_L) {
441 active_but->kb->bthid_state &= (!KB_STATE_CTRL_L);
443 if (active_but->kb->bthid_state & KB_STATE_SHIFT_L) {
445 active_but->kb->bthid_state &= (!KB_STATE_SHIFT_L);