core.c (5a84d159061d914c8dd4aa372ac6e9529c2be453) | core.c (e1aaadd4d8162a2c33e41dd5a72234ea4d3b014f) |
---|---|
1/* 2 HIDP implementation for Linux Bluetooth stack (BlueZ). 3 Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License version 2 as 7 published by the Free Software Foundation; 8 --- 24 unchanged lines hidden (view full) --- 33#include <linux/socket.h> 34#include <linux/ioctl.h> 35#include <linux/file.h> 36#include <linux/init.h> 37#include <linux/wait.h> 38#include <net/sock.h> 39 40#include <linux/input.h> | 1/* 2 HIDP implementation for Linux Bluetooth stack (BlueZ). 3 Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License version 2 as 7 published by the Free Software Foundation; 8 --- 24 unchanged lines hidden (view full) --- 33#include <linux/socket.h> 34#include <linux/ioctl.h> 35#include <linux/file.h> 36#include <linux/init.h> 37#include <linux/wait.h> 38#include <net/sock.h> 39 40#include <linux/input.h> |
41#include <linux/hid.h> |
|
41 42#include <net/bluetooth/bluetooth.h> 43#include <net/bluetooth/hci_core.h> 44#include <net/bluetooth/l2cap.h> 45 46#include "hidp.h" 47 48#ifndef CONFIG_BT_HIDP_DEBUG 49#undef BT_DBG 50#define BT_DBG(D...) 51#endif 52 | 42 43#include <net/bluetooth/bluetooth.h> 44#include <net/bluetooth/hci_core.h> 45#include <net/bluetooth/l2cap.h> 46 47#include "hidp.h" 48 49#ifndef CONFIG_BT_HIDP_DEBUG 50#undef BT_DBG 51#define BT_DBG(D...) 52#endif 53 |
53#define VERSION "1.1" | 54#define VERSION "1.2" |
54 55static DECLARE_RWSEM(hidp_session_sem); 56static LIST_HEAD(hidp_session_list); 57 58static unsigned char hidp_keycode[256] = { 59 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 60 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, 61 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, --- 57 unchanged lines hidden (view full) --- 119 ci->vendor = session->input->id.vendor; 120 ci->product = session->input->id.product; 121 ci->version = session->input->id.version; 122 if (session->input->name) 123 strncpy(ci->name, session->input->name, 128); 124 else 125 strncpy(ci->name, "HID Boot Device", 128); 126 } | 55 56static DECLARE_RWSEM(hidp_session_sem); 57static LIST_HEAD(hidp_session_list); 58 59static unsigned char hidp_keycode[256] = { 60 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 61 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, 62 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, --- 57 unchanged lines hidden (view full) --- 120 ci->vendor = session->input->id.vendor; 121 ci->product = session->input->id.product; 122 ci->version = session->input->id.version; 123 if (session->input->name) 124 strncpy(ci->name, session->input->name, 128); 125 else 126 strncpy(ci->name, "HID Boot Device", 128); 127 } |
128 129 if (session->hid) { 130 ci->vendor = session->hid->vendor; 131 ci->product = session->hid->product; 132 ci->version = session->hid->version; 133 strncpy(ci->name, session->hid->name, 128); 134 } |
|
127} 128 | 135} 136 |
129static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 137static inline int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, 138 unsigned int type, unsigned int code, int value) |
130{ | 139{ |
131 struct hidp_session *session = dev->private; 132 struct sk_buff *skb; | |
133 unsigned char newleds; | 140 unsigned char newleds; |
141 struct sk_buff *skb; |
|
134 | 142 |
135 BT_DBG("input %p type %d code %d value %d", dev, type, code, value); | 143 BT_DBG("session %p type %d code %d value %d", session, type, code, value); |
136 137 if (type != EV_LED) 138 return -1; 139 140 newleds = (!!test_bit(LED_KANA, dev->led) << 3) | 141 (!!test_bit(LED_COMPOSE, dev->led) << 3) | 142 (!!test_bit(LED_SCROLLL, dev->led) << 2) | 143 (!!test_bit(LED_CAPSL, dev->led) << 1) | --- 15 unchanged lines hidden (view full) --- 159 160 skb_queue_tail(&session->intr_transmit, skb); 161 162 hidp_schedule(session); 163 164 return 0; 165} 166 | 144 145 if (type != EV_LED) 146 return -1; 147 148 newleds = (!!test_bit(LED_KANA, dev->led) << 3) | 149 (!!test_bit(LED_COMPOSE, dev->led) << 3) | 150 (!!test_bit(LED_SCROLLL, dev->led) << 2) | 151 (!!test_bit(LED_CAPSL, dev->led) << 1) | --- 15 unchanged lines hidden (view full) --- 167 168 skb_queue_tail(&session->intr_transmit, skb); 169 170 hidp_schedule(session); 171 172 return 0; 173} 174 |
175static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 176{ 177 struct hid_device *hid = dev->private; 178 struct hidp_session *session = hid->driver_data; 179 180 return hidp_queue_event(session, dev, type, code, value); 181} 182 183static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 184{ 185 struct hidp_session *session = dev->private; 186 187 return hidp_queue_event(session, dev, type, code, value); 188} 189 |
|
167static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) 168{ 169 struct input_dev *dev = session->input; 170 unsigned char *keys = session->keys; 171 unsigned char *udata = skb->data + 1; 172 signed char *sdata = skb->data + 1; 173 int i, size = skb->len - 1; 174 --- 39 unchanged lines hidden (view full) --- 214 if (size > 3) 215 input_report_rel(dev, REL_WHEEL, sdata[3]); 216 break; 217 } 218 219 input_sync(dev); 220} 221 | 190static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) 191{ 192 struct input_dev *dev = session->input; 193 unsigned char *keys = session->keys; 194 unsigned char *udata = skb->data + 1; 195 signed char *sdata = skb->data + 1; 196 int i, size = skb->len - 1; 197 --- 39 unchanged lines hidden (view full) --- 237 if (size > 3) 238 input_report_rel(dev, REL_WHEEL, sdata[3]); 239 break; 240 } 241 242 input_sync(dev); 243} 244 |
245static inline int hidp_queue_report(struct hidp_session *session, unsigned char *data, int size) 246{ 247 struct sk_buff *skb; 248 249 BT_DBG("session %p hid %p data %p size %d", session, device, data, size); 250 251 if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) { 252 BT_ERR("Can't allocate memory for new frame"); 253 return -ENOMEM; 254 } 255 256 *skb_put(skb, 1) = 0xa2; 257 if (size > 0) 258 memcpy(skb_put(skb, size), data, size); 259 260 skb_queue_tail(&session->intr_transmit, skb); 261 262 hidp_schedule(session); 263 264 return 0; 265} 266 267static int hidp_send_report(struct hidp_session *session, struct hid_report *report) 268{ 269 unsigned char buf[32]; 270 int rsize; 271 272 rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); 273 if (rsize > sizeof(buf)) 274 return -EIO; 275 276 hid_output_report(report, buf); 277 278 return hidp_queue_report(session, buf, rsize); 279} 280 |
|
222static void hidp_idle_timeout(unsigned long arg) 223{ 224 struct hidp_session *session = (struct hidp_session *) arg; 225 226 atomic_inc(&session->terminate); 227 hidp_schedule(session); 228} 229 --- 111 unchanged lines hidden (view full) --- 341 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); 342 343 switch (param) { 344 case HIDP_DATA_RTYPE_INPUT: 345 hidp_set_timer(session); 346 347 if (session->input) 348 hidp_input_report(session, skb); | 281static void hidp_idle_timeout(unsigned long arg) 282{ 283 struct hidp_session *session = (struct hidp_session *) arg; 284 285 atomic_inc(&session->terminate); 286 hidp_schedule(session); 287} 288 --- 111 unchanged lines hidden (view full) --- 400 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); 401 402 switch (param) { 403 case HIDP_DATA_RTYPE_INPUT: 404 hidp_set_timer(session); 405 406 if (session->input) 407 hidp_input_report(session, skb); |
408 409 if (session->hid) 410 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0); 411 |
|
349 break; 350 351 case HIDP_DATA_RTYPE_OTHER: 352 case HIDP_DATA_RTYPE_OUPUT: 353 case HIDP_DATA_RTYPE_FEATURE: 354 break; 355 356 default: --- 42 unchanged lines hidden (view full) --- 399 400 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 401 402 hdr = skb->data[0]; 403 skb_pull(skb, 1); 404 405 if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) { 406 hidp_set_timer(session); | 412 break; 413 414 case HIDP_DATA_RTYPE_OTHER: 415 case HIDP_DATA_RTYPE_OUPUT: 416 case HIDP_DATA_RTYPE_FEATURE: 417 break; 418 419 default: --- 42 unchanged lines hidden (view full) --- 462 463 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 464 465 hdr = skb->data[0]; 466 skb_pull(skb, 1); 467 468 if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) { 469 hidp_set_timer(session); |
470 |
|
407 if (session->input) 408 hidp_input_report(session, skb); | 471 if (session->input) 472 hidp_input_report(session, skb); |
473 474 if (session->hid) { 475 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 1); 476 BT_DBG("report len %d", skb->len); 477 } |
|
409 } else { 410 BT_DBG("Unsupported protocol header 0x%02x", hdr); 411 } 412 413 kfree_skb(skb); 414} 415 416static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) --- 49 unchanged lines hidden (view full) --- 466 467 BT_DBG("session %p", session); 468 469 if (session->input) { 470 vendor = session->input->id.vendor; 471 product = session->input->id.product; 472 } 473 | 478 } else { 479 BT_DBG("Unsupported protocol header 0x%02x", hdr); 480 } 481 482 kfree_skb(skb); 483} 484 485static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) --- 49 unchanged lines hidden (view full) --- 535 536 BT_DBG("session %p", session); 537 538 if (session->input) { 539 vendor = session->input->id.vendor; 540 product = session->input->id.product; 541 } 542 |
543 if (session->hid) { 544 vendor = session->hid->vendor; 545 product = session->hid->product; 546 } 547 |
|
474 daemonize("khidpd_%04x%04x", vendor, product); 475 set_user_nice(current, -15); 476 current->flags |= PF_NOFREEZE; 477 478 init_waitqueue_entry(&ctrl_wait, current); 479 init_waitqueue_entry(&intr_wait, current); 480 add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait); 481 add_wait_queue(intr_sk->sk_sleep, &intr_wait); --- 34 unchanged lines hidden (view full) --- 516 517 __hidp_unlink_session(session); 518 519 if (session->input) { 520 input_unregister_device(session->input); 521 session->input = NULL; 522 } 523 | 548 daemonize("khidpd_%04x%04x", vendor, product); 549 set_user_nice(current, -15); 550 current->flags |= PF_NOFREEZE; 551 552 init_waitqueue_entry(&ctrl_wait, current); 553 init_waitqueue_entry(&intr_wait, current); 554 add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait); 555 add_wait_queue(intr_sk->sk_sleep, &intr_wait); --- 34 unchanged lines hidden (view full) --- 590 591 __hidp_unlink_session(session); 592 593 if (session->input) { 594 input_unregister_device(session->input); 595 session->input = NULL; 596 } 597 |
598 if (session->hid) { 599 if (session->hid->claimed & HID_CLAIMED_INPUT) 600 hidinput_disconnect(session->hid); 601 hid_free_device(session->hid); 602 } 603 |
|
524 up_write(&hidp_session_sem); 525 526 kfree(session); 527 return 0; 528} 529 530static struct device *hidp_get_device(struct hidp_session *session) 531{ --- 53 unchanged lines hidden (view full) --- 585 586 input->cdev.dev = hidp_get_device(session); 587 588 input->event = hidp_input_event; 589 590 input_register_device(input); 591} 592 | 604 up_write(&hidp_session_sem); 605 606 kfree(session); 607 return 0; 608} 609 610static struct device *hidp_get_device(struct hidp_session *session) 611{ --- 53 unchanged lines hidden (view full) --- 665 666 input->cdev.dev = hidp_get_device(session); 667 668 input->event = hidp_input_event; 669 670 input_register_device(input); 671} 672 |
673static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) 674{ 675 struct hid_device *hid = session->hid; 676 struct hid_report *report; 677 bdaddr_t src, dst; 678 679 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); 680 baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); 681 682 hid->driver_data = session; 683 684 hid->country = req->country; 685 686 hid->bus = BUS_BLUETOOTH; 687 hid->vendor = req->vendor; 688 hid->product = req->product; 689 hid->version = req->version; 690 691 strncpy(hid->name, req->name, 128); 692 strncpy(hid->phys, batostr(&src), 64); 693 strncpy(hid->uniq, batostr(&dst), 64); 694 695 hid->dev = hidp_get_device(session); 696 697 hid->hidinput_input_event = hidp_hidinput_event; 698 699 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) 700 hidp_send_report(session, report); 701 702 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) 703 hidp_send_report(session, report); 704 705 if (hidinput_connect(hid) == 0) { 706 hid->claimed |= HID_CLAIMED_INPUT; 707 hid_ff_init(hid); 708 } 709} 710 |
|
593int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) 594{ 595 struct hidp_session *session, *s; 596 int err; 597 598 BT_DBG(""); 599 600 if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) || 601 bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) 602 return -ENOTUNIQ; 603 604 session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); 605 if (!session) 606 return -ENOMEM; 607 | 711int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) 712{ 713 struct hidp_session *session, *s; 714 int err; 715 716 BT_DBG(""); 717 718 if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) || 719 bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) 720 return -ENOTUNIQ; 721 722 session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); 723 if (!session) 724 return -ENOMEM; 725 |
608 session->input = input_allocate_device(); 609 if (!session->input) { 610 kfree(session); 611 return -ENOMEM; | 726 BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); 727 728 if (req->rd_size > 0) { 729 unsigned char *buf = kmalloc(req->rd_size, GFP_KERNEL); 730 731 if (!buf) { 732 kfree(session); 733 return -ENOMEM; 734 } 735 736 if (copy_from_user(buf, req->rd_data, req->rd_size)) { 737 kfree(buf); 738 kfree(session); 739 return -EFAULT; 740 } 741 742 session->hid = hid_parse_report(buf, req->rd_size); 743 744 kfree(buf); 745 746 if (!session->hid) { 747 kfree(session); 748 return -EINVAL; 749 } |
612 } 613 | 750 } 751 |
752 if (!session->hid) { 753 session->input = input_allocate_device(); 754 if (!session->input) { 755 kfree(session); 756 return -ENOMEM; 757 } 758 } 759 |
|
614 down_write(&hidp_session_sem); 615 616 s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); 617 if (s && s->state == BT_CONNECTED) { 618 err = -EEXIST; 619 goto failed; 620 } 621 --- 17 unchanged lines hidden (view full) --- 639 skb_queue_head_init(&session->intr_transmit); 640 641 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 642 session->idle_to = req->idle_to; 643 644 if (session->input) 645 hidp_setup_input(session, req); 646 | 760 down_write(&hidp_session_sem); 761 762 s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); 763 if (s && s->state == BT_CONNECTED) { 764 err = -EEXIST; 765 goto failed; 766 } 767 --- 17 unchanged lines hidden (view full) --- 785 skb_queue_head_init(&session->intr_transmit); 786 787 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 788 session->idle_to = req->idle_to; 789 790 if (session->input) 791 hidp_setup_input(session, req); 792 |
793 if (session->hid) 794 hidp_setup_hid(session, req); 795 |
|
647 __hidp_link_session(session); 648 649 hidp_set_timer(session); 650 651 err = kernel_thread(hidp_session, session, CLONE_KERNEL); 652 if (err < 0) 653 goto unlink; 654 --- 17 unchanged lines hidden (view full) --- 672 if (session->input) { 673 input_unregister_device(session->input); 674 session->input = NULL; /* don't try to free it here */ 675 } 676 677failed: 678 up_write(&hidp_session_sem); 679 | 796 __hidp_link_session(session); 797 798 hidp_set_timer(session); 799 800 err = kernel_thread(hidp_session, session, CLONE_KERNEL); 801 if (err < 0) 802 goto unlink; 803 --- 17 unchanged lines hidden (view full) --- 821 if (session->input) { 822 input_unregister_device(session->input); 823 session->input = NULL; /* don't try to free it here */ 824 } 825 826failed: 827 up_write(&hidp_session_sem); 828 |
829 if (session->hid) 830 hid_free_device(session->hid); 831 |
|
680 kfree(session->input); 681 kfree(session); 682 return err; 683} 684 685int hidp_del_connection(struct hidp_conndel_req *req) 686{ 687 struct hidp_session *session; --- 99 unchanged lines hidden --- | 832 kfree(session->input); 833 kfree(session); 834 return err; 835} 836 837int hidp_del_connection(struct hidp_conndel_req *req) 838{ 839 struct hidp_session *session; --- 99 unchanged lines hidden --- |