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