This source file includes following definitions.
- hci_acl_open
- hci_acl_close
- hci_acl_newconn
- hci_acl_timeout
- hci_acl_setmode
- hci_acl_linkmode
- hci_acl_recv
- hci_acl_send
- hci_acl_start
- hci_acl_complete
- hci_sco_newconn
- hci_sco_recv
- hci_sco_start
- hci_sco_complete
- hci_link_alloc
- hci_link_free
- hci_link_lookup_state
- hci_link_lookup_bdaddr
- hci_link_lookup_handle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/cdefs.h>
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/l2cap.h>
47 #include <netbt/sco.h>
48
49
50
51
52
53
54
55
56
57
58 int hci_acl_expiry = 10;
59
60
61
62
63
64
65
66
67 struct hci_link *
68 hci_acl_open(struct hci_unit *unit, bdaddr_t *bdaddr)
69 {
70 struct hci_link *link;
71 struct hci_memo *memo;
72 hci_create_con_cp cp;
73 int err;
74
75 KASSERT(unit != NULL);
76 KASSERT(bdaddr != NULL);
77
78 link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
79 if (link == NULL) {
80 link = hci_link_alloc(unit);
81 if (link == NULL)
82 return NULL;
83
84 link->hl_type = HCI_LINK_ACL;
85 bdaddr_copy(&link->hl_bdaddr, bdaddr);
86 }
87
88 switch(link->hl_state) {
89 case HCI_LINK_CLOSED:
90
91
92
93 memset(&cp, 0, sizeof(cp));
94 bdaddr_copy(&cp.bdaddr, bdaddr);
95 cp.pkt_type = htole16(unit->hci_packet_type);
96
97 memo = hci_memo_find(unit, bdaddr);
98 if (memo != NULL) {
99 cp.page_scan_rep_mode = memo->response.page_scan_rep_mode;
100 cp.page_scan_mode = memo->response.page_scan_mode;
101 cp.clock_offset = htole16(memo->response.clock_offset);
102 }
103
104 if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH)
105 cp.accept_role_switch = 1;
106
107 err = hci_send_cmd(unit, HCI_CMD_CREATE_CON, &cp, sizeof(cp));
108 if (err) {
109 hci_link_free(link, err);
110 return NULL;
111 }
112
113 link->hl_state = HCI_LINK_WAIT_CONNECT;
114 break;
115
116 case HCI_LINK_WAIT_CONNECT:
117 case HCI_LINK_WAIT_AUTH:
118 case HCI_LINK_WAIT_ENCRYPT:
119 case HCI_LINK_WAIT_SECURE:
120
121
122
123
124 break;
125
126 case HCI_LINK_OPEN:
127
128
129
130
131
132 timeout_del(&link->hl_expire);
133 break;
134
135 default:
136 UNKNOWN(link->hl_state);
137 return NULL;
138 }
139
140
141 link->hl_refcnt++;
142
143 return link;
144 }
145
146
147
148
149
150 void
151 hci_acl_close(struct hci_link *link, int err)
152 {
153
154 KASSERT(link != NULL);
155
156 if (--link->hl_refcnt == 0) {
157 if (link->hl_state == HCI_LINK_CLOSED)
158 hci_link_free(link, err);
159 else if (hci_acl_expiry > 0)
160 timeout_add(&link->hl_expire, hci_acl_expiry * hz);
161 }
162 }
163
164
165
166
167
168
169
170
171
172
173
174 struct hci_link *
175 hci_acl_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
176 {
177 struct hci_link *link;
178
179 link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
180 if (link != NULL)
181 return NULL;
182
183 link = hci_link_alloc(unit);
184 if (link != NULL) {
185 link->hl_state = HCI_LINK_WAIT_CONNECT;
186 link->hl_type = HCI_LINK_ACL;
187 bdaddr_copy(&link->hl_bdaddr, bdaddr);
188
189 if (hci_acl_expiry > 0)
190 timeout_add(&link->hl_expire, hci_acl_expiry * hz);
191 }
192
193 return link;
194 }
195
196 void
197 hci_acl_timeout(void *arg)
198 {
199 struct hci_link *link = arg;
200 hci_discon_cp cp;
201 int s, err;
202
203 s = splsoftnet();
204
205 if (link->hl_refcnt > 0)
206 goto out;
207
208 DPRINTF("link #%d expired\n", link->hl_handle);
209
210 switch (link->hl_state) {
211 case HCI_LINK_CLOSED:
212 case HCI_LINK_WAIT_CONNECT:
213 hci_link_free(link, ECONNRESET);
214 break;
215
216 case HCI_LINK_WAIT_AUTH:
217 case HCI_LINK_WAIT_ENCRYPT:
218 case HCI_LINK_WAIT_SECURE:
219 case HCI_LINK_OPEN:
220 cp.con_handle = htole16(link->hl_handle);
221 cp.reason = 0x13;
222
223 err = hci_send_cmd(link->hl_unit, HCI_CMD_DISCONNECT,
224 &cp, sizeof(cp));
225
226 if (err) {
227 DPRINTF("error %d sending HCI_CMD_DISCONNECT\n",
228 err);
229 }
230
231 break;
232
233 default:
234 UNKNOWN(link->hl_state);
235 break;
236 }
237
238 out:
239 splx(s);
240 }
241
242
243
244
245 int
246 hci_acl_setmode(struct hci_link *link)
247 {
248 int err;
249
250 KASSERT(link != NULL);
251 KASSERT(link->hl_unit != NULL);
252
253 if (link->hl_state != HCI_LINK_OPEN)
254 return EINPROGRESS;
255
256 if ((link->hl_flags & HCI_LINK_AUTH_REQ)
257 && !(link->hl_flags & HCI_LINK_AUTH)) {
258 hci_auth_req_cp cp;
259
260 DPRINTF("requesting auth for handle #%d\n",
261 link->hl_handle);
262
263 link->hl_state = HCI_LINK_WAIT_AUTH;
264 cp.con_handle = htole16(link->hl_handle);
265 err = hci_send_cmd(link->hl_unit, HCI_CMD_AUTH_REQ,
266 &cp, sizeof(cp));
267
268 return (err == 0 ? EINPROGRESS : err);
269 }
270
271 if ((link->hl_flags & HCI_LINK_ENCRYPT_REQ)
272 && !(link->hl_flags & HCI_LINK_ENCRYPT)) {
273 hci_set_con_encryption_cp cp;
274
275
276
277 DPRINTF("requesting encryption for handle #%d\n",
278 link->hl_handle);
279
280 link->hl_state = HCI_LINK_WAIT_ENCRYPT;
281 cp.con_handle = htole16(link->hl_handle);
282 cp.encryption_enable = 0x01;
283
284 err = hci_send_cmd(link->hl_unit, HCI_CMD_SET_CON_ENCRYPTION,
285 &cp, sizeof(cp));
286
287 return (err == 0 ? EINPROGRESS : err);
288 }
289
290 if ((link->hl_flags & HCI_LINK_SECURE_REQ)) {
291 hci_change_con_link_key_cp cp;
292
293
294 link->hl_flags &= ~HCI_LINK_SECURE;
295
296 DPRINTF("changing link key for handle #%d\n",
297 link->hl_handle);
298
299 link->hl_state = HCI_LINK_WAIT_SECURE;
300 cp.con_handle = htole16(link->hl_handle);
301
302 err = hci_send_cmd(link->hl_unit, HCI_CMD_CHANGE_CON_LINK_KEY,
303 &cp, sizeof(cp));
304
305 return (err == 0 ? EINPROGRESS : err);
306 }
307
308 return 0;
309 }
310
311
312
313
314
315
316
317 void
318 hci_acl_linkmode(struct hci_link *link)
319 {
320 struct l2cap_channel *chan, *next;
321 int err, mode = 0;
322
323 DPRINTF("handle #%d, auth %s, encrypt %s, secure %s\n",
324 link->hl_handle,
325 (link->hl_flags & HCI_LINK_AUTH ? "on" : "off"),
326 (link->hl_flags & HCI_LINK_ENCRYPT ? "on" : "off"),
327 (link->hl_flags & HCI_LINK_SECURE ? "on" : "off"));
328
329 if (link->hl_flags & HCI_LINK_AUTH)
330 mode |= L2CAP_LM_AUTH;
331
332 if (link->hl_flags & HCI_LINK_ENCRYPT)
333 mode |= L2CAP_LM_ENCRYPT;
334
335 if (link->hl_flags & HCI_LINK_SECURE)
336 mode |= L2CAP_LM_SECURE;
337
338
339
340
341
342
343
344 next = LIST_FIRST(&l2cap_active_list);
345 while ((chan = next) != NULL) {
346 next = LIST_NEXT(chan, lc_ncid);
347
348 if (chan->lc_link != link)
349 continue;
350
351 switch(chan->lc_state) {
352 case L2CAP_WAIT_SEND_CONNECT_REQ:
353 if ((mode & chan->lc_mode) != chan->lc_mode) {
354 l2cap_close(chan, ECONNABORTED);
355 break;
356 }
357
358 chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP;
359 err = l2cap_send_connect_req(chan);
360 if (err) {
361 l2cap_close(chan, err);
362 break;
363 }
364 break;
365
366 case L2CAP_WAIT_SEND_CONNECT_RSP:
367 if ((mode & chan->lc_mode) != chan->lc_mode) {
368 l2cap_send_connect_rsp(link, chan->lc_ident,
369 0, chan->lc_rcid,
370 L2CAP_SECURITY_BLOCK);
371
372 l2cap_close(chan, ECONNABORTED);
373 break;
374 }
375
376 l2cap_send_connect_rsp(link, chan->lc_ident,
377 chan->lc_lcid, chan->lc_rcid,
378 L2CAP_SUCCESS);
379
380 chan->lc_state = L2CAP_WAIT_CONFIG;
381 chan->lc_flags |= (L2CAP_WAIT_CONFIG_RSP | L2CAP_WAIT_CONFIG_REQ);
382 err = l2cap_send_config_req(chan);
383 if (err) {
384 l2cap_close(chan, err);
385 break;
386 }
387 break;
388
389 case L2CAP_WAIT_RECV_CONNECT_RSP:
390 case L2CAP_WAIT_CONFIG:
391 case L2CAP_OPEN:
392 (*chan->lc_proto->linkmode)(chan->lc_upper, mode);
393 break;
394
395 default:
396 break;
397 }
398 }
399
400 link->hl_state = HCI_LINK_OPEN;
401 hci_acl_start(link);
402 }
403
404
405
406
407
408
409
410 void
411 hci_acl_recv(struct mbuf *m, struct hci_unit *unit)
412 {
413 struct hci_link *link;
414 hci_acldata_hdr_t hdr;
415 uint16_t handle, want;
416 int pb, got;
417
418 KASSERT(m != NULL);
419 KASSERT(unit != NULL);
420
421 KASSERT(m->m_pkthdr.len >= sizeof(hdr));
422 m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
423 m_adj(m, sizeof(hdr));
424
425 #ifdef DIAGNOSTIC
426 if (hdr.type != HCI_ACL_DATA_PKT) {
427 printf("%s: bad ACL packet type\n", unit->hci_devname);
428 goto bad;
429 }
430
431 if (m->m_pkthdr.len != letoh16(hdr.length)) {
432 printf("%s: bad ACL packet length (%d != %d)\n",
433 unit->hci_devname, m->m_pkthdr.len, letoh16(hdr.length));
434 goto bad;
435 }
436 #endif
437
438 hdr.length = letoh16(hdr.length);
439 hdr.con_handle = letoh16(hdr.con_handle);
440 handle = HCI_CON_HANDLE(hdr.con_handle);
441 pb = HCI_PB_FLAG(hdr.con_handle);
442
443 link = hci_link_lookup_handle(unit, handle);
444 if (link == NULL) {
445 hci_discon_cp cp;
446
447 DPRINTF("%s: dumping packet for unknown handle #%d\n",
448 unit->hci_devname, handle);
449
450
451
452
453
454
455
456 cp.con_handle = htole16(handle);
457 cp.reason = 0x13;
458 hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp));
459 goto bad;
460 }
461
462 switch (pb) {
463 case HCI_PACKET_START:
464 if (link->hl_rxp != NULL)
465 printf("%s: dropped incomplete ACL packet\n",
466 unit->hci_devname);
467
468 if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) {
469 printf("%s: short ACL packet\n",
470 unit->hci_devname);
471
472 goto bad;
473 }
474
475 link->hl_rxp = m;
476 got = m->m_pkthdr.len;
477 break;
478
479 case HCI_PACKET_FRAGMENT:
480 if (link->hl_rxp == NULL) {
481 printf("%s: unexpected packet fragment\n",
482 unit->hci_devname);
483
484 goto bad;
485 }
486
487 got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len;
488 m_cat(link->hl_rxp, m);
489 m = link->hl_rxp;
490 m->m_pkthdr.len = got;
491 break;
492
493 default:
494 printf("%s: unknown packet type\n",
495 unit->hci_devname);
496
497 goto bad;
498 }
499
500 m_copydata(m, 0, sizeof(want), (caddr_t)&want);
501 want = letoh16(want) + sizeof(l2cap_hdr_t) - got;
502
503 if (want > 0)
504 return;
505
506 link->hl_rxp = NULL;
507
508 if (want == 0) {
509 l2cap_recv_frame(m, link);
510 return;
511 }
512
513 bad:
514 m_freem(m);
515 }
516
517
518
519
520
521
522
523
524
525 int
526 hci_acl_send(struct mbuf *m, struct hci_link *link,
527 struct l2cap_channel *chan)
528 {
529 struct l2cap_pdu *pdu;
530 struct mbuf *n = NULL;
531 int plen, mlen, num = 0;
532
533 KASSERT(link != NULL);
534 KASSERT(m != NULL);
535 KASSERT(m->m_flags & M_PKTHDR);
536 KASSERT(m->m_pkthdr.len > 0);
537
538 if (link->hl_state == HCI_LINK_CLOSED) {
539 m_freem(m);
540 return ENETDOWN;
541 }
542
543 pdu = pool_get(&l2cap_pdu_pool, PR_NOWAIT);
544 if (pdu == NULL)
545 goto nomem;
546
547 bzero(pdu, sizeof *pdu);
548 pdu->lp_chan = chan;
549 pdu->lp_pending = 0;
550
551 plen = m->m_pkthdr.len;
552 mlen = link->hl_unit->hci_max_acl_size;
553
554 DPRINTFN(5, "%s: handle #%d, plen = %d, max = %d\n",
555 link->hl_unit->hci_devname, link->hl_handle, plen, mlen);
556
557 while (plen > 0) {
558 if (plen > mlen) {
559 n = m_split(m, mlen, M_DONTWAIT);
560 if (n == NULL)
561 goto nomem;
562 } else {
563 mlen = plen;
564 }
565
566 if (num++ == 0)
567 m->m_flags |= M_PROTO1;
568
569 DPRINTFN(10, "chunk of %d (plen = %d) bytes\n", mlen, plen);
570 IF_ENQUEUE(&pdu->lp_data, m);
571 m = n;
572 plen -= mlen;
573 }
574
575 TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next);
576 link->hl_txqlen += num;
577
578 hci_acl_start(link);
579
580 return 0;
581
582 nomem:
583 if (m) m_freem(m);
584 if (pdu) {
585 IF_PURGE(&pdu->lp_data);
586 pool_put(&l2cap_pdu_pool, pdu);
587 }
588
589 return ENOMEM;
590 }
591
592
593
594
595
596
597
598
599
600
601
602
603 void
604 hci_acl_start(struct hci_link *link)
605 {
606 struct hci_unit *unit;
607 hci_acldata_hdr_t *hdr;
608 struct l2cap_pdu *pdu;
609 struct mbuf *m;
610 uint16_t handle;
611
612 KASSERT(link != NULL);
613
614 unit = link->hl_unit;
615 KASSERT(unit != NULL);
616
617
618 if (link->hl_state != HCI_LINK_OPEN)
619 return;
620
621 if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0)
622 return;
623
624
625 pdu = TAILQ_FIRST(&link->hl_txq);
626 for (;;) {
627 if (pdu == NULL)
628 return;
629
630 if (!IF_IS_EMPTY(&pdu->lp_data))
631 break;
632
633 pdu = TAILQ_NEXT(pdu, lp_next);
634 }
635
636 while (unit->hci_num_acl_pkts > 0) {
637 IF_DEQUEUE(&pdu->lp_data, m);
638 KASSERT(m != NULL);
639
640 if (m->m_flags & M_PROTO1)
641 handle = HCI_MK_CON_HANDLE(link->hl_handle,
642 HCI_PACKET_START, 0);
643 else
644 handle = HCI_MK_CON_HANDLE(link->hl_handle,
645 HCI_PACKET_FRAGMENT, 0);
646
647 M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
648 if (m == NULL)
649 break;
650
651 hdr = mtod(m, hci_acldata_hdr_t *);
652 hdr->type = HCI_ACL_DATA_PKT;
653 hdr->con_handle = htole16(handle);
654 hdr->length = htole16(m->m_pkthdr.len - sizeof(*hdr));
655
656 link->hl_txqlen--;
657 pdu->lp_pending++;
658
659 hci_output_acl(unit, m);
660
661 if (IF_IS_EMPTY(&pdu->lp_data)) {
662 if (pdu->lp_chan) {
663
664
665
666
667
668
669
670
671 link->hl_state = HCI_LINK_BLOCK;
672 l2cap_start(pdu->lp_chan);
673 link->hl_state = HCI_LINK_OPEN;
674 }
675
676 pdu = TAILQ_NEXT(pdu, lp_next);
677 if (pdu == NULL)
678 break;
679 }
680 }
681
682
683
684
685
686 if (TAILQ_NEXT(link, hl_next)) {
687 TAILQ_REMOVE(&unit->hci_links, link, hl_next);
688 TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
689 }
690 }
691
692
693
694
695
696
697 void
698 hci_acl_complete(struct hci_link *link, int num)
699 {
700 struct l2cap_pdu *pdu;
701 struct l2cap_channel *chan;
702
703 DPRINTFN(5, "handle #%d (%d)\n", link->hl_handle, num);
704
705 while (num > 0) {
706 pdu = TAILQ_FIRST(&link->hl_txq);
707 if (pdu == NULL) {
708 printf("%s: %d packets completed on handle #%x "
709 "but none pending!\n",
710 link->hl_unit->hci_devname, num,
711 link->hl_handle);
712 return;
713 }
714
715 if (num >= pdu->lp_pending) {
716 num -= pdu->lp_pending;
717 pdu->lp_pending = 0;
718
719 if (IF_IS_EMPTY(&pdu->lp_data)) {
720 TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
721 chan = pdu->lp_chan;
722 if (chan != NULL) {
723 chan->lc_pending--;
724 (*chan->lc_proto->complete)
725 (chan->lc_upper, 1);
726
727 if (chan->lc_pending == 0)
728 l2cap_start(chan);
729 }
730
731 pool_put(&l2cap_pdu_pool, pdu);
732 }
733 } else {
734 pdu->lp_pending -= num;
735 num = 0;
736 }
737 }
738 }
739
740
741
742
743
744
745
746
747
748
749 struct hci_link *
750 hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
751 {
752 struct sockaddr_bt laddr, raddr;
753 struct sco_pcb *pcb, *new;
754 struct hci_link *sco, *acl;
755
756 memset(&laddr, 0, sizeof(laddr));
757 laddr.bt_len = sizeof(laddr);
758 laddr.bt_family = AF_BLUETOOTH;
759 bdaddr_copy(&laddr.bt_bdaddr, &unit->hci_bdaddr);
760
761 memset(&raddr, 0, sizeof(raddr));
762 raddr.bt_len = sizeof(raddr);
763 raddr.bt_family = AF_BLUETOOTH;
764 bdaddr_copy(&raddr.bt_bdaddr, bdaddr);
765
766
767
768
769
770
771 acl = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
772 if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
773 return NULL;
774
775 LIST_FOREACH(pcb, &sco_pcb, sp_next) {
776 if ((pcb->sp_flags & SP_LISTENING) == 0)
777 continue;
778
779 new = (*pcb->sp_proto->newconn)(pcb->sp_upper, &laddr, &raddr);
780 if (new == NULL)
781 continue;
782
783
784
785
786
787 bdaddr_copy(&new->sp_laddr, &unit->hci_bdaddr);
788 bdaddr_copy(&new->sp_raddr, bdaddr);
789
790 sco = hci_link_alloc(unit);
791 if (sco == NULL) {
792 sco_detach(&new);
793 return NULL;
794 }
795
796 sco->hl_type = HCI_LINK_SCO;
797 bdaddr_copy(&sco->hl_bdaddr, bdaddr);
798
799 sco->hl_link = hci_acl_open(unit, bdaddr);
800 KASSERT(sco->hl_link == acl);
801
802 sco->hl_sco = new;
803 new->sp_link = sco;
804
805 new->sp_mtu = unit->hci_max_sco_size;
806 return sco;
807 }
808
809 return NULL;
810 }
811
812
813
814
815
816 void
817 hci_sco_recv(struct mbuf *m, struct hci_unit *unit)
818 {
819 struct hci_link *link;
820 hci_scodata_hdr_t hdr;
821 uint16_t handle;
822
823 KASSERT(m != NULL);
824 KASSERT(unit != NULL);
825
826 KASSERT(m->m_pkthdr.len >= sizeof(hdr));
827 m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
828 m_adj(m, sizeof(hdr));
829
830 #ifdef DIAGNOSTIC
831 if (hdr.type != HCI_SCO_DATA_PKT) {
832 printf("%s: bad SCO packet type\n", unit->hci_devname);
833 goto bad;
834 }
835
836 if (m->m_pkthdr.len != hdr.length) {
837 printf("%s: bad SCO packet length (%d != %d)\n",
838 unit->hci_devname, m->m_pkthdr.len, hdr.length);
839 goto bad;
840 }
841 #endif
842
843 hdr.con_handle = letoh16(hdr.con_handle);
844 handle = HCI_CON_HANDLE(hdr.con_handle);
845
846 link = hci_link_lookup_handle(unit, handle);
847 if (link == NULL || link->hl_type == HCI_LINK_ACL) {
848 DPRINTF("%s: dumping packet for unknown handle #%d\n",
849 unit->hci_devname, handle);
850
851 goto bad;
852 }
853
854 (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m);
855 return;
856
857 bad:
858 m_freem(m);
859 }
860
861 void
862 hci_sco_start(struct hci_link *link)
863 {
864 }
865
866
867
868
869
870 void
871 hci_sco_complete(struct hci_link *link, int num)
872 {
873
874 DPRINTFN(5, "handle #%d (num=%d)\n", link->hl_handle, num);
875 link->hl_sco->sp_pending--;
876 (*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num);
877 }
878
879
880
881
882
883
884 struct hci_link *
885 hci_link_alloc(struct hci_unit *unit)
886 {
887 struct hci_link *link;
888
889 KASSERT(unit != NULL);
890
891 link = malloc(sizeof *link, M_BLUETOOTH, M_NOWAIT);
892 if (link == NULL)
893 return NULL;
894 bzero(link, sizeof *link);
895
896 link->hl_unit = unit;
897 link->hl_state = HCI_LINK_CLOSED;
898
899
900 timeout_set(&link->hl_expire, hci_acl_timeout, link);
901
902 TAILQ_INIT(&link->hl_txq);
903 TAILQ_INIT(&link->hl_reqs);
904
905 link->hl_mtu = L2CAP_MTU_DEFAULT;
906 link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT;
907
908
909 TAILQ_INSERT_HEAD(&unit->hci_links, link, hl_next);
910 return link;
911 }
912
913 void
914 hci_link_free(struct hci_link *link, int err)
915 {
916 struct l2cap_req *req;
917 struct l2cap_pdu *pdu;
918 struct l2cap_channel *chan, *next;
919
920 KASSERT(link != NULL);
921
922 DPRINTF("#%d, type = %d, state = %d, refcnt = %d\n",
923 link->hl_handle, link->hl_type,
924 link->hl_state, link->hl_refcnt);
925
926
927 if (link->hl_refcnt > 0) {
928 next = LIST_FIRST(&l2cap_active_list);
929 while ((chan = next) != NULL) {
930 next = LIST_NEXT(chan, lc_ncid);
931 if (chan->lc_link == link)
932 l2cap_close(chan, err);
933 }
934 }
935 KASSERT(link->hl_refcnt == 0);
936
937
938 while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL)
939 l2cap_request_free(req);
940
941 KASSERT(TAILQ_EMPTY(&link->hl_reqs));
942
943
944 while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) {
945 TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
946 IF_PURGE(&pdu->lp_data);
947 if (pdu->lp_pending)
948 link->hl_unit->hci_num_acl_pkts += pdu->lp_pending;
949
950 pool_put(&l2cap_pdu_pool, pdu);
951 }
952
953 KASSERT(TAILQ_EMPTY(&link->hl_txq));
954
955
956 if (link->hl_rxp != NULL) {
957 m_freem(link->hl_rxp);
958 link->hl_rxp = NULL;
959 }
960
961
962 if (link->hl_link != NULL) {
963 hci_acl_close(link->hl_link, err);
964 link->hl_link = NULL;
965 }
966
967
968 if (link->hl_sco != NULL) {
969 struct sco_pcb *pcb;
970
971 pcb = link->hl_sco;
972 pcb->sp_link = NULL;
973 link->hl_sco = NULL;
974 (*pcb->sp_proto->disconnected)(pcb->sp_upper, err);
975 }
976
977
978 IF_PURGE(&link->hl_data);
979
980
981
982
983
984
985 link->hl_state = HCI_LINK_CLOSED;
986 timeout_del(&link->hl_expire);
987 if (timeout_triggered(&link->hl_expire))
988 return;
989
990 TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next);
991 free(link, M_BLUETOOTH);
992 }
993
994
995
996
997 struct hci_link *
998 hci_link_lookup_state(struct hci_unit *unit, uint16_t type, uint16_t state)
999 {
1000 struct hci_link *link;
1001
1002 TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
1003 if (link->hl_type == type && link->hl_state == state)
1004 break;
1005 }
1006
1007 return link;
1008 }
1009
1010
1011
1012
1013
1014
1015 struct hci_link *
1016 hci_link_lookup_bdaddr(struct hci_unit *unit, bdaddr_t *bdaddr, uint16_t type)
1017 {
1018 struct hci_link *link;
1019
1020 KASSERT(unit != NULL);
1021 KASSERT(bdaddr != NULL);
1022
1023 TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
1024 if (link->hl_type != type)
1025 continue;
1026
1027 if (type == HCI_LINK_SCO && link->hl_handle != 0)
1028 continue;
1029
1030 if (bdaddr_same(&link->hl_bdaddr, bdaddr))
1031 break;
1032 }
1033
1034 return link;
1035 }
1036
1037 struct hci_link *
1038 hci_link_lookup_handle(struct hci_unit *unit, uint16_t handle)
1039 {
1040 struct hci_link *link;
1041
1042 KASSERT(unit != NULL);
1043
1044 TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
1045 if (handle == link->hl_handle)
1046 break;
1047 }
1048
1049 return link;
1050 }