1 /* $NetBSD: hci_link.c,v 1.1 2006/06/19 15:44:45 gdamore 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_link.c,v 1.1 2006/06/19 15:44:45 gdamore 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/queue.h> 42 #include <sys/systm.h> 43 44 #include <netbt/bluetooth.h> 45 #include <netbt/hci.h> 46 #include <netbt/sco.h> 47 #include <netbt/l2cap.h> 48 49 /******************************************************************************* 50 * 51 * HCI ACL Connections 52 */ 53 54 /* 55 * Automatically expire unused ACL connections after this number of 56 * seconds (if zero, do not expire unused connections) [sysctl] 57 */ 58 int hci_acl_expiry = 10; /* seconds */ 59 60 /* 61 * hci_acl_open(unit, bdaddr) 62 * 63 * open ACL connection to remote bdaddr. Only one ACL connection is permitted 64 * between any two Bluetooth devices, so we look for an existing one before 65 * trying to start a new one. 66 */ 67 struct hci_link * 68 hci_acl_open(struct hci_unit *unit, bdaddr_t *bdaddr) 69 { 70 struct hci_link *link; 71 hci_create_con_cp cp; 72 int err; 73 74 KASSERT(unit); 75 KASSERT(bdaddr); 76 77 link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL); 78 if (link == NULL) { 79 link = hci_link_alloc(unit); 80 if (link == NULL) 81 return NULL; 82 83 link->hl_type = HCI_LINK_ACL; 84 bdaddr_copy(&link->hl_bdaddr, bdaddr); 85 } 86 87 switch(link->hl_state) { 88 case HCI_LINK_CLOSED: 89 /* 90 * open connection to remote device 91 */ 92 memset(&cp, 0, sizeof(cp)); 93 bdaddr_copy(&cp.bdaddr, bdaddr); 94 cp.pkt_type = htole16(unit->hci_packet_type); 95 if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH) 96 cp.accept_role_switch = 1; 97 98 err = hci_send_cmd(unit, HCI_CMD_CREATE_CON, &cp, sizeof(cp)); 99 if (err) { 100 hci_link_free(link, err); 101 return NULL; 102 } 103 104 link->hl_state = HCI_LINK_WAIT_CONNECT; 105 break; 106 107 case HCI_LINK_WAIT_CONNECT: 108 /* 109 * somebody else already trying to connect, we just 110 * sit on the bench with them.. 111 */ 112 break; 113 114 case HCI_LINK_OPEN: 115 /* 116 * If already open, halt any expiry timeouts. We dont need 117 * to care about already invoking timeouts since refcnt >0 118 * will keep the link alive. 119 */ 120 callout_stop(&link->hl_expire); 121 break; 122 123 default: 124 UNKNOWN(link->hl_state); 125 return NULL; 126 } 127 128 /* open */ 129 link->hl_refcnt++; 130 131 return link; 132 } 133 134 /* 135 * Close ACL connection. When there are no more references to this link, 136 * we can either close it down or schedule a delayed closedown. 137 */ 138 void 139 hci_acl_close(struct hci_link *link, int err) 140 { 141 142 KASSERT(link); 143 144 if (--link->hl_refcnt == 0) { 145 if (link->hl_state == HCI_LINK_CLOSED) 146 hci_link_free(link, err); 147 else if (hci_acl_expiry > 0) 148 callout_schedule(&link->hl_expire, hci_acl_expiry * hz); 149 } 150 } 151 152 /* 153 * Incoming ACL connection. For now, we accept all connections but it 154 * would be better to check the L2CAP listen list and only accept when 155 * there is a listener available. 156 */ 157 struct hci_link * 158 hci_acl_newconn(struct hci_unit *unit, bdaddr_t *bdaddr) 159 { 160 struct hci_link *link; 161 162 link = hci_link_alloc(unit); 163 if (link != NULL) { 164 link->hl_state = HCI_LINK_WAIT_CONNECT; 165 link->hl_type = HCI_LINK_ACL; 166 bdaddr_copy(&link->hl_bdaddr, bdaddr); 167 168 if (hci_acl_expiry > 0) 169 callout_schedule(&link->hl_expire, hci_acl_expiry * hz); 170 } 171 172 return link; 173 } 174 175 void 176 hci_acl_timeout(void *arg) 177 { 178 struct hci_link *link = arg; 179 hci_discon_cp cp; 180 int s, err; 181 182 s = splsoftnet(); 183 callout_ack(&link->hl_expire); 184 185 if (link->hl_refcnt > 0) 186 goto out; 187 188 DPRINTF("link #%d expired\n", link->hl_handle); 189 190 switch (link->hl_state) { 191 case HCI_LINK_CLOSED: 192 case HCI_LINK_WAIT_CONNECT: 193 hci_link_free(link, ECONNRESET); 194 break; 195 196 case HCI_LINK_OPEN: 197 cp.con_handle = htole16(link->hl_handle); 198 cp.reason = 0x13; /* "Remote User Terminated Connection" */ 199 200 err = hci_send_cmd(link->hl_unit, HCI_CMD_DISCONNECT, 201 &cp, sizeof(cp)); 202 203 if (err) 204 DPRINTF("error %d sending HCI_CMD_DISCONNECT\n", 205 err); 206 207 break; 208 209 default: 210 UNKNOWN(link->hl_state); 211 break; 212 } 213 214 out: 215 splx(s); 216 } 217 218 /* 219 * Receive ACL Data 220 * 221 * we accumulate packet fragments on the hci_link structure 222 * until a full L2CAP frame is ready, then send it on. 223 */ 224 void 225 hci_acl_recv(struct mbuf *m, struct hci_unit *unit) 226 { 227 struct hci_link *link; 228 hci_acldata_hdr_t hdr; 229 uint16_t handle, want; 230 int pb, got; 231 232 KASSERT(m); 233 KASSERT(unit); 234 235 KASSERT(m->m_pkthdr.len >= sizeof(hdr)); 236 m_copydata(m, 0, sizeof(hdr), &hdr); 237 m_adj(m, sizeof(hdr)); 238 239 #ifdef DIAGNOSTIC 240 if (hdr.type != HCI_ACL_DATA_PKT) { 241 printf("%s: bad ACL packet type\n", unit->hci_devname); 242 goto bad; 243 } 244 245 if (m->m_pkthdr.len != le16toh(hdr.length)) { 246 printf("%s: bad ACL packet length\n", unit->hci_devname); 247 goto bad; 248 } 249 #endif 250 251 hdr.length = le16toh(hdr.length); 252 hdr.con_handle = le16toh(hdr.con_handle); 253 handle = HCI_CON_HANDLE(hdr.con_handle); 254 pb = HCI_PB_FLAG(hdr.con_handle); 255 256 link = hci_link_lookup_handle(unit, handle); 257 if (link == NULL) { 258 hci_discon_cp cp; 259 260 DPRINTF("%s: dumping packet for unknown handle #%d\n", 261 unit->hci_devname, handle); 262 263 /* 264 * There is no way to find out what this connection handle is 265 * for, just get rid of it. This may happen, if a USB dongle 266 * is plugged into a self powered hub and does not reset when 267 * the system is shut down. 268 */ 269 cp.con_handle = htole16(handle); 270 cp.reason = 0x13; /* "Remote User Terminated Connection" */ 271 hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp)); 272 goto bad; 273 } 274 275 switch (pb) { 276 case HCI_PACKET_START: 277 if (link->hl_rxp != NULL) 278 printf("%s: dropped incomplete ACL packet\n", 279 unit->hci_devname); 280 281 if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) { 282 printf("%s: short ACL packet\n", 283 unit->hci_devname); 284 285 goto bad; 286 } 287 288 link->hl_rxp = m; 289 got = m->m_pkthdr.len; 290 break; 291 292 case HCI_PACKET_FRAGMENT: 293 if (link->hl_rxp == NULL) { 294 printf("%s: unexpected packet fragment\n", 295 unit->hci_devname); 296 297 goto bad; 298 } 299 300 got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len; 301 m_cat(link->hl_rxp, m); 302 m = link->hl_rxp; 303 m->m_pkthdr.len = got; 304 break; 305 306 default: 307 printf("%s: unknown packet type\n", 308 unit->hci_devname); 309 310 goto bad; 311 } 312 313 m_copydata(m, 0, sizeof(want), &want); 314 want = le16toh(want) + sizeof(l2cap_hdr_t) - got; 315 316 if (want > 0) 317 return; 318 319 link->hl_rxp = NULL; 320 321 if (want == 0) { 322 l2cap_recv_frame(m, link); 323 return; 324 } 325 326 bad: 327 m_freem(m); 328 } 329 330 /* 331 * Send ACL data on link 332 * 333 * We must fragment packets into chunks of less than unit->hci_max_acl_size and 334 * prepend a relevant ACL header to each fragment. We keep a PDU structure 335 * attached to the link, so that completed fragments can be marked off and 336 * more data requested from above once the PDU is sent. 337 */ 338 int 339 hci_acl_send(struct mbuf *m, struct hci_link *link, 340 struct l2cap_channel *chan) 341 { 342 struct l2cap_pdu *pdu; 343 struct mbuf *n = NULL; 344 int plen, mlen, num = 0; 345 346 KASSERT(link); 347 KASSERT(m); 348 KASSERT(m->m_flags & M_PKTHDR); 349 KASSERT(m->m_pkthdr.len > 0); 350 351 if (link->hl_state == HCI_LINK_CLOSED) { 352 m_freem(m); 353 return ENETDOWN; 354 } 355 356 pdu = pool_get(&l2cap_pdu_pool, PR_NOWAIT); 357 if (pdu == NULL) 358 goto nomem; 359 360 pdu->lp_chan = chan; 361 pdu->lp_pending = 0; 362 MBUFQ_INIT(&pdu->lp_data); 363 364 plen = m->m_pkthdr.len; 365 mlen = link->hl_unit->hci_max_acl_size; 366 367 DPRINTFN(5, "%s: handle #%d, plen = %d, max = %d\n", 368 link->hl_unit->hci_devname, link->hl_handle, plen, mlen); 369 370 while (plen > 0) { 371 if (plen > mlen) { 372 n = m_split(m, mlen, M_DONTWAIT); 373 if (n == NULL) 374 goto nomem; 375 } else { 376 mlen = plen; 377 } 378 379 if (num++ == 0) 380 m->m_flags |= M_PROTO1; /* tag first fragment */ 381 382 DPRINTFN(10, "chunk of %d (plen = %d) bytes\n", mlen, plen); 383 MBUFQ_ENQUEUE(&pdu->lp_data, m); 384 m = n; 385 plen -= mlen; 386 } 387 388 TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next); 389 link->hl_txqlen += num; 390 391 hci_acl_start(link); 392 393 return 0; 394 395 nomem: 396 if (m) m_freem(m); 397 if (n) m_freem(n); 398 if (pdu) { 399 MBUFQ_DRAIN(&pdu->lp_data); 400 pool_put(&l2cap_pdu_pool, pdu); 401 } 402 403 return ENOMEM; 404 } 405 406 /* 407 * Start sending ACL data on link. 408 * 409 * We may use all the available packet slots. The reason that we add 410 * the ACL encapsulation here rather than in hci_acl_send() is that L2CAP 411 * signal packets may be queued before the handle is given to us.. 412 * 413 * this is called from hci_acl_send() above, and the event processing 414 * code (for CON_COMPL and NUM_COMPL_PKTS) 415 */ 416 void 417 hci_acl_start(struct hci_link *link) 418 { 419 struct hci_unit *unit; 420 hci_acldata_hdr_t *hdr; 421 struct l2cap_pdu *pdu; 422 struct mbuf *m; 423 uint16_t handle; 424 425 KASSERT(link); 426 427 unit = link->hl_unit; 428 KASSERT(unit); 429 430 /* this is mainly to block ourselves (below) */ 431 if (link->hl_state != HCI_LINK_OPEN) 432 return; 433 434 if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0) 435 return; 436 437 /* find first PDU with data to send */ 438 pdu = TAILQ_FIRST(&link->hl_txq); 439 for (;;) { 440 if (pdu == NULL) 441 return; 442 443 if (MBUFQ_FIRST(&pdu->lp_data) != NULL) 444 break; 445 446 pdu = TAILQ_NEXT(pdu, lp_next); 447 } 448 449 while (unit->hci_num_acl_pkts > 0) { 450 MBUFQ_DEQUEUE(&pdu->lp_data, m); 451 KASSERT(m != NULL); 452 453 if (m->m_flags & M_PROTO1) 454 handle = HCI_MK_CON_HANDLE(link->hl_handle, 455 HCI_PACKET_START, 0); 456 else 457 handle = HCI_MK_CON_HANDLE(link->hl_handle, 458 HCI_PACKET_FRAGMENT, 0); 459 460 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); 461 if (m == NULL) 462 break; 463 464 hdr = mtod(m, hci_acldata_hdr_t *); 465 hdr->type = HCI_ACL_DATA_PKT; 466 hdr->con_handle = htole16(handle); 467 hdr->length = htole16(m->m_pkthdr.len - sizeof(*hdr)); 468 469 link->hl_txqlen--; 470 pdu->lp_pending++; 471 472 hci_output_acl(unit, m); 473 474 if (MBUFQ_FIRST(&pdu->lp_data) == NULL) { 475 if (pdu->lp_chan) { 476 /* 477 * This should enable streaming of PDUs - when 478 * we have placed all the fragments on the acl 479 * output queue, we trigger the L2CAP layer to 480 * send us down one more. Use a false state so 481 * we dont run into ourselves coming back from 482 * the future.. 483 */ 484 link->hl_state = HCI_LINK_BLOCK; 485 l2cap_start(pdu->lp_chan); 486 link->hl_state = HCI_LINK_OPEN; 487 } 488 489 pdu = TAILQ_NEXT(pdu, lp_next); 490 if (pdu == NULL) 491 break; 492 } 493 } 494 495 /* 496 * We had our turn now, move to the back of the queue to let 497 * other links have a go at the output buffers.. 498 */ 499 if (TAILQ_NEXT(link, hl_next)) { 500 TAILQ_REMOVE(&unit->hci_links, link, hl_next); 501 TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next); 502 } 503 } 504 505 /* 506 * Confirm ACL packets cleared from Controller buffers. We scan our PDU 507 * list to clear pending fragments and signal upstream for more data 508 * when a PDU is complete. 509 */ 510 void 511 hci_acl_complete(struct hci_link *link, int num) 512 { 513 struct l2cap_pdu *pdu; 514 struct l2cap_channel *chan; 515 516 DPRINTFN(5, "handle #%d (%d)\n", link->hl_handle, num); 517 518 while (num > 0) { 519 pdu = TAILQ_FIRST(&link->hl_txq); 520 if (pdu == NULL) { 521 printf("%s: %d packets completed on handle #%x " 522 "but none pending!\n", 523 link->hl_unit->hci_devname, num, 524 link->hl_handle); 525 return; 526 } 527 528 if (num >= pdu->lp_pending) { 529 num -= pdu->lp_pending; 530 pdu->lp_pending = 0; 531 532 if (MBUFQ_FIRST(&pdu->lp_data) == NULL) { 533 TAILQ_REMOVE(&link->hl_txq, pdu, lp_next); 534 chan = pdu->lp_chan; 535 if (chan != NULL) { 536 chan->lc_pending--; 537 (*chan->lc_proto->complete) 538 (chan->lc_upper, 1); 539 540 if (chan->lc_pending == 0) 541 l2cap_start(chan); 542 } 543 544 pool_put(&l2cap_pdu_pool, pdu); 545 } 546 } else { 547 pdu->lp_pending -= num; 548 num = 0; 549 } 550 } 551 } 552 553 /******************************************************************************* 554 * 555 * HCI SCO Connections 556 */ 557 558 /* 559 * Incoming SCO Connection. Not yet implemented 560 */ 561 struct hci_link * 562 hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr) 563 { 564 565 return NULL; 566 } 567 568 /* 569 * receive SCO packet, we only need to strip the header and send 570 * it to the right handler 571 */ 572 void 573 hci_sco_recv(struct mbuf *m, struct hci_unit *unit) 574 { 575 struct hci_link *link; 576 hci_scodata_hdr_t hdr; 577 uint16_t handle; 578 579 KASSERT(m); 580 KASSERT(unit); 581 582 KASSERT(m->m_pkthdr.len >= sizeof(hdr)); 583 m_copydata(m, 0, sizeof(hdr), &hdr); 584 m_adj(m, sizeof(hdr)); 585 586 #ifdef DIAGNOSTIC 587 if (hdr.type != HCI_SCO_DATA_PKT) { 588 printf("%s: bad SCO packet type\n", unit->hci_devname); 589 goto bad; 590 } 591 592 if (m->m_pkthdr.len != hdr.length) { 593 printf("%s: bad SCO packet length (%d != %d)\n", unit->hci_devname, m->m_pkthdr.len, hdr.length); 594 goto bad; 595 } 596 #endif 597 598 hdr.con_handle = le16toh(hdr.con_handle); 599 handle = HCI_CON_HANDLE(hdr.con_handle); 600 601 link = hci_link_lookup_handle(unit, handle); 602 if (link == NULL || link->hl_type == HCI_LINK_ACL) { 603 DPRINTF("%s: dumping packet for unknown handle #%d\n", 604 unit->hci_devname, handle); 605 606 goto bad; 607 } 608 609 (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m); 610 return; 611 612 bad: 613 m_freem(m); 614 } 615 616 void 617 hci_sco_start(struct hci_link *link) 618 { 619 } 620 621 /* 622 * SCO packets have completed at the controller, so we can 623 * signal up to free the buffer space. 624 */ 625 void 626 hci_sco_complete(struct hci_link *link, int num) 627 { 628 629 DPRINTFN(5, "handle #%d (num=%d)\n", link->hl_handle, num); 630 link->hl_sco->sp_pending--; 631 (*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num); 632 } 633 634 /******************************************************************************* 635 * 636 * Generic HCI Connection alloc/free/lookup etc 637 */ 638 639 struct hci_link * 640 hci_link_alloc(struct hci_unit *unit) 641 { 642 struct hci_link *link; 643 644 KASSERT(unit); 645 646 link = malloc(sizeof(struct hci_link), M_BLUETOOTH, M_NOWAIT | M_ZERO); 647 if (link == NULL) 648 return NULL; 649 650 link->hl_unit = unit; 651 link->hl_state = HCI_LINK_CLOSED; 652 653 /* init ACL portion */ 654 callout_init(&link->hl_expire); 655 callout_setfunc(&link->hl_expire, hci_acl_timeout, link); 656 657 TAILQ_INIT(&link->hl_txq); /* outgoing packets */ 658 TAILQ_INIT(&link->hl_reqs); /* request queue */ 659 660 link->hl_mtu = L2CAP_MTU_DEFAULT; /* L2CAP signal mtu */ 661 link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT; /* flush timeout */ 662 663 /* init SCO portion */ 664 MBUFQ_INIT(&link->hl_data); 665 666 /* attach to unit */ 667 TAILQ_INSERT_HEAD(&unit->hci_links, link, hl_next); 668 return link; 669 } 670 671 void 672 hci_link_free(struct hci_link *link, int err) 673 { 674 struct l2cap_req *req; 675 struct l2cap_pdu *pdu; 676 struct l2cap_channel *chan; 677 678 KASSERT(link); 679 680 DPRINTF("#%d, type = %d, state = %d, refcnt = %d\n", 681 link->hl_handle, link->hl_type, 682 link->hl_state, link->hl_refcnt); 683 684 /* ACL reference count */ 685 if (link->hl_refcnt > 0) { 686 LIST_FOREACH(chan, &l2cap_active_list, lc_ncid) { 687 if (chan->lc_link == link) 688 l2cap_close(chan, err); 689 } 690 } 691 KASSERT(link->hl_refcnt == 0); 692 693 /* ACL L2CAP requests.. */ 694 while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL) 695 l2cap_request_free(req); 696 697 KASSERT(TAILQ_EMPTY(&link->hl_reqs)); 698 699 /* ACL outgoing data queue */ 700 while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) { 701 TAILQ_REMOVE(&link->hl_txq, pdu, lp_next); 702 MBUFQ_DRAIN(&pdu->lp_data); 703 if (pdu->lp_pending) 704 link->hl_unit->hci_num_acl_pkts += pdu->lp_pending; 705 706 pool_put(&l2cap_pdu_pool, pdu); 707 } 708 709 KASSERT(TAILQ_EMPTY(&link->hl_txq)); 710 711 /* ACL incoming data packet */ 712 if (link->hl_rxp != NULL) { 713 m_freem(link->hl_rxp); 714 link->hl_rxp = NULL; 715 } 716 717 /* SCO master ACL link */ 718 if (link->hl_link != NULL) { 719 hci_acl_close(link->hl_link, err); 720 link->hl_link = NULL; 721 } 722 723 /* SCO pcb */ 724 if (link->hl_sco != NULL) { 725 struct sco_pcb *pcb; 726 727 pcb = link->hl_sco; 728 pcb->sp_link = NULL; 729 link->hl_sco = NULL; 730 (*pcb->sp_proto->disconnected)(pcb->sp_upper, err); 731 } 732 733 /* flush any SCO data */ 734 MBUFQ_DRAIN(&link->hl_data); 735 736 /* 737 * Halt the callout - if its already running we cannot free the 738 * link structure but the timeout function will call us back in 739 * any case. 740 */ 741 link->hl_state = HCI_LINK_CLOSED; 742 callout_stop(&link->hl_expire); 743 if (callout_invoking(&link->hl_expire)) 744 return; 745 746 TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next); 747 free(link, M_BLUETOOTH); 748 } 749 750 /* 751 * Lookup HCI link by address and type. Note that for SCO links there may 752 * be more than one link per address, so we only return links with no 753 * handle (ie new links) 754 */ 755 struct hci_link * 756 hci_link_lookup_bdaddr(struct hci_unit *unit, bdaddr_t *bdaddr, uint16_t type) 757 { 758 struct hci_link *link; 759 760 KASSERT(unit); 761 KASSERT(bdaddr); 762 763 TAILQ_FOREACH(link, &unit->hci_links, hl_next) { 764 if (link->hl_type != type) 765 continue; 766 767 if (type == HCI_LINK_SCO && link->hl_handle != 0) 768 continue; 769 770 if (bdaddr_same(&link->hl_bdaddr, bdaddr)) 771 break; 772 } 773 774 return link; 775 } 776 777 struct hci_link * 778 hci_link_lookup_handle(struct hci_unit *unit, uint16_t handle) 779 { 780 struct hci_link *link; 781 782 KASSERT(unit); 783 784 TAILQ_FOREACH(link, &unit->hci_links, hl_next) { 785 if (handle == link->hl_handle) 786 break; 787 } 788 789 return link; 790 } 791