1 /* $NetBSD: hci_event.c,v 1.10 2007/11/10 23:12:22 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 2005 Iain Hibbert. 5 * Copyright (c) 2006 Itronix Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of Itronix Inc. may not be used to endorse 17 * or promote products derived from this software without specific 18 * prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.10 2007/11/10 23:12:22 plunky Exp $"); 35 36 #include <sys/param.h> 37 #include <sys/kernel.h> 38 #include <sys/malloc.h> 39 #include <sys/mbuf.h> 40 #include <sys/proc.h> 41 #include <sys/systm.h> 42 43 #include <netbt/bluetooth.h> 44 #include <netbt/hci.h> 45 #include <netbt/sco.h> 46 47 static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *); 48 static void hci_event_rssi_result(struct hci_unit *, struct mbuf *); 49 static void hci_event_command_status(struct hci_unit *, struct mbuf *); 50 static void hci_event_command_compl(struct hci_unit *, struct mbuf *); 51 static void hci_event_con_compl(struct hci_unit *, struct mbuf *); 52 static void hci_event_discon_compl(struct hci_unit *, struct mbuf *); 53 static void hci_event_con_req(struct hci_unit *, struct mbuf *); 54 static void hci_event_num_compl_pkts(struct hci_unit *, struct mbuf *); 55 static void hci_event_auth_compl(struct hci_unit *, struct mbuf *); 56 static void hci_event_encryption_change(struct hci_unit *, struct mbuf *); 57 static void hci_event_change_con_link_key_compl(struct hci_unit *, struct mbuf *); 58 static void hci_event_read_clock_offset_compl(struct hci_unit *, struct mbuf *); 59 static void hci_cmd_read_bdaddr(struct hci_unit *, struct mbuf *); 60 static void hci_cmd_read_buffer_size(struct hci_unit *, struct mbuf *); 61 static void hci_cmd_read_local_features(struct hci_unit *, struct mbuf *); 62 static void hci_cmd_reset(struct hci_unit *, struct mbuf *); 63 64 #ifdef BLUETOOTH_DEBUG 65 int bluetooth_debug; 66 67 static const char *hci_eventnames[] = { 68 /* 0x00 */ "NULL", 69 /* 0x01 */ "INQUIRY COMPLETE", 70 /* 0x02 */ "INQUIRY RESULT", 71 /* 0x03 */ "CONN COMPLETE", 72 /* 0x04 */ "CONN REQ", 73 /* 0x05 */ "DISCONN COMPLETE", 74 /* 0x06 */ "AUTH COMPLETE", 75 /* 0x07 */ "REMOTE NAME REQ COMPLETE", 76 /* 0x08 */ "ENCRYPTION CHANGE", 77 /* 0x09 */ "CHANGE CONN LINK KEY COMPLETE", 78 /* 0x0a */ "MASTER LINK KEY COMPLETE", 79 /* 0x0b */ "READ REMOTE FEATURES COMPLETE", 80 /* 0x0c */ "READ REMOTE VERSION INFO COMPLETE", 81 /* 0x0d */ "QoS SETUP COMPLETE", 82 /* 0x0e */ "COMMAND COMPLETE", 83 /* 0x0f */ "COMMAND STATUS", 84 /* 0x10 */ "HARDWARE ERROR", 85 /* 0x11 */ "FLUSH OCCUR", 86 /* 0x12 */ "ROLE CHANGE", 87 /* 0x13 */ "NUM COMPLETED PACKETS", 88 /* 0x14 */ "MODE CHANGE", 89 /* 0x15 */ "RETURN LINK KEYS", 90 /* 0x16 */ "PIN CODE REQ", 91 /* 0x17 */ "LINK KEY REQ", 92 /* 0x18 */ "LINK KEY NOTIFICATION", 93 /* 0x19 */ "LOOPBACK COMMAND", 94 /* 0x1a */ "DATA BUFFER OVERFLOW", 95 /* 0x1b */ "MAX SLOT CHANGE", 96 /* 0x1c */ "READ CLOCK OFFSET COMPLETE", 97 /* 0x1d */ "CONN PKT TYPE CHANGED", 98 /* 0x1e */ "QOS VIOLATION", 99 /* 0x1f */ "PAGE SCAN MODE CHANGE", 100 /* 0x20 */ "PAGE SCAN REP MODE CHANGE", 101 /* 0x21 */ "FLOW SPECIFICATION COMPLETE", 102 /* 0x22 */ "RSSI RESULT", 103 /* 0x23 */ "READ REMOTE EXT FEATURES" 104 }; 105 106 static const char * 107 hci_eventstr(unsigned int event) 108 { 109 110 if (event < (sizeof(hci_eventnames) / sizeof(*hci_eventnames))) 111 return hci_eventnames[event]; 112 113 switch (event) { 114 case HCI_EVENT_SCO_CON_COMPL: /* 0x2c */ 115 return "SCO CON COMPLETE"; 116 117 case HCI_EVENT_SCO_CON_CHANGED: /* 0x2d */ 118 return "SCO CON CHANGED"; 119 120 case HCI_EVENT_BT_LOGO: /* 0xfe */ 121 return "BT_LOGO"; 122 123 case HCI_EVENT_VENDOR: /* 0xff */ 124 return "VENDOR"; 125 } 126 127 return "UNRECOGNISED"; 128 } 129 #endif /* BLUETOOTH_DEBUG */ 130 131 /* 132 * process HCI Events 133 * 134 * We will free the mbuf at the end, no need for any sub 135 * functions to handle that. We kind of assume that the 136 * device sends us valid events. 137 */ 138 void 139 hci_event(struct mbuf *m, struct hci_unit *unit) 140 { 141 hci_event_hdr_t hdr; 142 143 KASSERT(m->m_flags & M_PKTHDR); 144 145 KASSERT(m->m_pkthdr.len >= sizeof(hdr)); 146 m_copydata(m, 0, sizeof(hdr), &hdr); 147 m_adj(m, sizeof(hdr)); 148 149 KASSERT(hdr.type == HCI_EVENT_PKT); 150 151 DPRINTFN(1, "(%s) event %s\n", 152 device_xname(unit->hci_dev), hci_eventstr(hdr.event)); 153 154 switch(hdr.event) { 155 case HCI_EVENT_COMMAND_STATUS: 156 hci_event_command_status(unit, m); 157 break; 158 159 case HCI_EVENT_COMMAND_COMPL: 160 hci_event_command_compl(unit, m); 161 break; 162 163 case HCI_EVENT_NUM_COMPL_PKTS: 164 hci_event_num_compl_pkts(unit, m); 165 break; 166 167 case HCI_EVENT_INQUIRY_RESULT: 168 hci_event_inquiry_result(unit, m); 169 break; 170 171 case HCI_EVENT_RSSI_RESULT: 172 hci_event_rssi_result(unit, m); 173 break; 174 175 case HCI_EVENT_CON_COMPL: 176 hci_event_con_compl(unit, m); 177 break; 178 179 case HCI_EVENT_DISCON_COMPL: 180 hci_event_discon_compl(unit, m); 181 break; 182 183 case HCI_EVENT_CON_REQ: 184 hci_event_con_req(unit, m); 185 break; 186 187 case HCI_EVENT_AUTH_COMPL: 188 hci_event_auth_compl(unit, m); 189 break; 190 191 case HCI_EVENT_ENCRYPTION_CHANGE: 192 hci_event_encryption_change(unit, m); 193 break; 194 195 case HCI_EVENT_CHANGE_CON_LINK_KEY_COMPL: 196 hci_event_change_con_link_key_compl(unit, m); 197 break; 198 199 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL: 200 hci_event_read_clock_offset_compl(unit, m); 201 break; 202 203 case HCI_EVENT_SCO_CON_COMPL: 204 case HCI_EVENT_INQUIRY_COMPL: 205 case HCI_EVENT_REMOTE_NAME_REQ_COMPL: 206 case HCI_EVENT_MASTER_LINK_KEY_COMPL: 207 case HCI_EVENT_READ_REMOTE_FEATURES_COMPL: 208 case HCI_EVENT_READ_REMOTE_VER_INFO_COMPL: 209 case HCI_EVENT_QOS_SETUP_COMPL: 210 case HCI_EVENT_HARDWARE_ERROR: 211 case HCI_EVENT_FLUSH_OCCUR: 212 case HCI_EVENT_ROLE_CHANGE: 213 case HCI_EVENT_MODE_CHANGE: 214 case HCI_EVENT_RETURN_LINK_KEYS: 215 case HCI_EVENT_PIN_CODE_REQ: 216 case HCI_EVENT_LINK_KEY_REQ: 217 case HCI_EVENT_LINK_KEY_NOTIFICATION: 218 case HCI_EVENT_LOOPBACK_COMMAND: 219 case HCI_EVENT_DATA_BUFFER_OVERFLOW: 220 case HCI_EVENT_MAX_SLOT_CHANGE: 221 case HCI_EVENT_CON_PKT_TYPE_CHANGED: 222 case HCI_EVENT_QOS_VIOLATION: 223 case HCI_EVENT_PAGE_SCAN_MODE_CHANGE: 224 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE: 225 case HCI_EVENT_FLOW_SPECIFICATION_COMPL: 226 case HCI_EVENT_READ_REMOTE_EXTENDED_FEATURES: 227 case HCI_EVENT_SCO_CON_CHANGED: 228 case HCI_EVENT_BT_LOGO: 229 case HCI_EVENT_VENDOR: 230 break; 231 232 default: 233 UNKNOWN(hdr.event); 234 break; 235 } 236 237 m_freem(m); 238 } 239 240 /* 241 * Command Status 242 * 243 * Update our record of num_cmd_pkts then post-process any pending commands 244 * and optionally restart cmd output on the unit. 245 */ 246 static void 247 hci_event_command_status(struct hci_unit *unit, struct mbuf *m) 248 { 249 hci_command_status_ep ep; 250 251 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 252 m_copydata(m, 0, sizeof(ep), &ep); 253 m_adj(m, sizeof(ep)); 254 255 DPRINTFN(1, "(%s) opcode (%03x|%04x) status = 0x%x num_cmd_pkts = %d\n", 256 device_xname(unit->hci_dev), 257 HCI_OGF(le16toh(ep.opcode)), HCI_OCF(le16toh(ep.opcode)), 258 ep.status, 259 ep.num_cmd_pkts); 260 261 unit->hci_num_cmd_pkts = ep.num_cmd_pkts; 262 263 /* 264 * post processing of pending commands 265 */ 266 switch(le16toh(ep.opcode)) { 267 default: 268 break; 269 } 270 271 while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) { 272 MBUFQ_DEQUEUE(&unit->hci_cmdwait, m); 273 hci_output_cmd(unit, m); 274 } 275 } 276 277 /* 278 * Command Complete 279 * 280 * Update our record of num_cmd_pkts then handle the completed command, 281 * and optionally restart cmd output on the unit. 282 */ 283 static void 284 hci_event_command_compl(struct hci_unit *unit, struct mbuf *m) 285 { 286 hci_command_compl_ep ep; 287 288 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 289 m_copydata(m, 0, sizeof(ep), &ep); 290 m_adj(m, sizeof(ep)); 291 292 DPRINTFN(1, "(%s) opcode (%03x|%04x) num_cmd_pkts = %d\n", 293 device_xname(unit->hci_dev), 294 HCI_OGF(le16toh(ep.opcode)), HCI_OCF(le16toh(ep.opcode)), 295 ep.num_cmd_pkts); 296 297 unit->hci_num_cmd_pkts = ep.num_cmd_pkts; 298 299 /* 300 * post processing of completed commands 301 */ 302 switch(le16toh(ep.opcode)) { 303 case HCI_CMD_READ_BDADDR: 304 hci_cmd_read_bdaddr(unit, m); 305 break; 306 307 case HCI_CMD_READ_BUFFER_SIZE: 308 hci_cmd_read_buffer_size(unit, m); 309 break; 310 311 case HCI_CMD_READ_LOCAL_FEATURES: 312 hci_cmd_read_local_features(unit, m); 313 break; 314 315 case HCI_CMD_RESET: 316 hci_cmd_reset(unit, m); 317 break; 318 319 default: 320 break; 321 } 322 323 while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) { 324 MBUFQ_DEQUEUE(&unit->hci_cmdwait, m); 325 hci_output_cmd(unit, m); 326 } 327 } 328 329 /* 330 * Number of Completed Packets 331 * 332 * This is sent periodically by the Controller telling us how many 333 * buffers are now freed up and which handle was using them. From 334 * this we determine which type of buffer it was and add the qty 335 * back into the relevant packet counter, then restart output on 336 * links that have halted. 337 */ 338 static void 339 hci_event_num_compl_pkts(struct hci_unit *unit, struct mbuf *m) 340 { 341 hci_num_compl_pkts_ep ep; 342 struct hci_link *link, *next; 343 uint16_t handle, num; 344 int num_acl = 0, num_sco = 0; 345 346 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 347 m_copydata(m, 0, sizeof(ep), &ep); 348 m_adj(m, sizeof(ep)); 349 350 while (ep.num_con_handles--) { 351 m_copydata(m, 0, sizeof(handle), &handle); 352 m_adj(m, sizeof(handle)); 353 handle = le16toh(handle); 354 355 m_copydata(m, 0, sizeof(num), &num); 356 m_adj(m, sizeof(num)); 357 num = le16toh(num); 358 359 link = hci_link_lookup_handle(unit, handle); 360 if (link) { 361 if (link->hl_type == HCI_LINK_ACL) { 362 num_acl += num; 363 hci_acl_complete(link, num); 364 } else { 365 num_sco += num; 366 hci_sco_complete(link, num); 367 } 368 } else { 369 /* XXX need to issue Read_Buffer_Size or Reset? */ 370 aprint_error_dev(unit->hci_dev, 371 "unknown handle %d! (losing track of %d packet buffer%s)\n", 372 handle, num, (num == 1 ? "" : "s")); 373 } 374 } 375 376 /* 377 * Move up any queued packets. When a link has sent data, it will move 378 * to the back of the queue - technically then if a link had something 379 * to send and there were still buffers available it could get started 380 * twice but it seemed more important to to handle higher loads fairly 381 * than worry about wasting cycles when we are not busy. 382 */ 383 384 unit->hci_num_acl_pkts += num_acl; 385 unit->hci_num_sco_pkts += num_sco; 386 387 link = TAILQ_FIRST(&unit->hci_links); 388 while (link && (unit->hci_num_acl_pkts > 0 || unit->hci_num_sco_pkts > 0)) { 389 next = TAILQ_NEXT(link, hl_next); 390 391 if (link->hl_type == HCI_LINK_ACL) { 392 if (unit->hci_num_acl_pkts > 0 && link->hl_txqlen > 0) 393 hci_acl_start(link); 394 } else { 395 if (unit->hci_num_sco_pkts > 0 && link->hl_txqlen > 0) 396 hci_sco_start(link); 397 } 398 399 link = next; 400 } 401 } 402 403 /* 404 * Inquiry Result 405 * 406 * keep a note of devices seen, so we know which unit to use 407 * on outgoing connections 408 */ 409 static void 410 hci_event_inquiry_result(struct hci_unit *unit, struct mbuf *m) 411 { 412 hci_inquiry_result_ep ep; 413 hci_inquiry_response ir; 414 struct hci_memo *memo; 415 416 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 417 m_copydata(m, 0, sizeof(ep), &ep); 418 m_adj(m, sizeof(ep)); 419 420 DPRINTFN(1, "%d response%s\n", ep.num_responses, 421 (ep.num_responses == 1 ? "" : "s")); 422 423 while(ep.num_responses--) { 424 KASSERT(m->m_pkthdr.len >= sizeof(ir)); 425 m_copydata(m, 0, sizeof(ir), &ir); 426 m_adj(m, sizeof(ir)); 427 428 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n", 429 ir.bdaddr.b[5], ir.bdaddr.b[4], ir.bdaddr.b[3], 430 ir.bdaddr.b[2], ir.bdaddr.b[1], ir.bdaddr.b[0]); 431 432 memo = hci_memo_new(unit, &ir.bdaddr); 433 if (memo != NULL) { 434 memo->page_scan_rep_mode = ir.page_scan_rep_mode; 435 memo->page_scan_mode = ir.page_scan_mode; 436 memo->clock_offset = ir.clock_offset; 437 } 438 } 439 } 440 441 /* 442 * Inquiry Result with RSSI 443 * 444 * as above but different packet when RSSI result is enabled 445 */ 446 static void 447 hci_event_rssi_result(struct hci_unit *unit, struct mbuf *m) 448 { 449 hci_rssi_result_ep ep; 450 hci_rssi_response rr; 451 struct hci_memo *memo; 452 453 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 454 m_copydata(m, 0, sizeof(ep), &ep); 455 m_adj(m, sizeof(ep)); 456 457 DPRINTFN(1, "%d response%s\n", ep.num_responses, 458 (ep.num_responses == 1 ? "" : "s")); 459 460 while(ep.num_responses--) { 461 KASSERT(m->m_pkthdr.len >= sizeof(rr)); 462 m_copydata(m, 0, sizeof(rr), &rr); 463 m_adj(m, sizeof(rr)); 464 465 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n", 466 rr.bdaddr.b[5], rr.bdaddr.b[4], rr.bdaddr.b[3], 467 rr.bdaddr.b[2], rr.bdaddr.b[1], rr.bdaddr.b[0]); 468 469 memo = hci_memo_new(unit, &rr.bdaddr); 470 if (memo != NULL) { 471 memo->page_scan_rep_mode = rr.page_scan_rep_mode; 472 memo->page_scan_mode = 0; 473 memo->clock_offset = rr.clock_offset; 474 } 475 } 476 } 477 478 /* 479 * Connection Complete 480 * 481 * Sent to us when a connection is made. If there is no link 482 * structure already allocated for this, we must have changed 483 * our mind, so just disconnect. 484 */ 485 static void 486 hci_event_con_compl(struct hci_unit *unit, struct mbuf *m) 487 { 488 hci_con_compl_ep ep; 489 hci_write_link_policy_settings_cp cp; 490 struct hci_link *link; 491 int err; 492 493 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 494 m_copydata(m, 0, sizeof(ep), &ep); 495 m_adj(m, sizeof(ep)); 496 497 DPRINTFN(1, "(%s) %s connection complete for " 498 "%02x:%02x:%02x:%02x:%02x:%02x status %#x\n", 499 device_xname(unit->hci_dev), 500 (ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"), 501 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3], 502 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0], 503 ep.status); 504 505 link = hci_link_lookup_bdaddr(unit, &ep.bdaddr, ep.link_type); 506 507 if (ep.status) { 508 if (link != NULL) { 509 switch (ep.status) { 510 case 0x04: /* "Page Timeout" */ 511 err = EHOSTDOWN; 512 break; 513 514 case 0x08: /* "Connection Timed Out" */ 515 err = ETIMEDOUT; 516 break; 517 518 case 0x16: /* "Connection Terminated by Local Host" */ 519 err = 0; 520 break; 521 522 default: 523 err = ECONNREFUSED; 524 break; 525 } 526 527 hci_link_free(link, err); 528 } 529 530 return; 531 } 532 533 if (link == NULL) { 534 hci_discon_cp dp; 535 536 dp.con_handle = ep.con_handle; 537 dp.reason = 0x13; /* "Remote User Terminated Connection" */ 538 539 hci_send_cmd(unit, HCI_CMD_DISCONNECT, &dp, sizeof(dp)); 540 return; 541 } 542 543 /* XXX could check auth_enable here */ 544 545 if (ep.encryption_mode) 546 link->hl_flags |= (HCI_LINK_AUTH | HCI_LINK_ENCRYPT); 547 548 link->hl_state = HCI_LINK_OPEN; 549 link->hl_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 550 551 if (ep.link_type == HCI_LINK_ACL) { 552 cp.con_handle = ep.con_handle; 553 cp.settings = htole16(unit->hci_link_policy); 554 err = hci_send_cmd(unit, HCI_CMD_WRITE_LINK_POLICY_SETTINGS, 555 &cp, sizeof(cp)); 556 if (err) 557 aprint_error_dev(unit->hci_dev, 558 "Warning, could not write link policy\n"); 559 560 err = hci_send_cmd(unit, HCI_CMD_READ_CLOCK_OFFSET, 561 &cp.con_handle, sizeof(cp.con_handle)); 562 if (err) 563 aprint_error_dev(unit->hci_dev, 564 "Warning, could not read clock offset\n"); 565 566 err = hci_acl_setmode(link); 567 if (err == EINPROGRESS) 568 return; 569 570 hci_acl_linkmode(link); 571 } else { 572 (*link->hl_sco->sp_proto->connected)(link->hl_sco->sp_upper); 573 } 574 } 575 576 /* 577 * Disconnection Complete 578 * 579 * This is sent in response to a disconnection request, but also if 580 * the remote device goes out of range. 581 */ 582 static void 583 hci_event_discon_compl(struct hci_unit *unit, struct mbuf *m) 584 { 585 hci_discon_compl_ep ep; 586 struct hci_link *link; 587 588 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 589 m_copydata(m, 0, sizeof(ep), &ep); 590 m_adj(m, sizeof(ep)); 591 592 ep.con_handle = le16toh(ep.con_handle); 593 594 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status); 595 596 link = hci_link_lookup_handle(unit, HCI_CON_HANDLE(ep.con_handle)); 597 if (link) 598 hci_link_free(link, ENOLINK); 599 } 600 601 /* 602 * Connect Request 603 * 604 * We check upstream for appropriate listeners and accept connections 605 * that are wanted. 606 */ 607 static void 608 hci_event_con_req(struct hci_unit *unit, struct mbuf *m) 609 { 610 hci_con_req_ep ep; 611 hci_accept_con_cp ap; 612 hci_reject_con_cp rp; 613 struct hci_link *link; 614 615 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 616 m_copydata(m, 0, sizeof(ep), &ep); 617 m_adj(m, sizeof(ep)); 618 619 DPRINTFN(1, "bdaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 620 "class %2.2x%2.2x%2.2x type %s\n", 621 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3], 622 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0], 623 ep.uclass[0], ep.uclass[1], ep.uclass[2], 624 ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"); 625 626 if (ep.link_type == HCI_LINK_ACL) 627 link = hci_acl_newconn(unit, &ep.bdaddr); 628 else 629 link = hci_sco_newconn(unit, &ep.bdaddr); 630 631 if (link == NULL) { 632 memset(&rp, 0, sizeof(rp)); 633 bdaddr_copy(&rp.bdaddr, &ep.bdaddr); 634 rp.reason = 0x0f; /* Unacceptable BD_ADDR */ 635 636 hci_send_cmd(unit, HCI_CMD_REJECT_CON, &rp, sizeof(rp)); 637 } else { 638 memset(&ap, 0, sizeof(ap)); 639 bdaddr_copy(&ap.bdaddr, &ep.bdaddr); 640 if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH) 641 ap.role = HCI_ROLE_MASTER; 642 else 643 ap.role = HCI_ROLE_SLAVE; 644 645 hci_send_cmd(unit, HCI_CMD_ACCEPT_CON, &ap, sizeof(ap)); 646 } 647 } 648 649 /* 650 * Auth Complete 651 * 652 * Authentication has been completed on an ACL link. We can notify the 653 * upper layer protocols unless further mode changes are pending. 654 */ 655 static void 656 hci_event_auth_compl(struct hci_unit *unit, struct mbuf *m) 657 { 658 hci_auth_compl_ep ep; 659 struct hci_link *link; 660 int err; 661 662 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 663 m_copydata(m, 0, sizeof(ep), &ep); 664 m_adj(m, sizeof(ep)); 665 666 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 667 668 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status); 669 670 link = hci_link_lookup_handle(unit, ep.con_handle); 671 if (link == NULL || link->hl_type != HCI_LINK_ACL) 672 return; 673 674 if (ep.status == 0) { 675 link->hl_flags |= HCI_LINK_AUTH; 676 677 if (link->hl_state == HCI_LINK_WAIT_AUTH) 678 link->hl_state = HCI_LINK_OPEN; 679 680 err = hci_acl_setmode(link); 681 if (err == EINPROGRESS) 682 return; 683 } 684 685 hci_acl_linkmode(link); 686 } 687 688 /* 689 * Encryption Change 690 * 691 * The encryption status has changed. Basically, we note the change 692 * then notify the upper layer protocol unless further mode changes 693 * are pending. 694 * Note that if encryption gets disabled when it has been requested, 695 * we will attempt to enable it again.. (its a feature not a bug :) 696 */ 697 static void 698 hci_event_encryption_change(struct hci_unit *unit, struct mbuf *m) 699 { 700 hci_encryption_change_ep ep; 701 struct hci_link *link; 702 int err; 703 704 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 705 m_copydata(m, 0, sizeof(ep), &ep); 706 m_adj(m, sizeof(ep)); 707 708 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 709 710 DPRINTFN(1, "handle #%d, status=0x%x, encryption_enable=0x%x\n", 711 ep.con_handle, ep.status, ep.encryption_enable); 712 713 link = hci_link_lookup_handle(unit, ep.con_handle); 714 if (link == NULL || link->hl_type != HCI_LINK_ACL) 715 return; 716 717 if (ep.status == 0) { 718 if (ep.encryption_enable == 0) 719 link->hl_flags &= ~HCI_LINK_ENCRYPT; 720 else 721 link->hl_flags |= (HCI_LINK_AUTH | HCI_LINK_ENCRYPT); 722 723 if (link->hl_state == HCI_LINK_WAIT_ENCRYPT) 724 link->hl_state = HCI_LINK_OPEN; 725 726 err = hci_acl_setmode(link); 727 if (err == EINPROGRESS) 728 return; 729 } 730 731 hci_acl_linkmode(link); 732 } 733 734 /* 735 * Change Connection Link Key Complete 736 * 737 * Link keys are handled in userland but if we are waiting to secure 738 * this link, we should notify the upper protocols. A SECURE request 739 * only needs a single key change, so we can cancel the request. 740 */ 741 static void 742 hci_event_change_con_link_key_compl(struct hci_unit *unit, struct mbuf *m) 743 { 744 hci_change_con_link_key_compl_ep ep; 745 struct hci_link *link; 746 int err; 747 748 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 749 m_copydata(m, 0, sizeof(ep), &ep); 750 m_adj(m, sizeof(ep)); 751 752 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 753 754 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status); 755 756 link = hci_link_lookup_handle(unit, ep.con_handle); 757 if (link == NULL || link->hl_type != HCI_LINK_ACL) 758 return; 759 760 link->hl_flags &= ~HCI_LINK_SECURE_REQ; 761 762 if (ep.status == 0) { 763 link->hl_flags |= (HCI_LINK_AUTH | HCI_LINK_SECURE); 764 765 if (link->hl_state == HCI_LINK_WAIT_SECURE) 766 link->hl_state = HCI_LINK_OPEN; 767 768 err = hci_acl_setmode(link); 769 if (err == EINPROGRESS) 770 return; 771 } 772 773 hci_acl_linkmode(link); 774 } 775 776 /* 777 * Read Clock Offset Complete 778 * 779 * We keep a note of the clock offset of remote devices when a 780 * link is made, in order to facilitate reconnections to the device 781 */ 782 static void 783 hci_event_read_clock_offset_compl(struct hci_unit *unit, struct mbuf *m) 784 { 785 hci_read_clock_offset_compl_ep ep; 786 struct hci_link *link; 787 788 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 789 m_copydata(m, 0, sizeof(ep), &ep); 790 m_adj(m, sizeof(ep)); 791 792 DPRINTFN(1, "handle #%d, offset=%u, status=0x%x\n", 793 le16toh(ep.con_handle), le16toh(ep.clock_offset), ep.status); 794 795 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 796 link = hci_link_lookup_handle(unit, ep.con_handle); 797 798 if (ep.status != 0 || link == NULL) 799 return; 800 801 link->hl_clock = ep.clock_offset; 802 } 803 804 /* 805 * process results of read_bdaddr command_complete event 806 */ 807 static void 808 hci_cmd_read_bdaddr(struct hci_unit *unit, struct mbuf *m) 809 { 810 hci_read_bdaddr_rp rp; 811 int s; 812 813 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 814 m_copydata(m, 0, sizeof(rp), &rp); 815 m_adj(m, sizeof(rp)); 816 817 if (rp.status > 0) 818 return; 819 820 if ((unit->hci_flags & BTF_INIT_BDADDR) == 0) 821 return; 822 823 bdaddr_copy(&unit->hci_bdaddr, &rp.bdaddr); 824 825 s = splraiseipl(unit->hci_ipl); 826 unit->hci_flags &= ~BTF_INIT_BDADDR; 827 splx(s); 828 829 wakeup(unit); 830 } 831 832 /* 833 * process results of read_buffer_size command_complete event 834 */ 835 static void 836 hci_cmd_read_buffer_size(struct hci_unit *unit, struct mbuf *m) 837 { 838 hci_read_buffer_size_rp rp; 839 int s; 840 841 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 842 m_copydata(m, 0, sizeof(rp), &rp); 843 m_adj(m, sizeof(rp)); 844 845 if (rp.status > 0) 846 return; 847 848 if ((unit->hci_flags & BTF_INIT_BUFFER_SIZE) == 0) 849 return; 850 851 unit->hci_max_acl_size = le16toh(rp.max_acl_size); 852 unit->hci_num_acl_pkts = le16toh(rp.num_acl_pkts); 853 unit->hci_max_sco_size = rp.max_sco_size; 854 unit->hci_num_sco_pkts = le16toh(rp.num_sco_pkts); 855 856 s = splraiseipl(unit->hci_ipl); 857 unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE; 858 splx(s); 859 860 wakeup(unit); 861 } 862 863 /* 864 * process results of read_local_features command_complete event 865 */ 866 static void 867 hci_cmd_read_local_features(struct hci_unit *unit, struct mbuf *m) 868 { 869 hci_read_local_features_rp rp; 870 int s; 871 872 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 873 m_copydata(m, 0, sizeof(rp), &rp); 874 m_adj(m, sizeof(rp)); 875 876 if (rp.status > 0) 877 return; 878 879 if ((unit->hci_flags & BTF_INIT_FEATURES) == 0) 880 return; 881 882 unit->hci_lmp_mask = 0; 883 884 if (rp.features[0] & HCI_LMP_ROLE_SWITCH) 885 unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH; 886 887 if (rp.features[0] & HCI_LMP_HOLD_MODE) 888 unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_HOLD_MODE; 889 890 if (rp.features[0] & HCI_LMP_SNIFF_MODE) 891 unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE; 892 893 if (rp.features[1] & HCI_LMP_PARK_MODE) 894 unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_PARK_MODE; 895 896 /* ACL packet mask */ 897 unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1; 898 899 if (rp.features[0] & HCI_LMP_3SLOT) 900 unit->hci_acl_mask |= HCI_PKT_DM3 | HCI_PKT_DH3; 901 902 if (rp.features[0] & HCI_LMP_5SLOT) 903 unit->hci_acl_mask |= HCI_PKT_DM5 | HCI_PKT_DH5; 904 905 if ((rp.features[3] & HCI_LMP_EDR_ACL_2MBPS) == 0) 906 unit->hci_acl_mask |= HCI_PKT_2MBPS_DH1 907 | HCI_PKT_2MBPS_DH3 908 | HCI_PKT_2MBPS_DH5; 909 910 if ((rp.features[3] & HCI_LMP_EDR_ACL_3MBPS) == 0) 911 unit->hci_acl_mask |= HCI_PKT_3MBPS_DH1 912 | HCI_PKT_3MBPS_DH3 913 | HCI_PKT_3MBPS_DH5; 914 915 if ((rp.features[4] & HCI_LMP_3SLOT_EDR_ACL) == 0) 916 unit->hci_acl_mask |= HCI_PKT_2MBPS_DH3 917 | HCI_PKT_3MBPS_DH3; 918 919 if ((rp.features[5] & HCI_LMP_5SLOT_EDR_ACL) == 0) 920 unit->hci_acl_mask |= HCI_PKT_2MBPS_DH5 921 | HCI_PKT_3MBPS_DH5; 922 923 unit->hci_packet_type = unit->hci_acl_mask; 924 925 /* SCO packet mask */ 926 unit->hci_sco_mask = 0; 927 if (rp.features[1] & HCI_LMP_SCO_LINK) 928 unit->hci_sco_mask |= HCI_PKT_HV1; 929 930 if (rp.features[1] & HCI_LMP_HV2_PKT) 931 unit->hci_sco_mask |= HCI_PKT_HV2; 932 933 if (rp.features[1] & HCI_LMP_HV3_PKT) 934 unit->hci_sco_mask |= HCI_PKT_HV3; 935 936 if (rp.features[3] & HCI_LMP_EV3_PKT) 937 unit->hci_sco_mask |= HCI_PKT_EV3; 938 939 if (rp.features[4] & HCI_LMP_EV4_PKT) 940 unit->hci_sco_mask |= HCI_PKT_EV4; 941 942 if (rp.features[4] & HCI_LMP_EV5_PKT) 943 unit->hci_sco_mask |= HCI_PKT_EV5; 944 945 /* XXX what do 2MBPS/3MBPS/3SLOT eSCO mean? */ 946 947 s = splraiseipl(unit->hci_ipl); 948 unit->hci_flags &= ~BTF_INIT_FEATURES; 949 splx(s); 950 951 wakeup(unit); 952 953 DPRINTFN(1, "%s: lmp_mask %4.4x, acl_mask %4.4x, sco_mask %4.4x\n", 954 device_xname(unit->hci_dev), unit->hci_lmp_mask, 955 unit->hci_acl_mask, unit->hci_sco_mask); 956 } 957 958 /* 959 * process results of reset command_complete event 960 * 961 * This has killed all the connections, so close down anything we have left, 962 * and reinitialise the unit. 963 */ 964 static void 965 hci_cmd_reset(struct hci_unit *unit, struct mbuf *m) 966 { 967 hci_reset_rp rp; 968 struct hci_link *link, *next; 969 int acl; 970 971 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 972 m_copydata(m, 0, sizeof(rp), &rp); 973 m_adj(m, sizeof(rp)); 974 975 if (rp.status != 0) 976 return; 977 978 /* 979 * release SCO links first, since they may be holding 980 * an ACL link reference. 981 */ 982 for (acl = 0 ; acl < 2 ; acl++) { 983 next = TAILQ_FIRST(&unit->hci_links); 984 while ((link = next) != NULL) { 985 next = TAILQ_NEXT(link, hl_next); 986 if (acl || link->hl_type != HCI_LINK_ACL) 987 hci_link_free(link, ECONNABORTED); 988 } 989 } 990 991 unit->hci_num_acl_pkts = 0; 992 unit->hci_num_sco_pkts = 0; 993 994 if (hci_send_cmd(unit, HCI_CMD_READ_BDADDR, NULL, 0)) 995 return; 996 997 if (hci_send_cmd(unit, HCI_CMD_READ_BUFFER_SIZE, NULL, 0)) 998 return; 999 1000 if (hci_send_cmd(unit, HCI_CMD_READ_LOCAL_FEATURES, NULL, 0)) 1001 return; 1002 } 1003