1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel (at) holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <stdlib.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 #include <sys/ioctl.h> 33 #include <sys/socket.h> 34 35 #include <bluetooth/bluetooth.h> 36 #include <bluetooth/hci.h> 37 #include <bluetooth/hci_lib.h> 38 #include <bluetooth/rfcomm.h> 39 #include <bluetooth/l2cap.h> 40 #include <bluetooth/sco.h> 41 #include <bluetooth/sdp.h> 42 #include <bluetooth/sdp_lib.h> 43 44 #include <glib.h> 45 46 #include "glib-helper.h" 47 48 /* Number of seconds to keep a sdp_session_t in the cache */ 49 #define CACHE_TIMEOUT 2 50 51 struct cached_sdp_session { 52 bdaddr_t src; 53 bdaddr_t dst; 54 sdp_session_t *session; 55 guint timer; 56 }; 57 58 static GSList *cached_sdp_sessions = NULL; 59 60 struct hci_cmd_data { 61 bt_hci_result_t cb; 62 uint16_t handle; 63 uint16_t ocf; 64 gpointer caller_data; 65 }; 66 67 static gboolean cached_session_expired(gpointer user_data) 68 { 69 struct cached_sdp_session *cached = user_data; 70 71 cached_sdp_sessions = g_slist_remove(cached_sdp_sessions, cached); 72 73 sdp_close(cached->session); 74 75 g_free(cached); 76 77 return FALSE; 78 } 79 80 static sdp_session_t *get_sdp_session(const bdaddr_t *src, const bdaddr_t *dst) 81 { 82 GSList *l; 83 84 for (l = cached_sdp_sessions; l != NULL; l = l->next) { 85 struct cached_sdp_session *c = l->data; 86 sdp_session_t *session; 87 88 if (bacmp(&c->src, src) || bacmp(&c->dst, dst)) 89 continue; 90 91 g_source_remove(c->timer); 92 93 session = c->session; 94 95 cached_sdp_sessions = g_slist_remove(cached_sdp_sessions, c); 96 g_free(c); 97 98 return session; 99 } 100 101 return sdp_connect(src, dst, SDP_NON_BLOCKING); 102 } 103 104 static void cache_sdp_session(bdaddr_t *src, bdaddr_t *dst, 105 sdp_session_t *session) 106 { 107 struct cached_sdp_session *cached; 108 109 cached = g_new0(struct cached_sdp_session, 1); 110 111 bacpy(&cached->src, src); 112 bacpy(&cached->dst, dst); 113 114 cached->session = session; 115 116 cached_sdp_sessions = g_slist_append(cached_sdp_sessions, cached); 117 118 cached->timer = g_timeout_add_seconds(CACHE_TIMEOUT, 119 cached_session_expired, 120 cached); 121 } 122 123 int set_nonblocking(int fd) 124 { 125 long arg; 126 127 arg = fcntl(fd, F_GETFL); 128 if (arg < 0) 129 return -errno; 130 131 /* Return if already nonblocking */ 132 if (arg & O_NONBLOCK) 133 return 0; 134 135 arg |= O_NONBLOCK; 136 if (fcntl(fd, F_SETFL, arg) < 0) 137 return -errno; 138 139 return 0; 140 } 141 142 struct search_context { 143 bdaddr_t src; 144 bdaddr_t dst; 145 sdp_session_t *session; 146 bt_callback_t cb; 147 bt_destroy_t destroy; 148 gpointer user_data; 149 uuid_t uuid; 150 guint io_id; 151 }; 152 153 static GSList *context_list = NULL; 154 155 static void search_context_cleanup(struct search_context *ctxt) 156 { 157 context_list = g_slist_remove(context_list, ctxt); 158 159 if (ctxt->destroy) 160 ctxt->destroy(ctxt->user_data); 161 162 g_free(ctxt); 163 } 164 165 static void search_completed_cb(uint8_t type, uint16_t status, 166 uint8_t *rsp, size_t size, void *user_data) 167 { 168 struct search_context *ctxt = user_data; 169 sdp_list_t *recs = NULL; 170 int scanned, seqlen = 0, bytesleft = size; 171 uint8_t dataType; 172 int err = 0; 173 174 if (status || type != SDP_SVC_SEARCH_ATTR_RSP) { 175 err = -EPROTO; 176 goto done; 177 } 178 179 scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen); 180 if (!scanned || !seqlen) 181 goto done; 182 183 rsp += scanned; 184 bytesleft -= scanned; 185 do { 186 sdp_record_t *rec; 187 int recsize; 188 189 recsize = 0; 190 rec = sdp_extract_pdu(rsp, bytesleft, &recsize); 191 if (!rec) 192 break; 193 194 if (!recsize) { 195 sdp_record_free(rec); 196 break; 197 } 198 199 scanned += recsize; 200 rsp += recsize; 201 bytesleft -= recsize; 202 203 recs = sdp_list_append(recs, rec); 204 } while (scanned < (ssize_t) size && bytesleft > 0); 205 206 done: 207 cache_sdp_session(&ctxt->src, &ctxt->dst, ctxt->session); 208 209 if (ctxt->cb) 210 ctxt->cb(recs, err, ctxt->user_data); 211 212 if (recs) 213 sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); 214 215 search_context_cleanup(ctxt); 216 } 217 218 static gboolean search_process_cb(GIOChannel *chan, 219 GIOCondition cond, void *user_data) 220 { 221 struct search_context *ctxt = user_data; 222 int err = 0; 223 224 if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { 225 err = EIO; 226 goto failed; 227 } 228 229 if (sdp_process(ctxt->session) < 0) 230 goto failed; 231 232 return TRUE; 233 234 failed: 235 if (err) { 236 sdp_close(ctxt->session); 237 ctxt->session = NULL; 238 239 if (ctxt->cb) 240 ctxt->cb(NULL, err, ctxt->user_data); 241 242 search_context_cleanup(ctxt); 243 } 244 245 return FALSE; 246 } 247 248 static gboolean connect_watch(GIOChannel *chan, GIOCondition cond, gpointer user_data) 249 { 250 struct search_context *ctxt = user_data; 251 sdp_list_t *search, *attrids; 252 uint32_t range = 0x0000ffff; 253 socklen_t len; 254 int sk, err = 0; 255 256 sk = g_io_channel_unix_get_fd(chan); 257 ctxt->io_id = 0; 258 259 len = sizeof(err); 260 if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { 261 err = errno; 262 goto failed; 263 } 264 265 if (err != 0) 266 goto failed; 267 268 if (sdp_set_notify(ctxt->session, search_completed_cb, ctxt) < 0) { 269 err = EIO; 270 goto failed; 271 } 272 273 search = sdp_list_append(NULL, &ctxt->uuid); 274 attrids = sdp_list_append(NULL, &range); 275 if (sdp_service_search_attr_async(ctxt->session, 276 search, SDP_ATTR_REQ_RANGE, attrids) < 0) { 277 sdp_list_free(attrids, NULL); 278 sdp_list_free(search, NULL); 279 err = EIO; 280 goto failed; 281 } 282 283 sdp_list_free(attrids, NULL); 284 sdp_list_free(search, NULL); 285 286 /* Set callback responsible for update the internal SDP transaction */ 287 ctxt->io_id = g_io_add_watch(chan, 288 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, 289 search_process_cb, ctxt); 290 return FALSE; 291 292 failed: 293 sdp_close(ctxt->session); 294 ctxt->session = NULL; 295 296 if (ctxt->cb) 297 ctxt->cb(NULL, -err, ctxt->user_data); 298 299 search_context_cleanup(ctxt); 300 301 return FALSE; 302 } 303 304 static int create_search_context(struct search_context **ctxt, 305 const bdaddr_t *src, const bdaddr_t *dst, 306 uuid_t *uuid) 307 { 308 sdp_session_t *s; 309 GIOChannel *chan; 310 311 if (!ctxt) 312 return -EINVAL; 313 314 s = get_sdp_session(src, dst); 315 if (!s) 316 return -errno; 317 318 *ctxt = g_try_malloc0(sizeof(struct search_context)); 319 if (!*ctxt) { 320 sdp_close(s); 321 return -ENOMEM; 322 } 323 324 bacpy(&(*ctxt)->src, src); 325 bacpy(&(*ctxt)->dst, dst); 326 (*ctxt)->session = s; 327 (*ctxt)->uuid = *uuid; 328 329 chan = g_io_channel_unix_new(sdp_get_socket(s)); 330 (*ctxt)->io_id = g_io_add_watch(chan, 331 G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, 332 connect_watch, *ctxt); 333 g_io_channel_unref(chan); 334 335 return 0; 336 } 337 338 int bt_search_service(const bdaddr_t *src, const bdaddr_t *dst, 339 uuid_t *uuid, bt_callback_t cb, void *user_data, 340 bt_destroy_t destroy) 341 { 342 struct search_context *ctxt = NULL; 343 int err; 344 345 if (!cb) 346 return -EINVAL; 347 348 err = create_search_context(&ctxt, src, dst, uuid); 349 if (err < 0) 350 return err; 351 352 ctxt->cb = cb; 353 ctxt->destroy = destroy; 354 ctxt->user_data = user_data; 355 356 context_list = g_slist_append(context_list, ctxt); 357 358 return 0; 359 } 360 361 int bt_discover_services(const bdaddr_t *src, const bdaddr_t *dst, 362 bt_callback_t cb, void *user_data, bt_destroy_t destroy) 363 { 364 uuid_t uuid; 365 366 sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); 367 368 return bt_search_service(src, dst, &uuid, cb, user_data, destroy); 369 } 370 371 static int find_by_bdaddr(const void *data, const void *user_data) 372 { 373 const struct search_context *ctxt = data, *search = user_data; 374 375 return (bacmp(&ctxt->dst, &search->dst) && 376 bacmp(&ctxt->src, &search->src)); 377 } 378 379 int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst) 380 { 381 struct search_context search, *ctxt; 382 GSList *match; 383 384 memset(&search, 0, sizeof(search)); 385 bacpy(&search.src, src); 386 bacpy(&search.dst, dst); 387 388 /* Ongoing SDP Discovery */ 389 match = g_slist_find_custom(context_list, &search, find_by_bdaddr); 390 if (!match) 391 return -ENODATA; 392 393 ctxt = match->data; 394 if (!ctxt->session) 395 return -ENOTCONN; 396 397 if (ctxt->io_id) 398 g_source_remove(ctxt->io_id); 399 400 if (ctxt->session) 401 sdp_close(ctxt->session); 402 403 search_context_cleanup(ctxt); 404 return 0; 405 } 406 407 char *bt_uuid2string(uuid_t *uuid) 408 { 409 gchar *str; 410 uuid_t uuid128; 411 unsigned int data0; 412 unsigned short data1; 413 unsigned short data2; 414 unsigned short data3; 415 unsigned int data4; 416 unsigned short data5; 417 418 if (!uuid) 419 return NULL; 420 421 switch (uuid->type) { 422 case SDP_UUID16: 423 sdp_uuid16_to_uuid128(&uuid128, uuid); 424 break; 425 case SDP_UUID32: 426 sdp_uuid32_to_uuid128(&uuid128, uuid); 427 break; 428 case SDP_UUID128: 429 memcpy(&uuid128, uuid, sizeof(uuid_t)); 430 break; 431 default: 432 /* Type of UUID unknown */ 433 return NULL; 434 } 435 436 memcpy(&data0, &uuid128.value.uuid128.data[0], 4); 437 memcpy(&data1, &uuid128.value.uuid128.data[4], 2); 438 memcpy(&data2, &uuid128.value.uuid128.data[6], 2); 439 memcpy(&data3, &uuid128.value.uuid128.data[8], 2); 440 memcpy(&data4, &uuid128.value.uuid128.data[10], 4); 441 memcpy(&data5, &uuid128.value.uuid128.data[14], 2); 442 443 str = g_try_malloc0(MAX_LEN_UUID_STR); 444 if (!str) 445 return NULL; 446 447 sprintf(str, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", 448 g_ntohl(data0), g_ntohs(data1), 449 g_ntohs(data2), g_ntohs(data3), 450 g_ntohl(data4), g_ntohs(data5)); 451 452 return str; 453 } 454 455 static struct { 456 const char *name; 457 uint16_t class; 458 } bt_services[] = { 459 { "vcp", VIDEO_CONF_SVCLASS_ID }, 460 { "pbap", PBAP_SVCLASS_ID }, 461 { "sap", SAP_SVCLASS_ID }, 462 { "ftp", OBEX_FILETRANS_SVCLASS_ID }, 463 { "bpp", BASIC_PRINTING_SVCLASS_ID }, 464 { "bip", IMAGING_SVCLASS_ID }, 465 { "synch", IRMC_SYNC_SVCLASS_ID }, 466 { "dun", DIALUP_NET_SVCLASS_ID }, 467 { "opp", OBEX_OBJPUSH_SVCLASS_ID }, 468 { "fax", FAX_SVCLASS_ID }, 469 { "spp", SERIAL_PORT_SVCLASS_ID }, 470 { "hsp", HEADSET_SVCLASS_ID }, 471 { "hfp", HANDSFREE_SVCLASS_ID }, 472 { } 473 }; 474 475 uint16_t bt_name2class(const char *pattern) 476 { 477 int i; 478 479 for (i = 0; bt_services[i].name; i++) { 480 if (strcasecmp(bt_services[i].name, pattern) == 0) 481 return bt_services[i].class; 482 } 483 484 return 0; 485 } 486 487 static inline gboolean is_uuid128(const char *string) 488 { 489 return (strlen(string) == 36 && 490 string[8] == '-' && 491 string[13] == '-' && 492 string[18] == '-' && 493 string[23] == '-'); 494 } 495 496 char *bt_name2string(const char *pattern) 497 { 498 uuid_t uuid; 499 uint16_t uuid16; 500 int i; 501 502 /* UUID 128 string format */ 503 if (is_uuid128(pattern)) 504 return g_strdup(pattern); 505 506 /* Friendly service name format */ 507 uuid16 = bt_name2class(pattern); 508 if (uuid16) 509 goto proceed; 510 511 /* HEX format */ 512 uuid16 = strtol(pattern, NULL, 16); 513 for (i = 0; bt_services[i].class; i++) { 514 if (bt_services[i].class == uuid16) 515 goto proceed; 516 } 517 518 return NULL; 519 520 proceed: 521 sdp_uuid16_create(&uuid, uuid16); 522 523 return bt_uuid2string(&uuid); 524 } 525 526 int bt_string2uuid(uuid_t *uuid, const char *string) 527 { 528 uint32_t data0, data4; 529 uint16_t data1, data2, data3, data5; 530 531 if (is_uuid128(string) && 532 sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx", 533 &data0, &data1, &data2, &data3, &data4, &data5) == 6) { 534 uint8_t val[16]; 535 536 data0 = g_htonl(data0); 537 data1 = g_htons(data1); 538 data2 = g_htons(data2); 539 data3 = g_htons(data3); 540 data4 = g_htonl(data4); 541 data5 = g_htons(data5); 542 543 memcpy(&val[0], &data0, 4); 544 memcpy(&val[4], &data1, 2); 545 memcpy(&val[6], &data2, 2); 546 memcpy(&val[8], &data3, 2); 547 memcpy(&val[10], &data4, 4); 548 memcpy(&val[14], &data5, 2); 549 550 sdp_uuid128_create(uuid, val); 551 552 return 0; 553 } else { 554 uint16_t class = bt_name2class(string); 555 if (class) { 556 sdp_uuid16_create(uuid, class); 557 return 0; 558 } 559 } 560 561 return -1; 562 } 563 564 gchar *bt_list2string(GSList *list) 565 { 566 GSList *l; 567 gchar *str, *tmp; 568 569 if (!list) 570 return NULL; 571 572 str = g_strdup((const gchar *) list->data); 573 574 for (l = list->next; l; l = l->next) { 575 tmp = g_strconcat(str, " " , (const gchar *) l->data, NULL); 576 g_free(str); 577 str = tmp; 578 } 579 580 return str; 581 } 582 583 GSList *bt_string2list(const gchar *str) 584 { 585 GSList *l = NULL; 586 gchar **uuids; 587 int i = 0; 588 589 if (!str) 590 return NULL; 591 592 /* FIXME: eglib doesn't support g_strsplit */ 593 uuids = g_strsplit(str, " ", 0); 594 if (!uuids) 595 return NULL; 596 597 while (uuids[i]) { 598 l = g_slist_append(l, uuids[i]); 599 i++; 600 } 601 602 g_free(uuids); 603 604 return l; 605 } 606 607 static gboolean hci_event_watch(GIOChannel *io, 608 GIOCondition cond, gpointer user_data) 609 { 610 unsigned char buf[HCI_MAX_EVENT_SIZE], *body; 611 struct hci_cmd_data *cmd = user_data; 612 evt_cmd_status *evt_status; 613 evt_auth_complete *evt_auth; 614 evt_encrypt_change *evt_enc; 615 hci_event_hdr *hdr; 616 set_conn_encrypt_cp cp; 617 int dd; 618 uint16_t ocf; 619 uint8_t status = HCI_OE_POWER_OFF; 620 621 if (cond & G_IO_NVAL) { 622 cmd->cb(status, cmd->caller_data); 623 return FALSE; 624 } 625 626 if (cond & (G_IO_ERR | G_IO_HUP)) 627 goto failed; 628 629 dd = g_io_channel_unix_get_fd(io); 630 631 if (read(dd, buf, sizeof(buf)) < 0) 632 goto failed; 633 634 hdr = (hci_event_hdr *) (buf + 1); 635 body = buf + (1 + HCI_EVENT_HDR_SIZE); 636 637 switch (hdr->evt) { 638 case EVT_CMD_STATUS: 639 evt_status = (evt_cmd_status *) body; 640 ocf = cmd_opcode_ocf(evt_status->opcode); 641 if (ocf != cmd->ocf) 642 return TRUE; 643 switch (ocf) { 644 case OCF_AUTH_REQUESTED: 645 case OCF_SET_CONN_ENCRYPT: 646 if (evt_status->status != 0) { 647 /* Baseband rejected command */ 648 status = evt_status->status; 649 goto failed; 650 } 651 break; 652 default: 653 return TRUE; 654 } 655 /* Wait for the next event */ 656 return TRUE; 657 case EVT_AUTH_COMPLETE: 658 evt_auth = (evt_auth_complete *) body; 659 if (evt_auth->handle != cmd->handle) { 660 /* Skipping */ 661 return TRUE; 662 } 663 664 if (evt_auth->status != 0x00) { 665 status = evt_auth->status; 666 /* Abort encryption */ 667 goto failed; 668 } 669 670 memset(&cp, 0, sizeof(cp)); 671 cp.handle = cmd->handle; 672 cp.encrypt = 1; 673 674 cmd->ocf = OCF_SET_CONN_ENCRYPT; 675 676 if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, 677 SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) { 678 status = HCI_COMMAND_DISALLOWED; 679 goto failed; 680 } 681 /* Wait for encrypt change event */ 682 return TRUE; 683 case EVT_ENCRYPT_CHANGE: 684 evt_enc = (evt_encrypt_change *) body; 685 if (evt_enc->handle != cmd->handle) 686 return TRUE; 687 688 /* Procedure finished: reporting status */ 689 status = evt_enc->status; 690 break; 691 default: 692 /* Skipping */ 693 return TRUE; 694 } 695 696 failed: 697 cmd->cb(status, cmd->caller_data); 698 g_io_channel_shutdown(io, TRUE, NULL); 699 700 return FALSE; 701 } 702 703 int bt_acl_encrypt(const bdaddr_t *src, const bdaddr_t *dst, 704 bt_hci_result_t cb, gpointer user_data) 705 { 706 GIOChannel *io; 707 struct hci_cmd_data *cmd; 708 struct hci_conn_info_req *cr; 709 auth_requested_cp cp; 710 struct hci_filter nf; 711 int dd, dev_id, err; 712 char src_addr[18]; 713 uint32_t link_mode; 714 uint16_t handle; 715 716 ba2str(src, src_addr); 717 dev_id = hci_devid(src_addr); 718 if (dev_id < 0) 719 return -errno; 720 721 dd = hci_open_dev(dev_id); 722 if (dd < 0) 723 return -errno; 724 725 cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); 726 cr->type = ACL_LINK; 727 bacpy(&cr->bdaddr, dst); 728 729 err = ioctl(dd, HCIGETCONNINFO, cr); 730 link_mode = cr->conn_info->link_mode; 731 handle = cr->conn_info->handle; 732 g_free(cr); 733 734 if (err < 0) { 735 err = errno; 736 goto failed; 737 } 738 739 if (link_mode & HCI_LM_ENCRYPT) { 740 /* Already encrypted */ 741 err = EALREADY; 742 goto failed; 743 } 744 745 memset(&cp, 0, sizeof(cp)); 746 cp.handle = htobs(handle); 747 748 if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_AUTH_REQUESTED, 749 AUTH_REQUESTED_CP_SIZE, &cp) < 0) { 750 err = errno; 751 goto failed; 752 } 753 754 cmd = g_new0(struct hci_cmd_data, 1); 755 cmd->handle = handle; 756 cmd->ocf = OCF_AUTH_REQUESTED; 757 cmd->cb = cb; 758 cmd->caller_data = user_data; 759 760 hci_filter_clear(&nf); 761 hci_filter_set_ptype(HCI_EVENT_PKT, &nf); 762 hci_filter_set_event(EVT_CMD_STATUS, &nf); 763 hci_filter_set_event(EVT_AUTH_COMPLETE, &nf); 764 hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf); 765 766 if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { 767 err = errno; 768 g_free(cmd); 769 goto failed; 770 } 771 772 io = g_io_channel_unix_new(dd); 773 g_io_channel_set_close_on_unref(io, FALSE); 774 g_io_add_watch_full(io, G_PRIORITY_DEFAULT, 775 G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN, 776 hci_event_watch, cmd, g_free); 777 g_io_channel_unref(io); 778 779 return 0; 780 781 failed: 782 close(dd); 783 784 return -err; 785 } 786