hciops.c revision 65bf1321203b55b11167ac8b869da28a86ce49d2
1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 * 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include <config.h> 25#endif 26 27#include <stdio.h> 28#include <errno.h> 29#include <unistd.h> 30#include <stdlib.h> 31#include <sys/types.h> 32#include <sys/ioctl.h> 33#include <sys/wait.h> 34 35#include <bluetooth/bluetooth.h> 36#include <bluetooth/hci.h> 37#include <bluetooth/hci_lib.h> 38 39#include <glib.h> 40 41#include "hcid.h" 42#include "sdpd.h" 43#include "adapter.h" 44#include "plugin.h" 45#include "log.h" 46#include "manager.h" 47 48static int child_pipe[2] = { -1, -1 }; 49 50static guint child_io_id = 0; 51static guint ctl_io_id = 0; 52 53static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) 54{ 55 int status, fd = g_io_channel_unix_get_fd(io); 56 pid_t child_pid; 57 58 if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) { 59 error("child_exit: unable to read child pid from pipe"); 60 return TRUE; 61 } 62 63 if (waitpid(child_pid, &status, 0) != child_pid) 64 error("waitpid(%d) failed", child_pid); 65 else 66 DBG("child %d exited", child_pid); 67 68 return TRUE; 69} 70 71static void at_child_exit(void) 72{ 73 pid_t pid = getpid(); 74 75 if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid)) 76 error("unable to write to child pipe"); 77} 78 79static void device_devup_setup(int index) 80{ 81 struct hci_dev_info di; 82 uint16_t policy; 83 int dd, err; 84 85 if (hci_devinfo(index, &di) < 0) 86 return; 87 88 if (ignore_device(&di)) 89 return; 90 91 dd = hci_open_dev(index); 92 if (dd < 0) { 93 err = errno; 94 error("Can't open device hci%d: %s (%d)", 95 index, strerror(err), err); 96 return; 97 } 98 99 /* Set page timeout */ 100 if ((main_opts.flags & (1 << HCID_SET_PAGETO))) { 101 write_page_timeout_cp cp; 102 103 cp.timeout = htobs(main_opts.pageto); 104 hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, 105 WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); 106 } 107 108 /* Set default link policy */ 109 policy = htobs(main_opts.link_policy); 110 hci_send_cmd(dd, OGF_LINK_POLICY, 111 OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy); 112 113 hci_close_dev(dd); 114 115 start_security_manager(index); 116 117 /* Return value 1 means ioctl(DEVDOWN) was performed */ 118 if (manager_start_adapter(index) == 1) 119 stop_security_manager(index); 120} 121 122static void init_device(int index) 123{ 124 struct hci_dev_req dr; 125 struct hci_dev_info di; 126 pid_t pid; 127 int dd, err; 128 129 /* Do initialization in the separate process */ 130 pid = fork(); 131 switch (pid) { 132 case 0: 133 atexit(at_child_exit); 134 break; 135 case -1: 136 err = errno; 137 error("Fork failed. Can't init device hci%d: %s (%d)", 138 index, strerror(err), err); 139 default: 140 DBG("child %d forked", pid); 141 return; 142 } 143 144 dd = hci_open_dev(index); 145 if (dd < 0) { 146 err = errno; 147 error("Can't open device hci%d: %s (%d)", 148 index, strerror(err), err); 149 exit(1); 150 } 151 152 memset(&dr, 0, sizeof(dr)); 153 dr.dev_id = index; 154 155 /* Set link mode */ 156 dr.dev_opt = main_opts.link_mode; 157 if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) { 158 err = errno; 159 error("Can't set link mode on hci%d: %s (%d)", 160 index, strerror(err), err); 161 } 162 163 /* Set link policy for BR/EDR HCI devices */ 164 if (hci_devinfo(index, &di) < 0) 165 goto fail; 166 167 if (!ignore_device(&di)) { 168 dr.dev_opt = main_opts.link_policy; 169 if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 && 170 errno != ENETDOWN) { 171 error("Can't set link policy on hci%d: %s (%d)", 172 index, strerror(errno), errno); 173 } 174 } 175 176 /* Start HCI device */ 177 if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) { 178 error("Can't init device hci%d: %s (%d)", 179 index, strerror(errno), errno); 180 goto fail; 181 } 182 183 hci_close_dev(dd); 184 exit(0); 185 186fail: 187 hci_close_dev(dd); 188 exit(1); 189} 190 191static void device_devreg_setup(int index) 192{ 193 struct hci_dev_info di; 194 gboolean devup; 195 196 init_device(index); 197 198 memset(&di, 0, sizeof(di)); 199 200 if (hci_devinfo(index, &di) < 0) 201 return; 202 203 devup = hci_test_bit(HCI_UP, &di.flags); 204 205 if (!ignore_device(&di)) 206 manager_register_adapter(index, devup); 207} 208 209static void device_event(int event, int index) 210{ 211 switch (event) { 212 case HCI_DEV_REG: 213 info("HCI dev %d registered", index); 214 device_devreg_setup(index); 215 break; 216 217 case HCI_DEV_UNREG: 218 info("HCI dev %d unregistered", index); 219 manager_unregister_adapter(index); 220 break; 221 222 case HCI_DEV_UP: 223 info("HCI dev %d up", index); 224 device_devup_setup(index); 225 break; 226 227 case HCI_DEV_DOWN: 228 info("HCI dev %d down", index); 229 manager_stop_adapter(index); 230 stop_security_manager(index); 231 break; 232 } 233} 234 235static int init_known_adapters(int ctl) 236{ 237 struct hci_dev_list_req *dl; 238 struct hci_dev_req *dr; 239 int i, err; 240 241 dl = g_try_malloc0(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); 242 if (!dl) { 243 err = errno; 244 error("Can't allocate devlist buffer: %s (%d)", 245 strerror(err), err); 246 return -err; 247 } 248 249 dl->dev_num = HCI_MAX_DEV; 250 dr = dl->dev_req; 251 252 if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { 253 err = errno; 254 error("Can't get device list: %s (%d)", 255 strerror(err), err); 256 g_free(dl); 257 return -err; 258 } 259 260 for (i = 0; i < dl->dev_num; i++, dr++) { 261 device_event(HCI_DEV_REG, dr->dev_id); 262 263 if (hci_test_bit(HCI_UP, &dr->dev_opt)) 264 device_event(HCI_DEV_UP, dr->dev_id); 265 } 266 267 g_free(dl); 268 return 0; 269} 270 271static gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, 272 gpointer data) 273{ 274 unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; 275 evt_stack_internal *si; 276 evt_si_device *sd; 277 hci_event_hdr *eh; 278 int type; 279 size_t len; 280 GIOError err; 281 282 ptr = buf; 283 284 err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len); 285 if (err) { 286 if (err == G_IO_ERROR_AGAIN) 287 return TRUE; 288 289 error("Read from control socket failed: %s (%d)", 290 strerror(errno), errno); 291 return FALSE; 292 } 293 294 type = *ptr++; 295 296 if (type != HCI_EVENT_PKT) 297 return TRUE; 298 299 eh = (hci_event_hdr *) ptr; 300 if (eh->evt != EVT_STACK_INTERNAL) 301 return TRUE; 302 303 ptr += HCI_EVENT_HDR_SIZE; 304 305 si = (evt_stack_internal *) ptr; 306 switch (si->type) { 307 case EVT_SI_DEVICE: 308 sd = (void *) &si->data; 309 device_event(sd->event, sd->dev_id); 310 break; 311 } 312 313 return TRUE; 314} 315 316static int hciops_setup(void) 317{ 318 struct sockaddr_hci addr; 319 struct hci_filter flt; 320 GIOChannel *ctl_io, *child_io; 321 int sock, err; 322 323 if (child_pipe[0] != -1) 324 return -EALREADY; 325 326 if (pipe(child_pipe) < 0) { 327 err = errno; 328 error("pipe(): %s (%d)", strerror(err), err); 329 return -err; 330 } 331 332 child_io = g_io_channel_unix_new(child_pipe[0]); 333 g_io_channel_set_close_on_unref(child_io, TRUE); 334 child_io_id = g_io_add_watch(child_io, 335 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, 336 child_exit, NULL); 337 g_io_channel_unref(child_io); 338 339 /* Create and bind HCI socket */ 340 sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 341 if (sock < 0) { 342 err = errno; 343 error("Can't open HCI socket: %s (%d)", strerror(err), 344 err); 345 return -err; 346 } 347 348 /* Set filter */ 349 hci_filter_clear(&flt); 350 hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 351 hci_filter_set_event(EVT_STACK_INTERNAL, &flt); 352 if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, 353 sizeof(flt)) < 0) { 354 err = errno; 355 error("Can't set filter: %s (%d)", strerror(err), err); 356 return -err; 357 } 358 359 memset(&addr, 0, sizeof(addr)); 360 addr.hci_family = AF_BLUETOOTH; 361 addr.hci_dev = HCI_DEV_NONE; 362 if (bind(sock, (struct sockaddr *) &addr, 363 sizeof(addr)) < 0) { 364 err = errno; 365 error("Can't bind HCI socket: %s (%d)", 366 strerror(err), err); 367 return -err; 368 } 369 370 ctl_io = g_io_channel_unix_new(sock); 371 g_io_channel_set_close_on_unref(ctl_io, TRUE); 372 373 ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); 374 375 g_io_channel_unref(ctl_io); 376 377 /* Initialize already connected devices */ 378 return init_known_adapters(sock); 379} 380 381static void hciops_cleanup(void) 382{ 383 if (child_io_id) { 384 g_source_remove(child_io_id); 385 child_io_id = 0; 386 } 387 388 if (ctl_io_id) { 389 g_source_remove(ctl_io_id); 390 ctl_io_id = 0; 391 } 392 393 if (child_pipe[0] >= 0) { 394 close(child_pipe[0]); 395 child_pipe[0] = -1; 396 } 397 398 if (child_pipe[1] >= 0) { 399 close(child_pipe[1]); 400 child_pipe[1] = -1; 401 } 402} 403 404static int hciops_start(int index) 405{ 406 int dd; 407 int err = 0; 408 409 dd = hci_open_dev(index); 410 if (dd < 0) 411 return -EIO; 412 413 if (ioctl(dd, HCIDEVUP, index) == 0) 414 goto done; /* on success */ 415 416 if (errno != EALREADY) { 417 err = errno; 418 error("Can't init device hci%d: %s (%d)", 419 index, strerror(err), err); 420 } 421 422done: 423 hci_close_dev(dd); 424 return -err; 425} 426 427static int hciops_stop(int index) 428{ 429 int dd; 430 int err = 0; 431 432 dd = hci_open_dev(index); 433 if (dd < 0) 434 return -EIO; 435 436 if (ioctl(dd, HCIDEVDOWN, index) == 0) 437 goto done; /* on success */ 438 439 if (errno != EALREADY) { 440 err = errno; 441 error("Can't stop device hci%d: %s (%d)", 442 index, strerror(err), err); 443 } 444 445done: 446 hci_close_dev(dd); 447 return -err; 448} 449 450static int hciops_powered(int index, gboolean powered) 451{ 452 int dd, err; 453 uint8_t mode = SCAN_DISABLED; 454 455 if (powered) 456 return hciops_start(index); 457 458 dd = hci_open_dev(index); 459 if (dd < 0) 460 return -EIO; 461 462 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 463 1, &mode); 464 if (err < 0) { 465 err = -errno; 466 hci_close_dev(dd); 467 return err; 468 } 469 470 hci_close_dev(dd); 471 472 return hciops_stop(index); 473} 474 475static int hciops_connectable(int index) 476{ 477 int dd, err; 478 uint8_t mode = SCAN_PAGE; 479 480 dd = hci_open_dev(index); 481 if (dd < 0) 482 return -EIO; 483 484 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 485 1, &mode); 486 if (err < 0) 487 err = -errno; 488 489 hci_close_dev(dd); 490 491 return err; 492} 493 494static int hciops_discoverable(int index) 495{ 496 int dd, err; 497 uint8_t mode = (SCAN_PAGE | SCAN_INQUIRY); 498 499 dd = hci_open_dev(index); 500 if (dd < 0) 501 return -EIO; 502 503 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 504 1, &mode); 505 if (err < 0) 506 err = -errno; 507 508 hci_close_dev(dd); 509 510 return err; 511} 512 513static int hciops_set_class(int index, uint32_t class) 514{ 515 int dd, err; 516 write_class_of_dev_cp cp; 517 518 dd = hci_open_dev(index); 519 if (dd < 0) 520 return -EIO; 521 522 memcpy(cp.dev_class, &class, 3); 523 524 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, 525 WRITE_CLASS_OF_DEV_CP_SIZE, &cp); 526 527 if (err < 0) 528 err = -errno; 529 530 hci_close_dev(dd); 531 532 return err; 533} 534 535static int hciops_set_limited_discoverable(int index, uint32_t class, 536 gboolean limited) 537{ 538 int dd, err; 539 int num = (limited ? 2 : 1); 540 uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e }; 541 write_current_iac_lap_cp cp; 542 543 /* 544 * 1: giac 545 * 2: giac + liac 546 */ 547 dd = hci_open_dev(index); 548 if (dd < 0) 549 return -EIO; 550 551 memset(&cp, 0, sizeof(cp)); 552 cp.num_current_iac = num; 553 memcpy(&cp.lap, lap, num * 3); 554 555 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CURRENT_IAC_LAP, 556 (num * 3 + 1), &cp); 557 if (err < 0) { 558 err = -errno; 559 hci_close_dev(dd); 560 return err; 561 } 562 563 hci_close_dev(dd); 564 565 return hciops_set_class(index, class); 566} 567 568static int hciops_start_discovery(int index, gboolean periodic) 569{ 570 uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; 571 int dd, err; 572 573 dd = hci_open_dev(index); 574 if (dd < 0) 575 return -EIO; 576 577 if (periodic) { 578 periodic_inquiry_cp cp; 579 580 memset(&cp, 0, sizeof(cp)); 581 memcpy(&cp.lap, lap, 3); 582 cp.max_period = htobs(24); 583 cp.min_period = htobs(16); 584 cp.length = 0x08; 585 cp.num_rsp = 0x00; 586 587 err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, 588 PERIODIC_INQUIRY_CP_SIZE, &cp); 589 } else { 590 inquiry_cp inq_cp; 591 592 memset(&inq_cp, 0, sizeof(inq_cp)); 593 memcpy(&inq_cp.lap, lap, 3); 594 inq_cp.length = 0x08; 595 inq_cp.num_rsp = 0x00; 596 597 err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY, 598 INQUIRY_CP_SIZE, &inq_cp); 599 } 600 601 if (err < 0) 602 err = -errno; 603 604 hci_close_dev(dd); 605 606 return err; 607} 608 609static int hciops_stop_discovery(int index) 610{ 611 struct hci_dev_info di; 612 int dd, err; 613 614 if (hci_devinfo(index, &di) < 0) 615 return -errno; 616 617 dd = hci_open_dev(index); 618 if (dd < 0) 619 return -EIO; 620 621 if (hci_test_bit(HCI_INQUIRY, &di.flags)) 622 err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 623 0, 0); 624 else 625 err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 626 0, 0); 627 if (err < 0) 628 err = -errno; 629 630 hci_close_dev(dd); 631 632 return err; 633} 634 635static int hciops_resolve_name(int index, bdaddr_t *bdaddr) 636{ 637 remote_name_req_cp cp; 638 int dd, err; 639 640 dd = hci_open_dev(index); 641 if (dd < 0) 642 return -EIO; 643 644 memset(&cp, 0, sizeof(cp)); 645 bacpy(&cp.bdaddr, bdaddr); 646 cp.pscan_rep_mode = 0x02; 647 648 err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, 649 REMOTE_NAME_REQ_CP_SIZE, &cp); 650 if (err < 0) 651 err = -errno; 652 653 hci_close_dev(dd); 654 655 return err; 656} 657 658static int hciops_set_name(int index, const char *name) 659{ 660 change_local_name_cp cp; 661 int dd, err; 662 663 dd = hci_open_dev(index); 664 if (dd < 0) 665 return -EIO; 666 667 memset(&cp, 0, sizeof(cp)); 668 strncpy((char *) cp.name, name, sizeof(cp.name)); 669 670 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, 671 CHANGE_LOCAL_NAME_CP_SIZE, &cp); 672 if (err < 0) 673 err = -errno; 674 675 hci_close_dev(dd); 676 677 return err; 678} 679 680static int hciops_read_name(int index) 681{ 682 int dd, err; 683 684 dd = hci_open_dev(index); 685 if (dd < 0) 686 return -EIO; 687 688 err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_LOCAL_NAME, 0, 0); 689 if (err < 0) 690 err = -errno; 691 692 hci_close_dev(dd); 693 694 return err; 695} 696 697static int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr) 698{ 699 remote_name_req_cancel_cp cp; 700 int dd, err; 701 702 dd = hci_open_dev(index); 703 if (dd < 0) 704 return -EIO; 705 706 memset(&cp, 0, sizeof(cp)); 707 bacpy(&cp.bdaddr, bdaddr); 708 709 err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL, 710 REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp); 711 if (err < 0) 712 err = -errno; 713 714 hci_close_dev(dd); 715 716 return err; 717} 718 719static struct btd_adapter_ops hci_ops = { 720 .setup = hciops_setup, 721 .cleanup = hciops_cleanup, 722 .start = hciops_start, 723 .stop = hciops_stop, 724 .set_powered = hciops_powered, 725 .set_connectable = hciops_connectable, 726 .set_discoverable = hciops_discoverable, 727 .set_limited_discoverable = hciops_set_limited_discoverable, 728 .start_discovery = hciops_start_discovery, 729 .stop_discovery = hciops_stop_discovery, 730 .resolve_name = hciops_resolve_name, 731 .cancel_resolve_name = hciops_cancel_resolve_name, 732 .set_name = hciops_set_name, 733 .read_name = hciops_read_name, 734 .set_class = hciops_set_class, 735}; 736 737static int hciops_init(void) 738{ 739 return btd_register_adapter_ops(&hci_ops); 740} 741static void hciops_exit(void) 742{ 743 btd_adapter_cleanup_ops(&hci_ops); 744} 745 746BLUETOOTH_PLUGIN_DEFINE(hciops, VERSION, 747 BLUETOOTH_PLUGIN_PRIORITY_LOW, hciops_init, hciops_exit) 748