core.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
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
9   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20   SOFTWARE IS DISCLAIMED.
21*/
22
23#include <linux/config.h>
24#include <linux/module.h>
25
26#include <linux/types.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/major.h>
30#include <linux/sched.h>
31#include <linux/slab.h>
32#include <linux/poll.h>
33#include <linux/fcntl.h>
34#include <linux/skbuff.h>
35#include <linux/socket.h>
36#include <linux/ioctl.h>
37#include <linux/file.h>
38#include <linux/init.h>
39#include <linux/wait.h>
40#include <net/sock.h>
41
42#include <linux/input.h>
43
44#include <net/bluetooth/bluetooth.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
54#define VERSION "1.1"
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,
63	 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
64	 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
65	105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
66	 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
67	191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
68	115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
69	122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
70	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
71	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
72	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
73	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
74	 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
75	150,158,159,128,136,177,178,176,142,152,173,140
76};
77
78static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
79
80static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
81{
82	struct hidp_session *session;
83	struct list_head *p;
84
85	BT_DBG("");
86
87	list_for_each(p, &hidp_session_list) {
88		session = list_entry(p, struct hidp_session, list);
89		if (!bacmp(bdaddr, &session->bdaddr))
90			return session;
91	}
92	return NULL;
93}
94
95static void __hidp_link_session(struct hidp_session *session)
96{
97	__module_get(THIS_MODULE);
98	list_add(&session->list, &hidp_session_list);
99}
100
101static void __hidp_unlink_session(struct hidp_session *session)
102{
103	list_del(&session->list);
104	module_put(THIS_MODULE);
105}
106
107static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
108{
109	bacpy(&ci->bdaddr, &session->bdaddr);
110
111	ci->flags = session->flags;
112	ci->state = session->state;
113
114	ci->vendor  = 0x0000;
115	ci->product = 0x0000;
116	ci->version = 0x0000;
117	memset(ci->name, 0, 128);
118
119	if (session->input) {
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
130static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
131{
132	struct hidp_session *session = dev->private;
133	struct sk_buff *skb;
134	unsigned char newleds;
135
136	BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
137
138	if (type != EV_LED)
139		return -1;
140
141	newleds = (!!test_bit(LED_KANA,    dev->led) << 3) |
142		  (!!test_bit(LED_COMPOSE, dev->led) << 3) |
143		  (!!test_bit(LED_SCROLLL, dev->led) << 2) |
144		  (!!test_bit(LED_CAPSL,   dev->led) << 1) |
145		  (!!test_bit(LED_NUML,    dev->led));
146
147	if (session->leds == newleds)
148		return 0;
149
150	session->leds = newleds;
151
152	if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
153		BT_ERR("Can't allocate memory for new frame");
154		return -ENOMEM;
155	}
156
157	*skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
158	*skb_put(skb, 1) = 0x01;
159	*skb_put(skb, 1) = newleds;
160
161	skb_queue_tail(&session->intr_transmit, skb);
162
163	hidp_schedule(session);
164
165	return 0;
166}
167
168static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
169{
170	struct input_dev *dev = session->input;
171	unsigned char *keys = session->keys;
172	unsigned char *udata = skb->data + 1;
173	signed char *sdata = skb->data + 1;
174	int i, size = skb->len - 1;
175
176	switch (skb->data[0]) {
177	case 0x01:	/* Keyboard report */
178		for (i = 0; i < 8; i++)
179			input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
180
181		/* If all the key codes have been set to 0x01, it means
182		 * too many keys were pressed at the same time. */
183		if (!memcmp(udata + 2, hidp_mkeyspat, 6))
184			break;
185
186		for (i = 2; i < 8; i++) {
187			if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
188				if (hidp_keycode[keys[i]])
189					input_report_key(dev, hidp_keycode[keys[i]], 0);
190				else
191					BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
192			}
193
194			if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
195				if (hidp_keycode[udata[i]])
196					input_report_key(dev, hidp_keycode[udata[i]], 1);
197				else
198					BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
199			}
200		}
201
202		memcpy(keys, udata, 8);
203		break;
204
205	case 0x02:	/* Mouse report */
206		input_report_key(dev, BTN_LEFT,   sdata[0] & 0x01);
207		input_report_key(dev, BTN_RIGHT,  sdata[0] & 0x02);
208		input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
209		input_report_key(dev, BTN_SIDE,   sdata[0] & 0x08);
210		input_report_key(dev, BTN_EXTRA,  sdata[0] & 0x10);
211
212		input_report_rel(dev, REL_X, sdata[1]);
213		input_report_rel(dev, REL_Y, sdata[2]);
214
215		if (size > 3)
216			input_report_rel(dev, REL_WHEEL, sdata[3]);
217		break;
218	}
219
220	input_sync(dev);
221}
222
223static void hidp_idle_timeout(unsigned long arg)
224{
225	struct hidp_session *session = (struct hidp_session *) arg;
226
227	atomic_inc(&session->terminate);
228	hidp_schedule(session);
229}
230
231static inline void hidp_set_timer(struct hidp_session *session)
232{
233	if (session->idle_to > 0)
234		mod_timer(&session->timer, jiffies + HZ * session->idle_to);
235}
236
237static inline void hidp_del_timer(struct hidp_session *session)
238{
239	if (session->idle_to > 0)
240		del_timer(&session->timer);
241}
242
243static int __hidp_send_ctrl_message(struct hidp_session *session,
244			unsigned char hdr, unsigned char *data, int size)
245{
246	struct sk_buff *skb;
247
248	BT_DBG("session %p data %p size %d", session, data, size);
249
250	if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
251		BT_ERR("Can't allocate memory for new frame");
252		return -ENOMEM;
253	}
254
255	*skb_put(skb, 1) = hdr;
256	if (data && size > 0)
257		memcpy(skb_put(skb, size), data, size);
258
259	skb_queue_tail(&session->ctrl_transmit, skb);
260
261	return 0;
262}
263
264static int inline hidp_send_ctrl_message(struct hidp_session *session,
265			unsigned char hdr, unsigned char *data, int size)
266{
267	int err;
268
269	err = __hidp_send_ctrl_message(session, hdr, data, size);
270
271	hidp_schedule(session);
272
273	return err;
274}
275
276static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
277{
278	BT_DBG("session %p param 0x%02x", session, param);
279
280	switch (param) {
281	case HIDP_HSHK_SUCCESSFUL:
282		/* FIXME: Call into SET_ GET_ handlers here */
283		break;
284
285	case HIDP_HSHK_NOT_READY:
286	case HIDP_HSHK_ERR_INVALID_REPORT_ID:
287	case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
288	case HIDP_HSHK_ERR_INVALID_PARAMETER:
289		/* FIXME: Call into SET_ GET_ handlers here */
290		break;
291
292	case HIDP_HSHK_ERR_UNKNOWN:
293		break;
294
295	case HIDP_HSHK_ERR_FATAL:
296		/* Device requests a reboot, as this is the only way this error
297 		 * can be recovered. */
298		__hidp_send_ctrl_message(session,
299			HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
300		break;
301
302	default:
303		__hidp_send_ctrl_message(session,
304			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
305		break;
306	}
307}
308
309static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
310{
311	BT_DBG("session %p param 0x%02x", session, param);
312
313	switch (param) {
314	case HIDP_CTRL_NOP:
315		break;
316
317	case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG:
318		/* Flush the transmit queues */
319		skb_queue_purge(&session->ctrl_transmit);
320		skb_queue_purge(&session->intr_transmit);
321
322		/* Kill session thread */
323		atomic_inc(&session->terminate);
324		break;
325
326	case HIDP_CTRL_HARD_RESET:
327	case HIDP_CTRL_SOFT_RESET:
328	case HIDP_CTRL_SUSPEND:
329	case HIDP_CTRL_EXIT_SUSPEND:
330		/* FIXME: We have to parse these and return no error */
331		break;
332
333	default:
334		__hidp_send_ctrl_message(session,
335			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
336		break;
337	}
338}
339
340static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
341{
342	BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
343
344	switch (param) {
345	case HIDP_DATA_RTYPE_INPUT:
346		hidp_set_timer(session);
347
348		if (session->input)
349			hidp_input_report(session, skb);
350		break;
351
352	case HIDP_DATA_RTYPE_OTHER:
353	case HIDP_DATA_RTYPE_OUPUT:
354	case HIDP_DATA_RTYPE_FEATURE:
355		break;
356
357	default:
358		__hidp_send_ctrl_message(session,
359			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
360	}
361}
362
363static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
364{
365	unsigned char hdr, type, param;
366
367	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
368
369	hdr = skb->data[0];
370	skb_pull(skb, 1);
371
372	type = hdr & HIDP_HEADER_TRANS_MASK;
373	param = hdr & HIDP_HEADER_PARAM_MASK;
374
375	switch (type) {
376	case HIDP_TRANS_HANDSHAKE:
377		hidp_process_handshake(session, param);
378		break;
379
380	case HIDP_TRANS_HID_CONTROL:
381		hidp_process_hid_control(session, param);
382		break;
383
384	case HIDP_TRANS_DATA:
385		hidp_process_data(session, skb, param);
386		break;
387
388	default:
389		__hidp_send_ctrl_message(session,
390			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
391		break;
392	}
393
394	kfree_skb(skb);
395}
396
397static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
398{
399	unsigned char hdr;
400
401	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
402
403	hdr = skb->data[0];
404	skb_pull(skb, 1);
405
406	if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
407		hidp_set_timer(session);
408		if (session->input)
409			hidp_input_report(session, skb);
410	} else {
411		BT_DBG("Unsupported protocol header 0x%02x", hdr);
412	}
413
414	kfree_skb(skb);
415}
416
417static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
418{
419	struct kvec iv = { data, len };
420	struct msghdr msg;
421
422	BT_DBG("sock %p data %p len %d", sock, data, len);
423
424	if (!len)
425		return 0;
426
427	memset(&msg, 0, sizeof(msg));
428
429	return kernel_sendmsg(sock, &msg, &iv, 1, len);
430}
431
432static int hidp_process_transmit(struct hidp_session *session)
433{
434	struct sk_buff *skb;
435
436	BT_DBG("session %p", session);
437
438	while ((skb = skb_dequeue(&session->ctrl_transmit))) {
439		if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
440			skb_queue_head(&session->ctrl_transmit, skb);
441			break;
442		}
443
444		hidp_set_timer(session);
445		kfree_skb(skb);
446	}
447
448	while ((skb = skb_dequeue(&session->intr_transmit))) {
449		if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
450			skb_queue_head(&session->intr_transmit, skb);
451			break;
452		}
453
454		hidp_set_timer(session);
455		kfree_skb(skb);
456	}
457
458	return skb_queue_len(&session->ctrl_transmit) +
459				skb_queue_len(&session->intr_transmit);
460}
461
462static int hidp_session(void *arg)
463{
464	struct hidp_session *session = arg;
465	struct sock *ctrl_sk = session->ctrl_sock->sk;
466	struct sock *intr_sk = session->intr_sock->sk;
467	struct sk_buff *skb;
468	int vendor = 0x0000, product = 0x0000;
469	wait_queue_t ctrl_wait, intr_wait;
470
471	BT_DBG("session %p", session);
472
473	if (session->input) {
474		vendor  = session->input->id.vendor;
475		product = session->input->id.product;
476	}
477
478	daemonize("khidpd_%04x%04x", vendor, product);
479	set_user_nice(current, -15);
480	current->flags |= PF_NOFREEZE;
481
482	init_waitqueue_entry(&ctrl_wait, current);
483	init_waitqueue_entry(&intr_wait, current);
484	add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
485	add_wait_queue(intr_sk->sk_sleep, &intr_wait);
486	while (!atomic_read(&session->terminate)) {
487		set_current_state(TASK_INTERRUPTIBLE);
488
489		if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)
490			break;
491
492		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
493			skb_orphan(skb);
494			hidp_recv_ctrl_frame(session, skb);
495		}
496
497		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
498			skb_orphan(skb);
499			hidp_recv_intr_frame(session, skb);
500		}
501
502		hidp_process_transmit(session);
503
504		schedule();
505	}
506	set_current_state(TASK_RUNNING);
507	remove_wait_queue(intr_sk->sk_sleep, &intr_wait);
508	remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
509
510	down_write(&hidp_session_sem);
511
512	hidp_del_timer(session);
513
514	if (intr_sk->sk_state != BT_CONNECTED)
515		wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
516
517	fput(session->ctrl_sock->file);
518
519	wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
520
521	fput(session->intr_sock->file);
522
523	__hidp_unlink_session(session);
524
525	if (session->input) {
526		input_unregister_device(session->input);
527		kfree(session->input);
528	}
529
530	up_write(&hidp_session_sem);
531
532	kfree(session);
533	return 0;
534}
535
536static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
537{
538	struct input_dev *input = session->input;
539	int i;
540
541	input->private = session;
542
543	input->id.bustype = BUS_BLUETOOTH;
544	input->id.vendor  = req->vendor;
545	input->id.product = req->product;
546	input->id.version = req->version;
547
548	if (req->subclass & 0x40) {
549		set_bit(EV_KEY, input->evbit);
550		set_bit(EV_LED, input->evbit);
551		set_bit(EV_REP, input->evbit);
552
553		set_bit(LED_NUML,    input->ledbit);
554		set_bit(LED_CAPSL,   input->ledbit);
555		set_bit(LED_SCROLLL, input->ledbit);
556		set_bit(LED_COMPOSE, input->ledbit);
557		set_bit(LED_KANA,    input->ledbit);
558
559		for (i = 0; i < sizeof(hidp_keycode); i++)
560			set_bit(hidp_keycode[i], input->keybit);
561		clear_bit(0, input->keybit);
562	}
563
564	if (req->subclass & 0x80) {
565		input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
566		input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
567		input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
568		input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
569		input->relbit[0] |= BIT(REL_WHEEL);
570	}
571
572	input->event = hidp_input_event;
573
574	input_register_device(input);
575}
576
577int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
578{
579	struct hidp_session *session, *s;
580	int err;
581
582	BT_DBG("");
583
584	if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||
585			bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))
586		return -ENOTUNIQ;
587
588	session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
589	if (!session)
590		return -ENOMEM;
591	memset(session, 0, sizeof(struct hidp_session));
592
593	session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
594	if (!session->input) {
595		kfree(session);
596		return -ENOMEM;
597	}
598	memset(session->input, 0, sizeof(struct input_dev));
599
600	down_write(&hidp_session_sem);
601
602	s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);
603	if (s && s->state == BT_CONNECTED) {
604		err = -EEXIST;
605		goto failed;
606	}
607
608	bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
609
610	session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
611	session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
612
613	BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
614
615	session->ctrl_sock = ctrl_sock;
616	session->intr_sock = intr_sock;
617	session->state     = BT_CONNECTED;
618
619	init_timer(&session->timer);
620
621	session->timer.function = hidp_idle_timeout;
622	session->timer.data     = (unsigned long) session;
623
624	skb_queue_head_init(&session->ctrl_transmit);
625	skb_queue_head_init(&session->intr_transmit);
626
627	session->flags   = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
628	session->idle_to = req->idle_to;
629
630	if (session->input)
631		hidp_setup_input(session, req);
632
633	__hidp_link_session(session);
634
635	hidp_set_timer(session);
636
637	err = kernel_thread(hidp_session, session, CLONE_KERNEL);
638	if (err < 0)
639		goto unlink;
640
641	if (session->input) {
642		hidp_send_ctrl_message(session,
643			HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
644		session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
645
646		session->leds = 0xff;
647		hidp_input_event(session->input, EV_LED, 0, 0);
648	}
649
650	up_write(&hidp_session_sem);
651	return 0;
652
653unlink:
654	hidp_del_timer(session);
655
656	__hidp_unlink_session(session);
657
658	if (session->input)
659		input_unregister_device(session->input);
660
661failed:
662	up_write(&hidp_session_sem);
663
664	if (session->input)
665		kfree(session->input);
666
667	kfree(session);
668	return err;
669}
670
671int hidp_del_connection(struct hidp_conndel_req *req)
672{
673	struct hidp_session *session;
674	int err = 0;
675
676	BT_DBG("");
677
678	down_read(&hidp_session_sem);
679
680	session = __hidp_get_session(&req->bdaddr);
681	if (session) {
682		if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
683			hidp_send_ctrl_message(session,
684				HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
685		} else {
686			/* Flush the transmit queues */
687			skb_queue_purge(&session->ctrl_transmit);
688			skb_queue_purge(&session->intr_transmit);
689
690			/* Kill session thread */
691			atomic_inc(&session->terminate);
692			hidp_schedule(session);
693		}
694	} else
695		err = -ENOENT;
696
697	up_read(&hidp_session_sem);
698	return err;
699}
700
701int hidp_get_connlist(struct hidp_connlist_req *req)
702{
703	struct list_head *p;
704	int err = 0, n = 0;
705
706	BT_DBG("");
707
708	down_read(&hidp_session_sem);
709
710	list_for_each(p, &hidp_session_list) {
711		struct hidp_session *session;
712		struct hidp_conninfo ci;
713
714		session = list_entry(p, struct hidp_session, list);
715
716		__hidp_copy_session(session, &ci);
717
718		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
719			err = -EFAULT;
720			break;
721		}
722
723		if (++n >= req->cnum)
724			break;
725
726		req->ci++;
727	}
728	req->cnum = n;
729
730	up_read(&hidp_session_sem);
731	return err;
732}
733
734int hidp_get_conninfo(struct hidp_conninfo *ci)
735{
736	struct hidp_session *session;
737	int err = 0;
738
739	down_read(&hidp_session_sem);
740
741	session = __hidp_get_session(&ci->bdaddr);
742	if (session)
743		__hidp_copy_session(session, ci);
744	else
745		err = -ENOENT;
746
747	up_read(&hidp_session_sem);
748	return err;
749}
750
751static int __init hidp_init(void)
752{
753	l2cap_load();
754
755	BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
756
757	return hidp_init_sockets();
758}
759
760static void __exit hidp_exit(void)
761{
762	hidp_cleanup_sockets();
763}
764
765module_init(hidp_init);
766module_exit(hidp_exit);
767
768MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
769MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
770MODULE_VERSION(VERSION);
771MODULE_LICENSE("GPL");
772MODULE_ALIAS("bt-proto-6");
773