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 ---