blob: 8d30a33b27d9e4c12cb79e2034a0c2226d2db205 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 HIDP implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
David Herrmannb4f34d82013-04-06 20:28:46 +02004 Copyright (C) 2013 David Herrmann <dh.herrmann@gmail.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation;
9
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090014 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 SOFTWARE IS DISCLAIMED.
22*/
23
David Herrmannb4f34d82013-04-06 20:28:46 +020024#include <linux/kref.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/file.h>
Szymon Jancaabf6f82011-04-05 15:37:45 +020027#include <linux/kthread.h>
Marcel Holtmann364f6352009-08-22 14:15:53 -070028#include <linux/hidraw.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30#include <net/bluetooth/bluetooth.h>
Marcel Holtmann0a85b962006-07-06 13:09:02 +020031#include <net/bluetooth/hci_core.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <net/bluetooth/l2cap.h>
33
34#include "hidp.h"
35
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +010036#define VERSION "1.2"
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
38static DECLARE_RWSEM(hidp_session_sem);
39static LIST_HEAD(hidp_session_list);
40
41static unsigned char hidp_keycode[256] = {
Szymon Janc17f09a72011-03-21 14:20:01 +010042 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36,
43 37, 38, 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45,
44 21, 44, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 28, 1,
45 14, 15, 57, 12, 13, 26, 27, 43, 43, 39, 40, 41, 51, 52,
46 53, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 87, 88,
47 99, 70, 119, 110, 102, 104, 111, 107, 109, 106, 105, 108, 103, 69,
48 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, 72, 73,
49 82, 83, 86, 127, 116, 117, 183, 184, 185, 186, 187, 188, 189, 190,
50 191, 192, 193, 194, 134, 138, 130, 132, 128, 129, 131, 137, 133, 135,
51 136, 113, 115, 114, 0, 0, 0, 121, 0, 89, 93, 124, 92, 94,
52 95, 0, 0, 0, 122, 123, 90, 91, 85, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 29, 42, 56, 125, 97, 54, 100, 126, 164, 166, 165, 163, 161, 115,
59 114, 113, 150, 158, 159, 128, 136, 177, 178, 176, 142, 152, 173, 140
Linus Torvalds1da177e2005-04-16 15:20:36 -070060};
61
62static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
63
David Herrmannb4f34d82013-04-06 20:28:46 +020064static int hidp_session_probe(struct l2cap_conn *conn,
65 struct l2cap_user *user);
66static void hidp_session_remove(struct l2cap_conn *conn,
67 struct l2cap_user *user);
68static int hidp_session_thread(void *arg);
69static void hidp_session_terminate(struct hidp_session *s);
70
David Herrmann3764eaa2013-04-06 20:28:43 +020071static inline void hidp_schedule(struct hidp_session *session)
72{
73 struct sock *ctrl_sk = session->ctrl_sock->sk;
74 struct sock *intr_sk = session->intr_sock->sk;
75
76 wake_up_interruptible(sk_sleep(ctrl_sk));
77 wake_up_interruptible(sk_sleep(intr_sk));
78}
79
Linus Torvalds1da177e2005-04-16 15:20:36 -070080static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
81{
82 struct hidp_session *session;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
84 BT_DBG("");
85
Gustavo F. Padovancd11cdd2011-10-06 17:35:31 -030086 list_for_each_entry(session, &hidp_session_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 if (!bacmp(bdaddr, &session->bdaddr))
88 return session;
89 }
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +020090
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 return NULL;
92}
93
Linus Torvalds1da177e2005-04-16 15:20:36 -070094static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
95{
Vasiliy Kulikovd31dbf62010-10-30 18:26:31 +040096 memset(ci, 0, sizeof(*ci));
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 bacpy(&ci->bdaddr, &session->bdaddr);
98
99 ci->flags = session->flags;
David Herrmanndcc07642013-04-06 20:28:40 +0200100 ci->state = BT_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
102 ci->vendor = 0x0000;
103 ci->product = 0x0000;
104 ci->version = 0x0000;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106 if (session->input) {
107 ci->vendor = session->input->id.vendor;
108 ci->product = session->input->id.product;
109 ci->version = session->input->id.version;
110 if (session->input->name)
111 strncpy(ci->name, session->input->name, 128);
112 else
113 strncpy(ci->name, "HID Boot Device", 128);
114 }
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100115
116 if (session->hid) {
117 ci->vendor = session->hid->vendor;
118 ci->product = session->hid->product;
119 ci->version = session->hid->version;
120 strncpy(ci->name, session->hid->name, 128);
121 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122}
123
Andrew Morton91f5cca2008-02-05 03:07:58 -0800124static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev,
125 unsigned int type, unsigned int code, int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 unsigned char newleds;
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100128 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100130 BT_DBG("session %p type %d code %d value %d", session, type, code, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132 if (type != EV_LED)
133 return -1;
134
135 newleds = (!!test_bit(LED_KANA, dev->led) << 3) |
136 (!!test_bit(LED_COMPOSE, dev->led) << 3) |
137 (!!test_bit(LED_SCROLLL, dev->led) << 2) |
138 (!!test_bit(LED_CAPSL, dev->led) << 1) |
139 (!!test_bit(LED_NUML, dev->led));
140
141 if (session->leds == newleds)
142 return 0;
143
144 session->leds = newleds;
145
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200146 skb = alloc_skb(3, GFP_ATOMIC);
147 if (!skb) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 BT_ERR("Can't allocate memory for new frame");
149 return -ENOMEM;
150 }
151
152 *skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
153 *skb_put(skb, 1) = 0x01;
154 *skb_put(skb, 1) = newleds;
155
156 skb_queue_tail(&session->intr_transmit, skb);
157
158 hidp_schedule(session);
159
160 return 0;
161}
162
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100163static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
164{
Marcel Holtmann5be39462007-05-09 09:15:30 +0200165 struct hid_device *hid = input_get_drvdata(dev);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100166 struct hidp_session *session = hid->driver_data;
167
168 return hidp_queue_event(session, dev, type, code, value);
169}
170
171static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
172{
Marcel Holtmann5be39462007-05-09 09:15:30 +0200173 struct hidp_session *session = input_get_drvdata(dev);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100174
175 return hidp_queue_event(session, dev, type, code, value);
176}
177
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
179{
180 struct input_dev *dev = session->input;
181 unsigned char *keys = session->keys;
182 unsigned char *udata = skb->data + 1;
183 signed char *sdata = skb->data + 1;
184 int i, size = skb->len - 1;
185
186 switch (skb->data[0]) {
187 case 0x01: /* Keyboard report */
188 for (i = 0; i < 8; i++)
189 input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
190
191 /* If all the key codes have been set to 0x01, it means
192 * too many keys were pressed at the same time. */
193 if (!memcmp(udata + 2, hidp_mkeyspat, 6))
194 break;
195
196 for (i = 2; i < 8; i++) {
197 if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
198 if (hidp_keycode[keys[i]])
199 input_report_key(dev, hidp_keycode[keys[i]], 0);
200 else
201 BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
202 }
203
204 if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
205 if (hidp_keycode[udata[i]])
206 input_report_key(dev, hidp_keycode[udata[i]], 1);
207 else
208 BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
209 }
210 }
211
212 memcpy(keys, udata, 8);
213 break;
214
215 case 0x02: /* Mouse report */
216 input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
217 input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
218 input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
219 input_report_key(dev, BTN_SIDE, sdata[0] & 0x08);
220 input_report_key(dev, BTN_EXTRA, sdata[0] & 0x10);
221
222 input_report_rel(dev, REL_X, sdata[1]);
223 input_report_rel(dev, REL_Y, sdata[2]);
224
225 if (size > 3)
226 input_report_rel(dev, REL_WHEEL, sdata[3]);
227 break;
228 }
229
230 input_sync(dev);
231}
232
Bastien Nocera6bf82682010-01-20 12:00:42 +0000233static int __hidp_send_ctrl_message(struct hidp_session *session,
Gustavo Padovan1d0c4da2012-06-09 19:22:42 -0300234 unsigned char hdr, unsigned char *data,
235 int size)
Bastien Nocera6bf82682010-01-20 12:00:42 +0000236{
237 struct sk_buff *skb;
238
239 BT_DBG("session %p data %p size %d", session, data, size);
240
David Herrmann794d1752011-08-26 14:06:02 +0200241 if (atomic_read(&session->terminate))
242 return -EIO;
243
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200244 skb = alloc_skb(size + 1, GFP_ATOMIC);
245 if (!skb) {
Bastien Nocera6bf82682010-01-20 12:00:42 +0000246 BT_ERR("Can't allocate memory for new frame");
247 return -ENOMEM;
248 }
249
250 *skb_put(skb, 1) = hdr;
251 if (data && size > 0)
252 memcpy(skb_put(skb, size), data, size);
253
254 skb_queue_tail(&session->ctrl_transmit, skb);
255
256 return 0;
257}
258
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300259static int hidp_send_ctrl_message(struct hidp_session *session,
Bastien Nocera6bf82682010-01-20 12:00:42 +0000260 unsigned char hdr, unsigned char *data, int size)
261{
262 int err;
263
264 err = __hidp_send_ctrl_message(session, hdr, data, size);
265
266 hidp_schedule(session);
267
268 return err;
269}
270
Andrew Morton91f5cca2008-02-05 03:07:58 -0800271static int hidp_queue_report(struct hidp_session *session,
272 unsigned char *data, int size)
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100273{
274 struct sk_buff *skb;
275
Dave Young6792b5e2007-10-20 14:15:39 +0200276 BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100277
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200278 skb = alloc_skb(size + 1, GFP_ATOMIC);
279 if (!skb) {
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100280 BT_ERR("Can't allocate memory for new frame");
281 return -ENOMEM;
282 }
283
284 *skb_put(skb, 1) = 0xa2;
285 if (size > 0)
286 memcpy(skb_put(skb, size), data, size);
287
288 skb_queue_tail(&session->intr_transmit, skb);
289
290 hidp_schedule(session);
291
292 return 0;
293}
294
295static int hidp_send_report(struct hidp_session *session, struct hid_report *report)
296{
297 unsigned char buf[32];
298 int rsize;
299
300 rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0);
301 if (rsize > sizeof(buf))
302 return -EIO;
303
304 hid_output_report(report, buf);
305
306 return hidp_queue_report(session, buf, rsize);
307}
308
Alan Ott0ff17312011-01-18 03:04:40 -0500309static int hidp_get_raw_report(struct hid_device *hid,
310 unsigned char report_number,
311 unsigned char *data, size_t count,
Jiri Kosinad4bfa032010-01-29 15:03:36 +0100312 unsigned char report_type)
Jiri Kosina2da31932009-11-26 16:20:56 +0100313{
Alan Ott0ff17312011-01-18 03:04:40 -0500314 struct hidp_session *session = hid->driver_data;
315 struct sk_buff *skb;
316 size_t len;
317 int numbered_reports = hid->report_enum[report_type].numbered;
David Herrmann794d1752011-08-26 14:06:02 +0200318 int ret;
Alan Ott0ff17312011-01-18 03:04:40 -0500319
Karl Reltonfd86c9b2013-02-20 18:16:19 +0000320 if (atomic_read(&session->terminate))
321 return -EIO;
322
Jiri Kosinad4bfa032010-01-29 15:03:36 +0100323 switch (report_type) {
324 case HID_FEATURE_REPORT:
Alan Ott0ff17312011-01-18 03:04:40 -0500325 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
326 break;
327 case HID_INPUT_REPORT:
328 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_INPUT;
Jiri Kosinad4bfa032010-01-29 15:03:36 +0100329 break;
330 case HID_OUTPUT_REPORT:
Alan Ott0ff17312011-01-18 03:04:40 -0500331 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_OUPUT;
Jiri Kosinad4bfa032010-01-29 15:03:36 +0100332 break;
333 default:
334 return -EINVAL;
335 }
336
Alan Ott0ff17312011-01-18 03:04:40 -0500337 if (mutex_lock_interruptible(&session->report_mutex))
338 return -ERESTARTSYS;
339
340 /* Set up our wait, and send the report request to the device. */
341 session->waiting_report_type = report_type & HIDP_DATA_RTYPE_MASK;
342 session->waiting_report_number = numbered_reports ? report_number : -1;
343 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
344 data[0] = report_number;
David Herrmann794d1752011-08-26 14:06:02 +0200345 ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 1);
346 if (ret)
347 goto err;
Alan Ott0ff17312011-01-18 03:04:40 -0500348
349 /* Wait for the return of the report. The returned report
350 gets put in session->report_return. */
David Herrmanne3492dc2013-04-06 20:28:41 +0200351 while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) &&
352 !atomic_read(&session->terminate)) {
Alan Ott0ff17312011-01-18 03:04:40 -0500353 int res;
354
355 res = wait_event_interruptible_timeout(session->report_queue,
David Herrmanne3492dc2013-04-06 20:28:41 +0200356 !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)
357 || atomic_read(&session->terminate),
Alan Ott0ff17312011-01-18 03:04:40 -0500358 5*HZ);
359 if (res == 0) {
360 /* timeout */
David Herrmann794d1752011-08-26 14:06:02 +0200361 ret = -EIO;
362 goto err;
Alan Ott0ff17312011-01-18 03:04:40 -0500363 }
364 if (res < 0) {
365 /* signal */
David Herrmann794d1752011-08-26 14:06:02 +0200366 ret = -ERESTARTSYS;
367 goto err;
Alan Ott0ff17312011-01-18 03:04:40 -0500368 }
369 }
370
371 skb = session->report_return;
372 if (skb) {
373 len = skb->len < count ? skb->len : count;
374 memcpy(data, skb->data, len);
375
376 kfree_skb(skb);
377 session->report_return = NULL;
378 } else {
379 /* Device returned a HANDSHAKE, indicating protocol error. */
380 len = -EIO;
381 }
382
383 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
384 mutex_unlock(&session->report_mutex);
385
386 return len;
387
David Herrmann794d1752011-08-26 14:06:02 +0200388err:
Alan Ott0ff17312011-01-18 03:04:40 -0500389 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
390 mutex_unlock(&session->report_mutex);
David Herrmann794d1752011-08-26 14:06:02 +0200391 return ret;
Alan Ott0ff17312011-01-18 03:04:40 -0500392}
393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
Jiri Kosina2da31932009-11-26 16:20:56 +0100395 unsigned char report_type)
396{
Alan Ott08254112011-01-18 03:04:38 -0500397 struct hidp_session *session = hid->driver_data;
398 int ret;
399
Jiri Kosinad4bfa032010-01-29 15:03:36 +0100400 switch (report_type) {
401 case HID_FEATURE_REPORT:
402 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
403 break;
404 case HID_OUTPUT_REPORT:
Antonio Ospite97e1efb2011-02-20 18:26:46 +0100405 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
Jiri Kosinad4bfa032010-01-29 15:03:36 +0100406 break;
407 default:
408 return -EINVAL;
409 }
410
Alan Ott08254112011-01-18 03:04:38 -0500411 if (mutex_lock_interruptible(&session->report_mutex))
412 return -ERESTARTSYS;
413
414 /* Set up our wait, and send the report request to the device. */
415 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
David Herrmann794d1752011-08-26 14:06:02 +0200416 ret = hidp_send_ctrl_message(hid->driver_data, report_type, data,
417 count);
418 if (ret)
Alan Ott08254112011-01-18 03:04:38 -0500419 goto err;
Alan Ott08254112011-01-18 03:04:38 -0500420
421 /* Wait for the ACK from the device. */
David Herrmanne3492dc2013-04-06 20:28:41 +0200422 while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) &&
423 !atomic_read(&session->terminate)) {
Alan Ott08254112011-01-18 03:04:38 -0500424 int res;
425
426 res = wait_event_interruptible_timeout(session->report_queue,
David Herrmanne3492dc2013-04-06 20:28:41 +0200427 !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)
428 || atomic_read(&session->terminate),
Alan Ott08254112011-01-18 03:04:38 -0500429 10*HZ);
430 if (res == 0) {
431 /* timeout */
432 ret = -EIO;
433 goto err;
434 }
435 if (res < 0) {
436 /* signal */
437 ret = -ERESTARTSYS;
438 goto err;
439 }
440 }
441
442 if (!session->output_report_success) {
443 ret = -EIO;
444 goto err;
445 }
446
447 ret = count;
448
449err:
450 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
451 mutex_unlock(&session->report_mutex);
452 return ret;
Jiri Kosina2da31932009-11-26 16:20:56 +0100453}
454
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455static void hidp_idle_timeout(unsigned long arg)
456{
457 struct hidp_session *session = (struct hidp_session *) arg;
458
Peter Hurley7bb59df2011-06-30 13:53:53 -0400459 atomic_inc(&session->terminate);
460 wake_up_process(session->task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461}
462
Andrew Morton91f5cca2008-02-05 03:07:58 -0800463static void hidp_set_timer(struct hidp_session *session)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464{
465 if (session->idle_to > 0)
466 mod_timer(&session->timer, jiffies + HZ * session->idle_to);
467}
468
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300469static void hidp_del_timer(struct hidp_session *session)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470{
471 if (session->idle_to > 0)
472 del_timer(&session->timer);
473}
474
Andrew Morton91f5cca2008-02-05 03:07:58 -0800475static void hidp_process_handshake(struct hidp_session *session,
476 unsigned char param)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477{
478 BT_DBG("session %p param 0x%02x", session, param);
Alan Ott08254112011-01-18 03:04:38 -0500479 session->output_report_success = 0; /* default condition */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481 switch (param) {
482 case HIDP_HSHK_SUCCESSFUL:
483 /* FIXME: Call into SET_ GET_ handlers here */
Alan Ott08254112011-01-18 03:04:38 -0500484 session->output_report_success = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 break;
486
487 case HIDP_HSHK_NOT_READY:
488 case HIDP_HSHK_ERR_INVALID_REPORT_ID:
489 case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
490 case HIDP_HSHK_ERR_INVALID_PARAMETER:
Gustavo F. Padovanab88f712011-10-06 22:05:37 -0300491 if (test_and_clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags))
Alan Ott0ff17312011-01-18 03:04:40 -0500492 wake_up_interruptible(&session->report_queue);
Gustavo F. Padovanab88f712011-10-06 22:05:37 -0300493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 /* FIXME: Call into SET_ GET_ handlers here */
495 break;
496
497 case HIDP_HSHK_ERR_UNKNOWN:
498 break;
499
500 case HIDP_HSHK_ERR_FATAL:
501 /* Device requests a reboot, as this is the only way this error
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900502 * can be recovered. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 __hidp_send_ctrl_message(session,
504 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
505 break;
506
507 default:
508 __hidp_send_ctrl_message(session,
509 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
510 break;
511 }
Alan Ott08254112011-01-18 03:04:38 -0500512
513 /* Wake up the waiting thread. */
Gustavo F. Padovanab88f712011-10-06 22:05:37 -0300514 if (test_and_clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags))
Alan Ott08254112011-01-18 03:04:38 -0500515 wake_up_interruptible(&session->report_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516}
517
Andrew Morton91f5cca2008-02-05 03:07:58 -0800518static void hidp_process_hid_control(struct hidp_session *session,
519 unsigned char param)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
521 BT_DBG("session %p param 0x%02x", session, param);
522
Dave Youngeff001e2008-02-05 03:07:14 -0800523 if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 /* Flush the transmit queues */
525 skb_queue_purge(&session->ctrl_transmit);
526 skb_queue_purge(&session->intr_transmit);
527
Peter Hurley7bb59df2011-06-30 13:53:53 -0400528 atomic_inc(&session->terminate);
529 wake_up_process(current);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 }
531}
532
Alan Ott0ff17312011-01-18 03:04:40 -0500533/* Returns true if the passed-in skb should be freed by the caller. */
534static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
Andrew Morton91f5cca2008-02-05 03:07:58 -0800535 unsigned char param)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536{
Alan Ott0ff17312011-01-18 03:04:40 -0500537 int done_with_skb = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
539
540 switch (param) {
541 case HIDP_DATA_RTYPE_INPUT:
542 hidp_set_timer(session);
543
544 if (session->input)
545 hidp_input_report(session, skb);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100546
547 if (session->hid)
548 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 break;
550
551 case HIDP_DATA_RTYPE_OTHER:
552 case HIDP_DATA_RTYPE_OUPUT:
553 case HIDP_DATA_RTYPE_FEATURE:
554 break;
555
556 default:
557 __hidp_send_ctrl_message(session,
558 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
559 }
Alan Ott0ff17312011-01-18 03:04:40 -0500560
561 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) &&
562 param == session->waiting_report_type) {
563 if (session->waiting_report_number < 0 ||
564 session->waiting_report_number == skb->data[0]) {
565 /* hidp_get_raw_report() is waiting on this report. */
566 session->report_return = skb;
567 done_with_skb = 0;
568 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
569 wake_up_interruptible(&session->report_queue);
570 }
571 }
572
573 return done_with_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574}
575
Andrew Morton91f5cca2008-02-05 03:07:58 -0800576static void hidp_recv_ctrl_frame(struct hidp_session *session,
577 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578{
579 unsigned char hdr, type, param;
Alan Ott0ff17312011-01-18 03:04:40 -0500580 int free_skb = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
582 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
583
584 hdr = skb->data[0];
585 skb_pull(skb, 1);
586
587 type = hdr & HIDP_HEADER_TRANS_MASK;
588 param = hdr & HIDP_HEADER_PARAM_MASK;
589
590 switch (type) {
591 case HIDP_TRANS_HANDSHAKE:
592 hidp_process_handshake(session, param);
593 break;
594
595 case HIDP_TRANS_HID_CONTROL:
596 hidp_process_hid_control(session, param);
597 break;
598
599 case HIDP_TRANS_DATA:
Alan Ott0ff17312011-01-18 03:04:40 -0500600 free_skb = hidp_process_data(session, skb, param);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 break;
602
603 default:
604 __hidp_send_ctrl_message(session,
605 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
606 break;
607 }
608
Alan Ott0ff17312011-01-18 03:04:40 -0500609 if (free_skb)
610 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611}
612
Andrew Morton91f5cca2008-02-05 03:07:58 -0800613static void hidp_recv_intr_frame(struct hidp_session *session,
614 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615{
616 unsigned char hdr;
617
618 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
619
620 hdr = skb->data[0];
621 skb_pull(skb, 1);
622
623 if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
624 hidp_set_timer(session);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 if (session->input)
627 hidp_input_report(session, skb);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100628
629 if (session->hid) {
630 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 1);
631 BT_DBG("report len %d", skb->len);
632 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 } else {
634 BT_DBG("Unsupported protocol header 0x%02x", hdr);
635 }
636
637 kfree_skb(skb);
638}
639
640static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
641{
642 struct kvec iv = { data, len };
643 struct msghdr msg;
644
645 BT_DBG("sock %p data %p len %d", sock, data, len);
646
647 if (!len)
648 return 0;
649
650 memset(&msg, 0, sizeof(msg));
651
652 return kernel_sendmsg(sock, &msg, &iv, 1, len);
653}
654
Gustavo F. Padovan679344e2011-10-06 20:51:37 -0300655static void hidp_process_intr_transmit(struct hidp_session *session)
656{
657 struct sk_buff *skb;
658
659 BT_DBG("session %p", session);
660
661 while ((skb = skb_dequeue(&session->intr_transmit))) {
662 if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
663 skb_queue_head(&session->intr_transmit, skb);
664 break;
665 }
666
667 hidp_set_timer(session);
668 kfree_skb(skb);
669 }
670}
671
672static void hidp_process_ctrl_transmit(struct hidp_session *session)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673{
674 struct sk_buff *skb;
675
676 BT_DBG("session %p", session);
677
678 while ((skb = skb_dequeue(&session->ctrl_transmit))) {
679 if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
680 skb_queue_head(&session->ctrl_transmit, skb);
681 break;
682 }
683
684 hidp_set_timer(session);
685 kfree_skb(skb);
686 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687}
688
689static int hidp_session(void *arg)
690{
691 struct hidp_session *session = arg;
692 struct sock *ctrl_sk = session->ctrl_sock->sk;
693 struct sock *intr_sk = session->intr_sock->sk;
694 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 wait_queue_t ctrl_wait, intr_wait;
696
697 BT_DBG("session %p", session);
698
David Herrmann25df0842011-11-01 17:27:50 +0100699 __module_get(THIS_MODULE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 set_user_nice(current, -15);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
702 init_waitqueue_entry(&ctrl_wait, current);
703 init_waitqueue_entry(&intr_wait, current);
Eric Dumazetaa395142010-04-20 13:03:51 +0000704 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
705 add_wait_queue(sk_sleep(intr_sk), &intr_wait);
Alan Ott0f69dca2011-01-18 03:04:37 -0500706 session->waiting_for_startup = 0;
707 wake_up_interruptible(&session->startup_queue);
Peter Hurley7bb59df2011-06-30 13:53:53 -0400708 set_current_state(TASK_INTERRUPTIBLE);
709 while (!atomic_read(&session->terminate)) {
Szymon Janc17f09a72011-03-21 14:20:01 +0100710 if (ctrl_sk->sk_state != BT_CONNECTED ||
711 intr_sk->sk_state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 break;
713
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
715 skb_orphan(skb);
Mat Martineau44935722011-07-22 14:53:58 -0700716 if (!skb_linearize(skb))
717 hidp_recv_intr_frame(session, skb);
718 else
719 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 }
721
Gustavo F. Padovan679344e2011-10-06 20:51:37 -0300722 hidp_process_intr_transmit(session);
723
Gustavo F. Padovandc0da5c2011-10-06 18:02:13 -0300724 while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
725 skb_orphan(skb);
726 if (!skb_linearize(skb))
727 hidp_recv_ctrl_frame(session, skb);
728 else
729 kfree_skb(skb);
730 }
731
Gustavo F. Padovan679344e2011-10-06 20:51:37 -0300732 hidp_process_ctrl_transmit(session);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
734 schedule();
Peter Hurley7bb59df2011-06-30 13:53:53 -0400735 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 }
737 set_current_state(TASK_RUNNING);
Karl Reltonfd86c9b2013-02-20 18:16:19 +0000738 atomic_inc(&session->terminate);
Eric Dumazetaa395142010-04-20 13:03:51 +0000739 remove_wait_queue(sk_sleep(intr_sk), &intr_wait);
740 remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
David Herrmann794d1752011-08-26 14:06:02 +0200742 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
743 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
744 wake_up_interruptible(&session->report_queue);
745
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 down_write(&hidp_session_sem);
747
748 hidp_del_timer(session);
749
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 if (session->input) {
751 input_unregister_device(session->input);
Dmitry Torokhov34abf912005-09-15 02:01:40 -0500752 session->input = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 }
754
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100755 if (session->hid) {
Jiri Slaby85cdaf52008-05-16 11:49:15 +0200756 hid_destroy_device(session->hid);
Marcel Holtmannedad6382009-08-22 14:22:15 -0700757 session->hid = NULL;
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100758 }
759
Marcel Holtmannec8dab32008-07-14 20:13:53 +0200760 /* Wakeup user-space polling for socket errors */
761 session->intr_sock->sk->sk_err = EUNATCH;
762 session->ctrl_sock->sk->sk_err = EUNATCH;
763
764 hidp_schedule(session);
765
David Woodhouse1c398582007-07-07 14:58:39 -0400766 fput(session->intr_sock->file);
767
Eric Dumazetaa395142010-04-20 13:03:51 +0000768 wait_event_timeout(*(sk_sleep(ctrl_sk)),
David Woodhouse1c398582007-07-07 14:58:39 -0400769 (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
770
771 fput(session->ctrl_sock->file);
772
David Herrmannfc225c32013-04-06 20:28:38 +0200773 list_del(&session->list);
David Woodhouse1c398582007-07-07 14:58:39 -0400774
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 up_write(&hidp_session_sem);
776
Peter Hurley1c97e942011-08-05 10:51:34 -0400777 kfree(session->rd_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 kfree(session);
David Herrmann25df0842011-11-01 17:27:50 +0100779 module_put_and_exit(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 return 0;
781}
782
Gustavo F. Padovan3e90dc82011-10-07 01:29:51 -0300783static struct hci_conn *hidp_get_connection(struct hidp_session *session)
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200784{
785 bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
786 bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
Peter Hurley1785dbf2011-08-30 11:53:35 -0400787 struct hci_conn *conn;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200788 struct hci_dev *hdev;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200789
790 hdev = hci_get_route(dst, src);
791 if (!hdev)
792 return NULL;
793
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300794 hci_dev_lock(hdev);
Peter Hurley1785dbf2011-08-30 11:53:35 -0400795 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300796 hci_dev_unlock(hdev);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200797
798 hci_dev_put(hdev);
799
Peter Hurley1785dbf2011-08-30 11:53:35 -0400800 return conn;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200801}
802
Andrew Morton91f5cca2008-02-05 03:07:58 -0800803static int hidp_setup_input(struct hidp_session *session,
804 struct hidp_connadd_req *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805{
Jiri Slabyc500c972008-05-16 11:49:16 +0200806 struct input_dev *input;
Gustavo F. Padovan3415a5f2011-10-06 21:17:32 -0300807 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
Jiri Slabyc500c972008-05-16 11:49:16 +0200809 input = input_allocate_device();
810 if (!input)
811 return -ENOMEM;
812
813 session->input = input;
814
Marcel Holtmann5be39462007-05-09 09:15:30 +0200815 input_set_drvdata(input, session);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816
Dmitry Torokhov34abf912005-09-15 02:01:40 -0500817 input->name = "Bluetooth HID Boot Protocol Device";
818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 input->id.bustype = BUS_BLUETOOTH;
820 input->id.vendor = req->vendor;
821 input->id.product = req->product;
822 input->id.version = req->version;
823
824 if (req->subclass & 0x40) {
825 set_bit(EV_KEY, input->evbit);
826 set_bit(EV_LED, input->evbit);
827 set_bit(EV_REP, input->evbit);
828
829 set_bit(LED_NUML, input->ledbit);
830 set_bit(LED_CAPSL, input->ledbit);
831 set_bit(LED_SCROLLL, input->ledbit);
832 set_bit(LED_COMPOSE, input->ledbit);
833 set_bit(LED_KANA, input->ledbit);
834
835 for (i = 0; i < sizeof(hidp_keycode); i++)
836 set_bit(hidp_keycode[i], input->keybit);
837 clear_bit(0, input->keybit);
838 }
839
840 if (req->subclass & 0x80) {
Jiri Slaby7b19ada2007-10-18 23:40:32 -0700841 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
842 input->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
843 BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
844 input->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
845 input->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
846 BIT_MASK(BTN_EXTRA);
847 input->relbit[0] |= BIT_MASK(REL_WHEEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 }
849
David Herrmannb4f34d82013-04-06 20:28:46 +0200850 input->dev.parent = &session->hconn->dev;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200851
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 input->event = hidp_input_event;
853
Marcel Holtmannedad6382009-08-22 14:22:15 -0700854 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855}
856
Marcel Holtmannf5ffd462007-02-17 23:58:53 +0100857static int hidp_open(struct hid_device *hid)
858{
859 return 0;
860}
861
862static void hidp_close(struct hid_device *hid)
863{
864}
865
Jiri Slabyc500c972008-05-16 11:49:16 +0200866static int hidp_parse(struct hid_device *hid)
867{
868 struct hidp_session *session = hid->driver_data;
Jiri Slabyc500c972008-05-16 11:49:16 +0200869
Michael Poole15c697c2010-02-05 12:23:43 -0500870 return hid_parse_report(session->hid, session->rd_data,
871 session->rd_size);
Jiri Slabyc500c972008-05-16 11:49:16 +0200872}
873
874static int hidp_start(struct hid_device *hid)
875{
876 struct hidp_session *session = hid->driver_data;
877 struct hid_report *report;
878
David Herrmann142c69c2011-08-26 13:27:12 +0200879 if (hid->quirks & HID_QUIRK_NO_INIT_REPORTS)
880 return 0;
881
Jiri Slabyc500c972008-05-16 11:49:16 +0200882 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].
883 report_list, list)
884 hidp_send_report(session, report);
885
886 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].
887 report_list, list)
888 hidp_send_report(session, report);
889
Jiri Slabyc500c972008-05-16 11:49:16 +0200890 return 0;
891}
892
893static void hidp_stop(struct hid_device *hid)
894{
895 struct hidp_session *session = hid->driver_data;
896
897 skb_queue_purge(&session->ctrl_transmit);
898 skb_queue_purge(&session->intr_transmit);
899
Jiri Slabyc500c972008-05-16 11:49:16 +0200900 hid->claimed = 0;
901}
902
903static struct hid_ll_driver hidp_hid_driver = {
904 .parse = hidp_parse,
905 .start = hidp_start,
906 .stop = hidp_stop,
907 .open = hidp_open,
908 .close = hidp_close,
909 .hidinput_input_event = hidp_hidinput_event,
910};
911
Alan Ott0f69dca2011-01-18 03:04:37 -0500912/* This function sets up the hid device. It does not add it
913 to the HID system. That is done in hidp_add_connection(). */
Jiri Slaby85cdaf52008-05-16 11:49:15 +0200914static int hidp_setup_hid(struct hidp_session *session,
Andrew Morton91f5cca2008-02-05 03:07:58 -0800915 struct hidp_connadd_req *req)
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100916{
Jiri Slabyc500c972008-05-16 11:49:16 +0200917 struct hid_device *hid;
Marcel Holtmannedad6382009-08-22 14:22:15 -0700918 int err;
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100919
Michael Poole15c697c2010-02-05 12:23:43 -0500920 session->rd_data = kzalloc(req->rd_size, GFP_KERNEL);
921 if (!session->rd_data)
922 return -ENOMEM;
923
924 if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) {
925 err = -EFAULT;
926 goto fault;
927 }
928 session->rd_size = req->rd_size;
929
Jiri Slabyc500c972008-05-16 11:49:16 +0200930 hid = hid_allocate_device();
Michael Poole15c697c2010-02-05 12:23:43 -0500931 if (IS_ERR(hid)) {
932 err = PTR_ERR(hid);
933 goto fault;
934 }
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100935
Jiri Slabyc500c972008-05-16 11:49:16 +0200936 session->hid = hid;
Michael Poole15c697c2010-02-05 12:23:43 -0500937
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100938 hid->driver_data = session;
939
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100940 hid->bus = BUS_BLUETOOTH;
941 hid->vendor = req->vendor;
942 hid->product = req->product;
943 hid->version = req->version;
Jiri Slabyc500c972008-05-16 11:49:16 +0200944 hid->country = req->country;
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100945
Anderson Lizardo0a9ab9b2013-01-06 18:28:53 -0400946 strncpy(hid->name, req->name, sizeof(req->name) - 1);
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +0300947
948 snprintf(hid->phys, sizeof(hid->phys), "%pMR",
949 &bt_sk(session->ctrl_sock->sk)->src);
950
951 snprintf(hid->uniq, sizeof(hid->uniq), "%pMR",
952 &bt_sk(session->ctrl_sock->sk)->dst);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100953
David Herrmannb4f34d82013-04-06 20:28:46 +0200954 hid->dev.parent = &session->hconn->dev;
Jiri Slabyc500c972008-05-16 11:49:16 +0200955 hid->ll_driver = &hidp_hid_driver;
Jiri Slaby85cdaf52008-05-16 11:49:15 +0200956
Alan Ott0ff17312011-01-18 03:04:40 -0500957 hid->hid_get_raw_report = hidp_get_raw_report;
Jiri Kosina2da31932009-11-26 16:20:56 +0100958 hid->hid_output_raw_report = hidp_output_raw_report;
959
Lamarque V. Souza4529eef2012-12-06 12:39:55 -0200960 /* True if device is blacklisted in drivers/hid/hid-core.c */
961 if (hid_ignore(hid)) {
962 hid_destroy_device(session->hid);
963 session->hid = NULL;
964 return -ENODEV;
965 }
966
Jiri Slabyc500c972008-05-16 11:49:16 +0200967 return 0;
Marcel Holtmannedad6382009-08-22 14:22:15 -0700968
Michael Poole15c697c2010-02-05 12:23:43 -0500969fault:
970 kfree(session->rd_data);
971 session->rd_data = NULL;
972
Marcel Holtmannedad6382009-08-22 14:22:15 -0700973 return err;
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +0100974}
975
David Herrmannb4f34d82013-04-06 20:28:46 +0200976/* initialize session devices */
977static int hidp_session_dev_init(struct hidp_session *session,
978 struct hidp_connadd_req *req)
979{
980 int ret;
981
982 if (req->rd_size > 0) {
983 ret = hidp_setup_hid(session, req);
984 if (ret && ret != -ENODEV)
985 return ret;
986 }
987
988 if (!session->hid) {
989 ret = hidp_setup_input(session, req);
990 if (ret < 0)
991 return ret;
992 }
993
994 return 0;
995}
996
997/* destroy session devices */
998static void hidp_session_dev_destroy(struct hidp_session *session)
999{
1000 if (session->hid)
1001 put_device(&session->hid->dev);
1002 else if (session->input)
1003 input_put_device(session->input);
1004
1005 kfree(session->rd_data);
1006 session->rd_data = NULL;
1007}
1008
1009/* add HID/input devices to their underlying bus systems */
1010static int hidp_session_dev_add(struct hidp_session *session)
1011{
1012 int ret;
1013
1014 /* Both HID and input systems drop a ref-count when unregistering the
1015 * device but they don't take a ref-count when registering them. Work
1016 * around this by explicitly taking a refcount during registration
1017 * which is dropped automatically by unregistering the devices. */
1018
1019 if (session->hid) {
1020 ret = hid_add_device(session->hid);
1021 if (ret)
1022 return ret;
1023 get_device(&session->hid->dev);
1024 } else if (session->input) {
1025 ret = input_register_device(session->input);
1026 if (ret)
1027 return ret;
1028 input_get_device(session->input);
1029 }
1030
1031 return 0;
1032}
1033
1034/* remove HID/input devices from their bus systems */
1035static void hidp_session_dev_del(struct hidp_session *session)
1036{
1037 if (session->hid)
1038 hid_destroy_device(session->hid);
1039 else if (session->input)
1040 input_unregister_device(session->input);
1041}
1042
1043/*
1044 * Create new session object
1045 * Allocate session object, initialize static fields, copy input data into the
1046 * object and take a reference to all sub-objects.
1047 * This returns 0 on success and puts a pointer to the new session object in
1048 * \out. Otherwise, an error code is returned.
1049 * The new session object has an initial ref-count of 1.
1050 */
1051static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr,
1052 struct socket *ctrl_sock,
1053 struct socket *intr_sock,
1054 struct hidp_connadd_req *req,
1055 struct l2cap_conn *conn)
1056{
1057 struct hidp_session *session;
1058 int ret;
1059 struct bt_sock *ctrl, *intr;
1060
1061 ctrl = bt_sk(ctrl_sock->sk);
1062 intr = bt_sk(intr_sock->sk);
1063
1064 session = kzalloc(sizeof(*session), GFP_KERNEL);
1065 if (!session)
1066 return -ENOMEM;
1067
1068 /* object and runtime management */
1069 kref_init(&session->ref);
1070 atomic_set(&session->state, HIDP_SESSION_IDLING);
1071 init_waitqueue_head(&session->state_queue);
1072 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
1073
1074 /* connection management */
1075 bacpy(&session->bdaddr, bdaddr);
1076 session->conn = conn;
1077 session->user.probe = hidp_session_probe;
1078 session->user.remove = hidp_session_remove;
1079 session->ctrl_sock = ctrl_sock;
1080 session->intr_sock = intr_sock;
1081 skb_queue_head_init(&session->ctrl_transmit);
1082 skb_queue_head_init(&session->intr_transmit);
1083 session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl)->chan->omtu,
1084 l2cap_pi(ctrl)->chan->imtu);
1085 session->intr_mtu = min_t(uint, l2cap_pi(intr)->chan->omtu,
1086 l2cap_pi(intr)->chan->imtu);
1087 session->idle_to = req->idle_to;
1088
1089 /* device management */
1090 setup_timer(&session->timer, hidp_idle_timeout,
1091 (unsigned long)session);
1092
1093 /* session data */
1094 mutex_init(&session->report_mutex);
1095 init_waitqueue_head(&session->report_queue);
1096
1097 ret = hidp_session_dev_init(session, req);
1098 if (ret)
1099 goto err_free;
1100
1101 l2cap_conn_get(session->conn);
1102 get_file(session->intr_sock->file);
1103 get_file(session->ctrl_sock->file);
1104 *out = session;
1105 return 0;
1106
1107err_free:
1108 kfree(session);
1109 return ret;
1110}
1111
1112/* increase ref-count of the given session by one */
1113static void hidp_session_get(struct hidp_session *session)
1114{
1115 kref_get(&session->ref);
1116}
1117
1118/* release callback */
1119static void session_free(struct kref *ref)
1120{
1121 struct hidp_session *session = container_of(ref, struct hidp_session,
1122 ref);
1123
1124 hidp_session_dev_destroy(session);
1125 skb_queue_purge(&session->ctrl_transmit);
1126 skb_queue_purge(&session->intr_transmit);
1127 fput(session->intr_sock->file);
1128 fput(session->ctrl_sock->file);
1129 l2cap_conn_put(session->conn);
1130 kfree(session);
1131}
1132
1133/* decrease ref-count of the given session by one */
1134static void hidp_session_put(struct hidp_session *session)
1135{
1136 kref_put(&session->ref, session_free);
1137}
1138
1139/*
1140 * Search the list of active sessions for a session with target address
1141 * \bdaddr. You must hold at least a read-lock on \hidp_session_sem. As long as
1142 * you do not release this lock, the session objects cannot vanish and you can
1143 * safely take a reference to the session yourself.
1144 */
1145static struct hidp_session *__hidp_session_find(const bdaddr_t *bdaddr)
1146{
1147 struct hidp_session *session;
1148
1149 list_for_each_entry(session, &hidp_session_list, list) {
1150 if (!bacmp(bdaddr, &session->bdaddr))
1151 return session;
1152 }
1153
1154 return NULL;
1155}
1156
1157/*
1158 * Same as __hidp_session_find() but no locks must be held. This also takes a
1159 * reference of the returned session (if non-NULL) so you must drop this
1160 * reference if you no longer use the object.
1161 */
1162static struct hidp_session *hidp_session_find(const bdaddr_t *bdaddr)
1163{
1164 struct hidp_session *session;
1165
1166 down_read(&hidp_session_sem);
1167
1168 session = __hidp_session_find(bdaddr);
1169 if (session)
1170 hidp_session_get(session);
1171
1172 up_read(&hidp_session_sem);
1173
1174 return session;
1175}
1176
1177/*
1178 * Start session synchronously
1179 * This starts a session thread and waits until initialization
1180 * is done or returns an error if it couldn't be started.
1181 * If this returns 0 the session thread is up and running. You must call
1182 * hipd_session_stop_sync() before deleting any runtime resources.
1183 */
1184static int hidp_session_start_sync(struct hidp_session *session)
1185{
1186 unsigned int vendor, product;
1187
1188 if (session->hid) {
1189 vendor = session->hid->vendor;
1190 product = session->hid->product;
1191 } else if (session->input) {
1192 vendor = session->input->id.vendor;
1193 product = session->input->id.product;
1194 } else {
1195 vendor = 0x0000;
1196 product = 0x0000;
1197 }
1198
1199 session->task = kthread_run(hidp_session_thread, session,
1200 "khidpd_%04x%04x", vendor, product);
1201 if (IS_ERR(session->task))
1202 return PTR_ERR(session->task);
1203
1204 while (atomic_read(&session->state) <= HIDP_SESSION_IDLING)
1205 wait_event(session->state_queue,
1206 atomic_read(&session->state) > HIDP_SESSION_IDLING);
1207
1208 return 0;
1209}
1210
1211/*
1212 * Terminate session thread
1213 * Wake up session thread and notify it to stop. This is asynchronous and
1214 * returns immediately. Call this whenever a runtime error occurs and you want
1215 * the session to stop.
1216 * Note: wake_up_process() performs any necessary memory-barriers for us.
1217 */
1218static void hidp_session_terminate(struct hidp_session *session)
1219{
1220 atomic_inc(&session->terminate);
1221 wake_up_process(session->task);
1222}
1223
1224/*
1225 * Probe HIDP session
1226 * This is called from the l2cap_conn core when our l2cap_user object is bound
1227 * to the hci-connection. We get the session via the \user object and can now
1228 * start the session thread, register the HID/input devices and link it into
1229 * the global session list.
1230 * The global session-list owns its own reference to the session object so you
1231 * can drop your own reference after registering the l2cap_user object.
1232 */
1233static int hidp_session_probe(struct l2cap_conn *conn,
1234 struct l2cap_user *user)
1235{
1236 struct hidp_session *session = container_of(user,
1237 struct hidp_session,
1238 user);
1239 struct hidp_session *s;
1240 int ret;
1241
1242 down_write(&hidp_session_sem);
1243
1244 /* check that no other session for this device exists */
1245 s = __hidp_session_find(&session->bdaddr);
1246 if (s) {
1247 ret = -EEXIST;
1248 goto out_unlock;
1249 }
1250
1251 ret = hidp_session_start_sync(session);
1252 if (ret)
1253 goto out_unlock;
1254
1255 ret = hidp_session_dev_add(session);
1256 if (ret)
1257 goto out_stop;
1258
1259 hidp_session_get(session);
1260 list_add(&session->list, &hidp_session_list);
1261 ret = 0;
1262 goto out_unlock;
1263
1264out_stop:
1265 hidp_session_terminate(session);
1266out_unlock:
1267 up_write(&hidp_session_sem);
1268 return ret;
1269}
1270
1271/*
1272 * Remove HIDP session
1273 * Called from the l2cap_conn core when either we explicitly unregistered
1274 * the l2cap_user object or if the underlying connection is shut down.
1275 * We signal the hidp-session thread to shut down, unregister the HID/input
1276 * devices and unlink the session from the global list.
1277 * This drops the reference to the session that is owned by the global
1278 * session-list.
1279 * Note: We _must_ not synchronosly wait for the session-thread to shut down.
1280 * This is, because the session-thread might be waiting for an HCI lock that is
1281 * held while we are called. Therefore, we only unregister the devices and
1282 * notify the session-thread to terminate. The thread itself owns a reference
1283 * to the session object so it can safely shut down.
1284 */
1285static void hidp_session_remove(struct l2cap_conn *conn,
1286 struct l2cap_user *user)
1287{
1288 struct hidp_session *session = container_of(user,
1289 struct hidp_session,
1290 user);
1291
1292 down_write(&hidp_session_sem);
1293
1294 hidp_session_terminate(session);
1295 hidp_session_dev_del(session);
1296 list_del(&session->list);
1297
1298 up_write(&hidp_session_sem);
1299
1300 hidp_session_put(session);
1301}
1302
1303/*
1304 * Session Worker
1305 * This performs the actual main-loop of the HIDP worker. We first check
1306 * whether the underlying connection is still alive, then parse all pending
1307 * messages and finally send all outstanding messages.
1308 */
1309static void hidp_session_run(struct hidp_session *session)
1310{
1311 struct sock *ctrl_sk = session->ctrl_sock->sk;
1312 struct sock *intr_sk = session->intr_sock->sk;
1313 struct sk_buff *skb;
1314
1315 for (;;) {
1316 /*
1317 * This thread can be woken up two ways:
1318 * - You call hidp_session_terminate() which sets the
1319 * session->terminate flag and wakes this thread up.
1320 * - Via modifying the socket state of ctrl/intr_sock. This
1321 * thread is woken up by ->sk_state_changed().
1322 *
1323 * Note: set_current_state() performs any necessary
1324 * memory-barriers for us.
1325 */
1326 set_current_state(TASK_INTERRUPTIBLE);
1327
1328 if (atomic_read(&session->terminate))
1329 break;
1330
1331 if (ctrl_sk->sk_state != BT_CONNECTED ||
1332 intr_sk->sk_state != BT_CONNECTED)
1333 break;
1334
1335 /* parse incoming intr-skbs */
1336 while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
1337 skb_orphan(skb);
1338 if (!skb_linearize(skb))
1339 hidp_recv_intr_frame(session, skb);
1340 else
1341 kfree_skb(skb);
1342 }
1343
1344 /* send pending intr-skbs */
1345 hidp_process_intr_transmit(session);
1346
1347 /* parse incoming ctrl-skbs */
1348 while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
1349 skb_orphan(skb);
1350 if (!skb_linearize(skb))
1351 hidp_recv_ctrl_frame(session, skb);
1352 else
1353 kfree_skb(skb);
1354 }
1355
1356 /* send pending ctrl-skbs */
1357 hidp_process_ctrl_transmit(session);
1358
1359 schedule();
1360 }
1361
1362 atomic_inc(&session->terminate);
1363 set_current_state(TASK_RUNNING);
1364}
1365
1366/*
1367 * HIDP session thread
1368 * This thread runs the I/O for a single HIDP session. Startup is synchronous
1369 * which allows us to take references to ourself here instead of doing that in
1370 * the caller.
1371 * When we are ready to run we notify the caller and call hidp_session_run().
1372 */
1373static int hidp_session_thread(void *arg)
1374{
1375 struct hidp_session *session = arg;
1376 wait_queue_t ctrl_wait, intr_wait;
1377
1378 BT_DBG("session %p", session);
1379
1380 /* initialize runtime environment */
1381 hidp_session_get(session);
1382 __module_get(THIS_MODULE);
1383 set_user_nice(current, -15);
1384 hidp_set_timer(session);
1385
1386 init_waitqueue_entry(&ctrl_wait, current);
1387 init_waitqueue_entry(&intr_wait, current);
1388 add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait);
1389 add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait);
1390 /* This memory barrier is paired with wq_has_sleeper(). See
1391 * sock_poll_wait() for more information why this is needed. */
1392 smp_mb();
1393
1394 /* notify synchronous startup that we're ready */
1395 atomic_inc(&session->state);
1396 wake_up(&session->state_queue);
1397
1398 /* run session */
1399 hidp_session_run(session);
1400
1401 /* cleanup runtime environment */
1402 remove_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait);
1403 remove_wait_queue(sk_sleep(session->intr_sock->sk), &ctrl_wait);
1404 wake_up_interruptible(&session->report_queue);
1405 hidp_del_timer(session);
1406
1407 /*
1408 * If we stopped ourself due to any internal signal, we should try to
1409 * unregister our own session here to avoid having it linger until the
1410 * parent l2cap_conn dies or user-space cleans it up.
1411 * This does not deadlock as we don't do any synchronous shutdown.
1412 * Instead, this call has the same semantics as if user-space tried to
1413 * delete the session.
1414 */
1415 l2cap_unregister_user(session->conn, &session->user);
1416 hidp_session_put(session);
1417
1418 module_put_and_exit(0);
1419 return 0;
1420}
1421
1422static int hidp_verify_sockets(struct socket *ctrl_sock,
1423 struct socket *intr_sock)
1424{
1425 struct bt_sock *ctrl, *intr;
1426 struct hidp_session *session;
1427
1428 if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock))
1429 return -EINVAL;
1430
1431 ctrl = bt_sk(ctrl_sock->sk);
1432 intr = bt_sk(intr_sock->sk);
1433
1434 if (bacmp(&ctrl->src, &intr->src) || bacmp(&ctrl->dst, &intr->dst))
1435 return -ENOTUNIQ;
1436 if (ctrl->sk.sk_state != BT_CONNECTED ||
1437 intr->sk.sk_state != BT_CONNECTED)
1438 return -EBADFD;
1439
1440 /* early session check, we check again during session registration */
1441 session = hidp_session_find(&ctrl->dst);
1442 if (session) {
1443 hidp_session_put(session);
1444 return -EEXIST;
1445 }
1446
1447 return 0;
1448}
1449
1450int hidp_connection_add(struct hidp_connadd_req *req,
1451 struct socket *ctrl_sock,
1452 struct socket *intr_sock)
1453{
1454 struct hidp_session *session;
1455 struct l2cap_conn *conn;
1456 struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan;
1457 int ret;
1458
1459 ret = hidp_verify_sockets(ctrl_sock, intr_sock);
1460 if (ret)
1461 return ret;
1462
1463 conn = NULL;
1464 l2cap_chan_lock(chan);
1465 if (chan->conn) {
1466 l2cap_conn_get(chan->conn);
1467 conn = chan->conn;
1468 }
1469 l2cap_chan_unlock(chan);
1470
1471 if (!conn)
1472 return -EBADFD;
1473
1474 ret = hidp_session_new(&session, &bt_sk(ctrl_sock->sk)->dst, ctrl_sock,
1475 intr_sock, req, conn);
1476 if (ret)
1477 goto out_conn;
1478
1479 ret = l2cap_register_user(conn, &session->user);
1480 if (ret)
1481 goto out_session;
1482
1483 ret = 0;
1484
1485out_session:
1486 hidp_session_put(session);
1487out_conn:
1488 l2cap_conn_put(conn);
1489 return ret;
1490}
1491
1492int hidp_connection_del(struct hidp_conndel_req *req)
1493{
1494 struct hidp_session *session;
1495
1496 session = hidp_session_find(&req->bdaddr);
1497 if (!session)
1498 return -ENOENT;
1499
1500 if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG))
1501 hidp_send_ctrl_message(session,
1502 HIDP_TRANS_HID_CONTROL |
1503 HIDP_CTRL_VIRTUAL_CABLE_UNPLUG,
1504 NULL, 0);
1505 else
1506 l2cap_unregister_user(session->conn, &session->user);
1507
1508 hidp_session_put(session);
1509
1510 return 0;
1511}
1512
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
1514{
1515 struct hidp_session *session, *s;
Szymon Jancaabf6f82011-04-05 15:37:45 +02001516 int vendor, product;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 int err;
1518
1519 BT_DBG("");
1520
David Herrmannb3916db2013-04-05 14:57:34 +02001521 if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock))
1522 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||
1524 bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))
1525 return -ENOTUNIQ;
1526
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +01001527 BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size);
1528
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 down_write(&hidp_session_sem);
1530
1531 s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);
David Herrmanndcc07642013-04-06 20:28:40 +02001532 if (s) {
Gustavo F. Padovan81b25cd2011-10-06 23:32:29 -03001533 up_write(&hidp_session_sem);
1534 return -EEXIST;
1535 }
1536
1537 session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL);
1538 if (!session) {
1539 up_write(&hidp_session_sem);
1540 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 }
1542
1543 bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
1544
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001545 session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->chan->omtu,
1546 l2cap_pi(ctrl_sock->sk)->chan->imtu);
1547 session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->chan->omtu,
1548 l2cap_pi(intr_sock->sk)->chan->imtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
1550 BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
1551
1552 session->ctrl_sock = ctrl_sock;
1553 session->intr_sock = intr_sock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
David Herrmannb4f34d82013-04-06 20:28:46 +02001555 session->hconn = hidp_get_connection(session);
1556 if (!session->hconn) {
Gustavo F. Padovan3c32fa92011-10-20 17:21:34 -02001557 err = -ENOTCONN;
1558 goto failed;
1559 }
1560
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -08001561 setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
1563 skb_queue_head_init(&session->ctrl_transmit);
1564 skb_queue_head_init(&session->intr_transmit);
1565
Alan Ott0ff17312011-01-18 03:04:40 -05001566 mutex_init(&session->report_mutex);
1567 init_waitqueue_head(&session->report_queue);
Alan Ott0f69dca2011-01-18 03:04:37 -05001568 init_waitqueue_head(&session->startup_queue);
1569 session->waiting_for_startup = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
1571 session->idle_to = req->idle_to;
1572
David Herrmannfc225c32013-04-06 20:28:38 +02001573 list_add(&session->list, &hidp_session_list);
Peter Hurley1785dbf2011-08-30 11:53:35 -04001574
Jiri Slabyc500c972008-05-16 11:49:16 +02001575 if (req->rd_size > 0) {
Jiri Slaby85cdaf52008-05-16 11:49:15 +02001576 err = hidp_setup_hid(session, req);
Lamarque V. Souza4529eef2012-12-06 12:39:55 -02001577 if (err && err != -ENODEV)
Marcel Holtmannedad6382009-08-22 14:22:15 -07001578 goto purge;
Jiri Slabyc500c972008-05-16 11:49:16 +02001579 }
1580
1581 if (!session->hid) {
1582 err = hidp_setup_input(session, req);
1583 if (err < 0)
Marcel Holtmannedad6382009-08-22 14:22:15 -07001584 goto purge;
Jiri Slaby85cdaf52008-05-16 11:49:15 +02001585 }
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +01001586
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 hidp_set_timer(session);
1588
Szymon Jancaabf6f82011-04-05 15:37:45 +02001589 if (session->hid) {
1590 vendor = session->hid->vendor;
1591 product = session->hid->product;
1592 } else if (session->input) {
1593 vendor = session->input->id.vendor;
1594 product = session->input->id.product;
1595 } else {
1596 vendor = 0x0000;
1597 product = 0x0000;
1598 }
1599
1600 session->task = kthread_run(hidp_session, session, "khidpd_%04x%04x",
1601 vendor, product);
1602 if (IS_ERR(session->task)) {
1603 err = PTR_ERR(session->task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 goto unlink;
Szymon Jancaabf6f82011-04-05 15:37:45 +02001605 }
1606
Alan Ott0f69dca2011-01-18 03:04:37 -05001607 while (session->waiting_for_startup) {
1608 wait_event_interruptible(session->startup_queue,
1609 !session->waiting_for_startup);
1610 }
1611
Gustavo F. Padovan3415a5f2011-10-06 21:17:32 -03001612 if (session->hid)
1613 err = hid_add_device(session->hid);
1614 else
1615 err = input_register_device(session->input);
1616
Peter Hurleye9d5cb52011-08-05 10:51:26 -04001617 if (err < 0) {
1618 atomic_inc(&session->terminate);
1619 wake_up_process(session->task);
1620 up_write(&hidp_session_sem);
1621 return err;
1622 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
1624 if (session->input) {
1625 hidp_send_ctrl_message(session,
1626 HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
1627 session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
1628
1629 session->leds = 0xff;
1630 hidp_input_event(session->input, EV_LED, 0, 0);
1631 }
1632
1633 up_write(&hidp_session_sem);
1634 return 0;
1635
1636unlink:
1637 hidp_del_timer(session);
1638
Marcel Holtmannedad6382009-08-22 14:22:15 -07001639 if (session->input) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 input_unregister_device(session->input);
Marcel Holtmannedad6382009-08-22 14:22:15 -07001641 session->input = NULL;
1642 }
1643
1644 if (session->hid) {
Jiri Slaby85cdaf52008-05-16 11:49:15 +02001645 hid_destroy_device(session->hid);
Marcel Holtmannedad6382009-08-22 14:22:15 -07001646 session->hid = NULL;
1647 }
1648
Michael Poole15c697c2010-02-05 12:23:43 -05001649 kfree(session->rd_data);
1650 session->rd_data = NULL;
1651
Marcel Holtmannedad6382009-08-22 14:22:15 -07001652purge:
David Herrmannfc225c32013-04-06 20:28:38 +02001653 list_del(&session->list);
Peter Hurley1785dbf2011-08-30 11:53:35 -04001654
Jiri Slabyc500c972008-05-16 11:49:16 +02001655 skb_queue_purge(&session->ctrl_transmit);
1656 skb_queue_purge(&session->intr_transmit);
Marcel Holtmannedad6382009-08-22 14:22:15 -07001657
Jiri Slabyc500c972008-05-16 11:49:16 +02001658failed:
1659 up_write(&hidp_session_sem);
Marcel Holtmanne1aaadd2007-02-17 23:58:49 +01001660
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 kfree(session);
1662 return err;
1663}
1664
1665int hidp_del_connection(struct hidp_conndel_req *req)
1666{
1667 struct hidp_session *session;
1668 int err = 0;
1669
1670 BT_DBG("");
1671
1672 down_read(&hidp_session_sem);
1673
1674 session = __hidp_get_session(&req->bdaddr);
1675 if (session) {
1676 if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
1677 hidp_send_ctrl_message(session,
1678 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
1679 } else {
1680 /* Flush the transmit queues */
1681 skb_queue_purge(&session->ctrl_transmit);
1682 skb_queue_purge(&session->intr_transmit);
1683
Peter Hurley7bb59df2011-06-30 13:53:53 -04001684 atomic_inc(&session->terminate);
1685 wake_up_process(session->task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 }
1687 } else
1688 err = -ENOENT;
1689
1690 up_read(&hidp_session_sem);
1691 return err;
1692}
1693
1694int hidp_get_connlist(struct hidp_connlist_req *req)
1695{
Gustavo F. Padovancd11cdd2011-10-06 17:35:31 -03001696 struct hidp_session *session;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 int err = 0, n = 0;
1698
1699 BT_DBG("");
1700
1701 down_read(&hidp_session_sem);
1702
Gustavo F. Padovancd11cdd2011-10-06 17:35:31 -03001703 list_for_each_entry(session, &hidp_session_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 struct hidp_conninfo ci;
1705
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 __hidp_copy_session(session, &ci);
1707
1708 if (copy_to_user(req->ci, &ci, sizeof(ci))) {
1709 err = -EFAULT;
1710 break;
1711 }
1712
1713 if (++n >= req->cnum)
1714 break;
1715
1716 req->ci++;
1717 }
1718 req->cnum = n;
1719
1720 up_read(&hidp_session_sem);
1721 return err;
1722}
1723
1724int hidp_get_conninfo(struct hidp_conninfo *ci)
1725{
1726 struct hidp_session *session;
1727 int err = 0;
1728
1729 down_read(&hidp_session_sem);
1730
1731 session = __hidp_get_session(&ci->bdaddr);
1732 if (session)
1733 __hidp_copy_session(session, ci);
1734 else
1735 err = -ENOENT;
1736
1737 up_read(&hidp_session_sem);
1738 return err;
1739}
1740
1741static int __init hidp_init(void)
1742{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
1744
Henrik Rydberg8215d552012-04-23 12:07:07 +02001745 return hidp_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746}
1747
1748static void __exit hidp_exit(void)
1749{
1750 hidp_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751}
1752
1753module_init(hidp_init);
1754module_exit(hidp_exit);
1755
1756MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
David Herrmannb4f34d82013-04-06 20:28:46 +02001757MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
1759MODULE_VERSION(VERSION);
1760MODULE_LICENSE("GPL");
1761MODULE_ALIAS("bt-proto-6");