1 | /* $NetBSD: hci_link.c,v 1.24 2014/05/20 18:25:54 rmind 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.24 2014/05/20 18:25:54 rmind 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/l2cap.h> |
47 | #include <netbt/sco.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 | 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, bdaddr, HCI_LINK_ACL); |
81 | if (link == NULL) |
82 | return NULL; |
83 | } |
84 | |
85 | switch(link->hl_state) { |
86 | case HCI_LINK_CLOSED: |
87 | /* |
88 | * open connection to remote device |
89 | */ |
90 | memset(&cp, 0, sizeof(cp)); |
91 | bdaddr_copy(&cp.bdaddr, bdaddr); |
92 | cp.pkt_type = htole16(unit->hci_packet_type); |
93 | |
94 | memo = hci_memo_find(unit, bdaddr); |
95 | if (memo != NULL) { |
96 | cp.page_scan_rep_mode = memo->page_scan_rep_mode; |
97 | cp.page_scan_mode = memo->page_scan_mode; |
98 | cp.clock_offset = memo->clock_offset; |
99 | } |
100 | |
101 | if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH) |
102 | cp.accept_role_switch = 1; |
103 | |
104 | err = hci_send_cmd(unit, HCI_CMD_CREATE_CON, &cp, sizeof(cp)); |
105 | if (err) { |
106 | hci_link_free(link, err); |
107 | return NULL; |
108 | } |
109 | |
110 | link->hl_flags |= HCI_LINK_CREATE_CON; |
111 | link->hl_state = HCI_LINK_WAIT_CONNECT; |
112 | break; |
113 | |
114 | case HCI_LINK_WAIT_CONNECT: |
115 | case HCI_LINK_WAIT_AUTH: |
116 | case HCI_LINK_WAIT_ENCRYPT: |
117 | case HCI_LINK_WAIT_SECURE: |
118 | /* |
119 | * somebody else already trying to connect, we just |
120 | * sit on the bench with them.. |
121 | */ |
122 | break; |
123 | |
124 | case HCI_LINK_OPEN: |
125 | /* |
126 | * If already open, halt any expiry timeouts. We dont need |
127 | * to care about already invoking timeouts since refcnt >0 |
128 | * will keep the link alive. |
129 | */ |
130 | callout_stop(&link->hl_expire); |
131 | break; |
132 | |
133 | default: |
134 | UNKNOWN(link->hl_state); |
135 | return NULL; |
136 | } |
137 | |
138 | /* open */ |
139 | link->hl_refcnt++; |
140 | |
141 | return link; |
142 | } |
143 | |
144 | /* |
145 | * Close ACL connection. When there are no more references to this link, |
146 | * we can either close it down or schedule a delayed closedown. |
147 | */ |
148 | void |
149 | hci_acl_close(struct hci_link *link, int err) |
150 | { |
151 | |
152 | KASSERT(link != NULL); |
153 | |
154 | if (--link->hl_refcnt == 0) { |
155 | if (link->hl_state == HCI_LINK_CLOSED) |
156 | hci_link_free(link, err); |
157 | else if (hci_acl_expiry > 0) |
158 | callout_schedule(&link->hl_expire, hci_acl_expiry * hz); |
159 | } |
160 | } |
161 | |
162 | /* |
163 | * Incoming ACL connection. |
164 | * |
165 | * Check the L2CAP listeners list and only accept when there is a |
166 | * potential listener available. |
167 | * |
168 | * There should not be a link to the same bdaddr already, we check |
169 | * anyway though its left unhandled for now. |
170 | */ |
171 | struct hci_link * |
172 | hci_acl_newconn(struct hci_unit *unit, bdaddr_t *bdaddr) |
173 | { |
174 | struct hci_link *link; |
175 | struct l2cap_channel *chan; |
176 | |
177 | LIST_FOREACH(chan, &l2cap_listen_list, lc_ncid) { |
178 | if (bdaddr_same(&unit->hci_bdaddr, &chan->lc_laddr.bt_bdaddr) |
179 | || bdaddr_any(&chan->lc_laddr.bt_bdaddr)) |
180 | break; |
181 | } |
182 | |
183 | if (chan == NULL) { |
184 | DPRINTF("%s: rejecting connection (no listeners)\n" , |
185 | device_xname(unit->hci_dev)); |
186 | |
187 | return NULL; |
188 | } |
189 | |
190 | link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL); |
191 | if (link != NULL) { |
192 | DPRINTF("%s: rejecting connection (link exists)\n" , |
193 | device_xname(unit->hci_dev)); |
194 | |
195 | return NULL; |
196 | } |
197 | |
198 | link = hci_link_alloc(unit, bdaddr, HCI_LINK_ACL); |
199 | if (link != NULL) { |
200 | link->hl_state = HCI_LINK_WAIT_CONNECT; |
201 | |
202 | if (hci_acl_expiry > 0) |
203 | callout_schedule(&link->hl_expire, hci_acl_expiry * hz); |
204 | } |
205 | |
206 | return link; |
207 | } |
208 | |
209 | void |
210 | hci_acl_timeout(void *arg) |
211 | { |
212 | struct hci_link *link = arg; |
213 | hci_discon_cp cp; |
214 | int err; |
215 | |
216 | mutex_enter(bt_lock); |
217 | callout_ack(&link->hl_expire); |
218 | |
219 | if (link->hl_refcnt > 0) |
220 | goto out; |
221 | |
222 | DPRINTF("link #%d expired\n" , link->hl_handle); |
223 | |
224 | switch (link->hl_state) { |
225 | case HCI_LINK_CLOSED: |
226 | case HCI_LINK_WAIT_CONNECT: |
227 | hci_link_free(link, ECONNRESET); |
228 | break; |
229 | |
230 | case HCI_LINK_WAIT_AUTH: |
231 | case HCI_LINK_WAIT_ENCRYPT: |
232 | case HCI_LINK_WAIT_SECURE: |
233 | case HCI_LINK_OPEN: |
234 | cp.con_handle = htole16(link->hl_handle); |
235 | cp.reason = 0x13; /* "Remote User Terminated Connection" */ |
236 | |
237 | err = hci_send_cmd(link->hl_unit, HCI_CMD_DISCONNECT, |
238 | &cp, sizeof(cp)); |
239 | |
240 | if (err) { |
241 | DPRINTF("error %d sending HCI_CMD_DISCONNECT\n" , |
242 | err); |
243 | } |
244 | |
245 | break; |
246 | |
247 | default: |
248 | UNKNOWN(link->hl_state); |
249 | break; |
250 | } |
251 | |
252 | out: |
253 | mutex_exit(bt_lock); |
254 | } |
255 | |
256 | /* |
257 | * Initiate any Link Mode change requests. |
258 | */ |
259 | int |
260 | hci_acl_setmode(struct hci_link *link) |
261 | { |
262 | int err; |
263 | |
264 | KASSERT(link != NULL); |
265 | KASSERT(link->hl_unit != NULL); |
266 | |
267 | if (link->hl_state != HCI_LINK_OPEN) |
268 | return EINPROGRESS; |
269 | |
270 | if ((link->hl_flags & HCI_LINK_AUTH_REQ) |
271 | && !(link->hl_flags & HCI_LINK_AUTH)) { |
272 | hci_auth_req_cp cp; |
273 | |
274 | DPRINTF("requesting auth for handle #%d\n" , |
275 | link->hl_handle); |
276 | |
277 | link->hl_state = HCI_LINK_WAIT_AUTH; |
278 | cp.con_handle = htole16(link->hl_handle); |
279 | err = hci_send_cmd(link->hl_unit, HCI_CMD_AUTH_REQ, |
280 | &cp, sizeof(cp)); |
281 | |
282 | return (err == 0 ? EINPROGRESS : err); |
283 | } |
284 | |
285 | if ((link->hl_flags & HCI_LINK_ENCRYPT_REQ) |
286 | && !(link->hl_flags & HCI_LINK_ENCRYPT)) { |
287 | hci_set_con_encryption_cp cp; |
288 | |
289 | /* XXX we should check features for encryption capability */ |
290 | |
291 | DPRINTF("requesting encryption for handle #%d\n" , |
292 | link->hl_handle); |
293 | |
294 | link->hl_state = HCI_LINK_WAIT_ENCRYPT; |
295 | cp.con_handle = htole16(link->hl_handle); |
296 | cp.encryption_enable = 0x01; |
297 | |
298 | err = hci_send_cmd(link->hl_unit, HCI_CMD_SET_CON_ENCRYPTION, |
299 | &cp, sizeof(cp)); |
300 | |
301 | return (err == 0 ? EINPROGRESS : err); |
302 | } |
303 | |
304 | if ((link->hl_flags & HCI_LINK_SECURE_REQ)) { |
305 | hci_change_con_link_key_cp cp; |
306 | |
307 | /* always change link key for SECURE requests */ |
308 | link->hl_flags &= ~HCI_LINK_SECURE; |
309 | |
310 | DPRINTF("changing link key for handle #%d\n" , |
311 | link->hl_handle); |
312 | |
313 | link->hl_state = HCI_LINK_WAIT_SECURE; |
314 | cp.con_handle = htole16(link->hl_handle); |
315 | |
316 | err = hci_send_cmd(link->hl_unit, HCI_CMD_CHANGE_CON_LINK_KEY, |
317 | &cp, sizeof(cp)); |
318 | |
319 | return (err == 0 ? EINPROGRESS : err); |
320 | } |
321 | |
322 | return 0; |
323 | } |
324 | |
325 | /* |
326 | * Link Mode changed. |
327 | * |
328 | * This is called from event handlers when the mode change |
329 | * is complete. We notify upstream and restart the link. |
330 | */ |
331 | void |
332 | hci_acl_linkmode(struct hci_link *link) |
333 | { |
334 | struct l2cap_channel *chan, *next; |
335 | int err, mode = 0; |
336 | |
337 | DPRINTF("handle #%d, auth %s, encrypt %s, secure %s\n" , |
338 | link->hl_handle, |
339 | (link->hl_flags & HCI_LINK_AUTH ? "on" : "off" ), |
340 | (link->hl_flags & HCI_LINK_ENCRYPT ? "on" : "off" ), |
341 | (link->hl_flags & HCI_LINK_SECURE ? "on" : "off" )); |
342 | |
343 | if (link->hl_flags & HCI_LINK_AUTH) |
344 | mode |= L2CAP_LM_AUTH; |
345 | |
346 | if (link->hl_flags & HCI_LINK_ENCRYPT) |
347 | mode |= L2CAP_LM_ENCRYPT; |
348 | |
349 | if (link->hl_flags & HCI_LINK_SECURE) |
350 | mode |= L2CAP_LM_SECURE; |
351 | |
352 | /* |
353 | * The link state will only be OPEN here if the mode change |
354 | * was successful. So, we can proceed with L2CAP connections, |
355 | * or notify already establshed channels, to allow any that |
356 | * are dissatisfied to disconnect before we restart. |
357 | */ |
358 | next = LIST_FIRST(&l2cap_active_list); |
359 | while ((chan = next) != NULL) { |
360 | next = LIST_NEXT(chan, lc_ncid); |
361 | |
362 | if (chan->lc_link != link) |
363 | continue; |
364 | |
365 | switch(chan->lc_state) { |
366 | case L2CAP_WAIT_SEND_CONNECT_REQ: /* we are connecting */ |
367 | if ((mode & chan->lc_mode) != chan->lc_mode) { |
368 | l2cap_close(chan, ECONNABORTED); |
369 | break; |
370 | } |
371 | |
372 | chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP; |
373 | err = l2cap_send_connect_req(chan); |
374 | if (err) { |
375 | l2cap_close(chan, err); |
376 | break; |
377 | } |
378 | break; |
379 | |
380 | case L2CAP_WAIT_SEND_CONNECT_RSP: /* they are connecting */ |
381 | if ((mode & chan->lc_mode) != chan->lc_mode) { |
382 | l2cap_send_connect_rsp(link, chan->lc_ident, |
383 | 0, chan->lc_rcid, |
384 | L2CAP_SECURITY_BLOCK); |
385 | |
386 | l2cap_close(chan, ECONNABORTED); |
387 | break; |
388 | } |
389 | |
390 | l2cap_send_connect_rsp(link, chan->lc_ident, |
391 | chan->lc_lcid, chan->lc_rcid, |
392 | L2CAP_SUCCESS); |
393 | |
394 | chan->lc_state = L2CAP_WAIT_CONFIG; |
395 | chan->lc_flags |= (L2CAP_WAIT_CONFIG_RSP | L2CAP_WAIT_CONFIG_REQ); |
396 | err = l2cap_send_config_req(chan); |
397 | if (err) { |
398 | l2cap_close(chan, err); |
399 | break; |
400 | } |
401 | break; |
402 | |
403 | case L2CAP_WAIT_RECV_CONNECT_RSP: |
404 | case L2CAP_WAIT_CONFIG: |
405 | case L2CAP_OPEN: /* already established */ |
406 | (*chan->lc_proto->linkmode)(chan->lc_upper, mode); |
407 | break; |
408 | |
409 | default: |
410 | break; |
411 | } |
412 | } |
413 | |
414 | link->hl_state = HCI_LINK_OPEN; |
415 | hci_acl_start(link); |
416 | } |
417 | |
418 | /* |
419 | * Receive ACL Data |
420 | * |
421 | * we accumulate packet fragments on the hci_link structure |
422 | * until a full L2CAP frame is ready, then send it on. |
423 | */ |
424 | void |
425 | hci_acl_recv(struct mbuf *m, struct hci_unit *unit) |
426 | { |
427 | struct hci_link *link; |
428 | hci_acldata_hdr_t hdr; |
429 | uint16_t handle, want; |
430 | int pb, got; |
431 | |
432 | KASSERT(m != NULL); |
433 | KASSERT(unit != NULL); |
434 | |
435 | if (m->m_pkthdr.len < sizeof(hdr)) |
436 | goto bad; |
437 | |
438 | m_copydata(m, 0, sizeof(hdr), &hdr); |
439 | m_adj(m, sizeof(hdr)); |
440 | |
441 | KASSERT(hdr.type == HCI_ACL_DATA_PKT); |
442 | |
443 | hdr.length = le16toh(hdr.length); |
444 | hdr.con_handle = le16toh(hdr.con_handle); |
445 | handle = HCI_CON_HANDLE(hdr.con_handle); |
446 | pb = HCI_PB_FLAG(hdr.con_handle); |
447 | |
448 | if (m->m_pkthdr.len != hdr.length) |
449 | goto bad; |
450 | |
451 | link = hci_link_lookup_handle(unit, handle); |
452 | if (link == NULL) { |
453 | hci_discon_cp cp; |
454 | |
455 | DPRINTF("%s: dumping packet for unknown handle #%d\n" , |
456 | device_xname(unit->hci_dev), handle); |
457 | |
458 | /* |
459 | * There is no way to find out what this connection handle is |
460 | * for, just get rid of it. This may happen, if a USB dongle |
461 | * is plugged into a self powered hub and does not reset when |
462 | * the system is shut down. |
463 | * |
464 | * This can cause a problem with some Broadcom controllers |
465 | * which emit empty ACL packets during connection setup, so |
466 | * only disconnect where data is present. |
467 | */ |
468 | if (hdr.length > 0) { |
469 | cp.con_handle = htole16(handle); |
470 | cp.reason = 0x13;/*"Remote User Terminated Connection"*/ |
471 | hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp)); |
472 | } |
473 | goto bad; |
474 | } |
475 | |
476 | switch (pb) { |
477 | case HCI_PACKET_START: |
478 | if (link->hl_rxp != NULL) |
479 | aprint_error_dev(unit->hci_dev, |
480 | "dropped incomplete ACL packet\n" ); |
481 | |
482 | if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) |
483 | goto bad; |
484 | |
485 | link->hl_rxp = m; |
486 | got = m->m_pkthdr.len; |
487 | break; |
488 | |
489 | case HCI_PACKET_FRAGMENT: |
490 | if (link->hl_rxp == NULL) { |
491 | aprint_error_dev(unit->hci_dev, |
492 | "unexpected packet fragment\n" ); |
493 | |
494 | goto bad; |
495 | } |
496 | |
497 | got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len; |
498 | m_cat(link->hl_rxp, m); |
499 | m = link->hl_rxp; |
500 | m->m_pkthdr.len = got; |
501 | break; |
502 | |
503 | default: |
504 | DPRINTF("%s: unknown packet type\n" , |
505 | device_xname(unit->hci_dev)); |
506 | |
507 | goto bad; |
508 | } |
509 | |
510 | m_copydata(m, 0, sizeof(want), &want); |
511 | want = le16toh(want) + sizeof(l2cap_hdr_t) - got; |
512 | |
513 | if (want > 0) |
514 | return; |
515 | |
516 | link->hl_rxp = NULL; |
517 | |
518 | if (want == 0) { |
519 | l2cap_recv_frame(m, link); |
520 | return; |
521 | } |
522 | |
523 | bad: |
524 | m_freem(m); |
525 | } |
526 | |
527 | /* |
528 | * Send ACL data on link |
529 | * |
530 | * We must fragment packets into chunks of less than unit->hci_max_acl_size and |
531 | * prepend a relevant ACL header to each fragment. We keep a PDU structure |
532 | * attached to the link, so that completed fragments can be marked off and |
533 | * more data requested from above once the PDU is sent. |
534 | */ |
535 | int |
536 | hci_acl_send(struct mbuf *m, struct hci_link *link, |
537 | struct l2cap_channel *chan) |
538 | { |
539 | struct l2cap_pdu *pdu; |
540 | struct mbuf *n = NULL; |
541 | int plen, mlen, num = 0; |
542 | |
543 | KASSERT(link != NULL); |
544 | KASSERT(m != NULL); |
545 | KASSERT(m->m_flags & M_PKTHDR); |
546 | KASSERT(m->m_pkthdr.len > 0); |
547 | |
548 | if (link->hl_state == HCI_LINK_CLOSED) { |
549 | m_freem(m); |
550 | return ENETDOWN; |
551 | } |
552 | |
553 | pdu = pool_get(&l2cap_pdu_pool, PR_NOWAIT); |
554 | if (pdu == NULL) |
555 | goto nomem; |
556 | |
557 | pdu->lp_chan = chan; |
558 | pdu->lp_pending = 0; |
559 | MBUFQ_INIT(&pdu->lp_data); |
560 | |
561 | plen = m->m_pkthdr.len; |
562 | mlen = link->hl_unit->hci_max_acl_size; |
563 | |
564 | DPRINTFN(5, "%s: handle #%d, plen = %d, max = %d\n" , |
565 | device_xname(link->hl_unit->hci_dev), link->hl_handle, plen, mlen); |
566 | |
567 | while (plen > 0) { |
568 | if (plen > mlen) { |
569 | n = m_split(m, mlen, M_DONTWAIT); |
570 | if (n == NULL) |
571 | goto nomem; |
572 | } else { |
573 | mlen = plen; |
574 | } |
575 | |
576 | if (num++ == 0) |
577 | m->m_flags |= M_PROTO1; /* tag first fragment */ |
578 | |
579 | DPRINTFN(10, "chunk of %d (plen = %d) bytes\n" , mlen, plen); |
580 | MBUFQ_ENQUEUE(&pdu->lp_data, m); |
581 | m = n; |
582 | plen -= mlen; |
583 | } |
584 | |
585 | TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next); |
586 | link->hl_txqlen += num; |
587 | |
588 | hci_acl_start(link); |
589 | |
590 | return 0; |
591 | |
592 | nomem: |
593 | if (m) m_freem(m); |
594 | if (pdu) { |
595 | MBUFQ_DRAIN(&pdu->lp_data); |
596 | pool_put(&l2cap_pdu_pool, pdu); |
597 | } |
598 | |
599 | return ENOMEM; |
600 | } |
601 | |
602 | /* |
603 | * Start sending ACL data on link. |
604 | * |
605 | * This is called when the queue may need restarting: as new data |
606 | * is queued, after link mode changes have completed, or when device |
607 | * buffers have cleared. |
608 | * |
609 | * We may use all the available packet slots. The reason that we add |
610 | * the ACL encapsulation here rather than in hci_acl_send() is that L2CAP |
611 | * signal packets may be queued before the handle is given to us.. |
612 | */ |
613 | void |
614 | hci_acl_start(struct hci_link *link) |
615 | { |
616 | struct hci_unit *unit; |
617 | hci_acldata_hdr_t *hdr; |
618 | struct l2cap_pdu *pdu; |
619 | struct mbuf *m; |
620 | uint16_t handle; |
621 | |
622 | KASSERT(link != NULL); |
623 | |
624 | unit = link->hl_unit; |
625 | KASSERT(unit != NULL); |
626 | |
627 | /* this is mainly to block ourselves (below) */ |
628 | if (link->hl_state != HCI_LINK_OPEN) |
629 | return; |
630 | |
631 | if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0) |
632 | return; |
633 | |
634 | /* find first PDU with data to send */ |
635 | pdu = TAILQ_FIRST(&link->hl_txq); |
636 | for (;;) { |
637 | if (pdu == NULL) |
638 | return; |
639 | |
640 | if (MBUFQ_FIRST(&pdu->lp_data) != NULL) |
641 | break; |
642 | |
643 | pdu = TAILQ_NEXT(pdu, lp_next); |
644 | } |
645 | |
646 | while (unit->hci_num_acl_pkts > 0) { |
647 | MBUFQ_DEQUEUE(&pdu->lp_data, m); |
648 | KASSERT(m != NULL); |
649 | |
650 | if (m->m_flags & M_PROTO1) |
651 | handle = HCI_MK_CON_HANDLE(link->hl_handle, |
652 | HCI_PACKET_START, 0); |
653 | else |
654 | handle = HCI_MK_CON_HANDLE(link->hl_handle, |
655 | HCI_PACKET_FRAGMENT, 0); |
656 | |
657 | M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); |
658 | if (m == NULL) |
659 | break; |
660 | |
661 | hdr = mtod(m, hci_acldata_hdr_t *); |
662 | hdr->type = HCI_ACL_DATA_PKT; |
663 | hdr->con_handle = htole16(handle); |
664 | hdr->length = htole16(m->m_pkthdr.len - sizeof(*hdr)); |
665 | |
666 | link->hl_txqlen--; |
667 | pdu->lp_pending++; |
668 | |
669 | hci_output_acl(unit, m); |
670 | |
671 | if (MBUFQ_FIRST(&pdu->lp_data) == NULL) { |
672 | if (pdu->lp_chan) { |
673 | /* |
674 | * This should enable streaming of PDUs - when |
675 | * we have placed all the fragments on the acl |
676 | * output queue, we trigger the L2CAP layer to |
677 | * send us down one more. Use a false state so |
678 | * we dont run into ourselves coming back from |
679 | * the future.. |
680 | */ |
681 | link->hl_state = HCI_LINK_BLOCK; |
682 | l2cap_start(pdu->lp_chan); |
683 | link->hl_state = HCI_LINK_OPEN; |
684 | } |
685 | |
686 | pdu = TAILQ_NEXT(pdu, lp_next); |
687 | if (pdu == NULL) |
688 | break; |
689 | } |
690 | } |
691 | |
692 | /* |
693 | * We had our turn now, move to the back of the queue to let |
694 | * other links have a go at the output buffers.. |
695 | */ |
696 | if (TAILQ_NEXT(link, hl_next)) { |
697 | TAILQ_REMOVE(&unit->hci_links, link, hl_next); |
698 | TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next); |
699 | } |
700 | } |
701 | |
702 | /* |
703 | * Confirm ACL packets cleared from Controller buffers. We scan our PDU |
704 | * list to clear pending fragments and signal upstream for more data |
705 | * when a PDU is complete. |
706 | */ |
707 | void |
708 | hci_acl_complete(struct hci_link *link, int num) |
709 | { |
710 | struct l2cap_pdu *pdu; |
711 | struct l2cap_channel *chan; |
712 | |
713 | DPRINTFN(5, "handle #%d (%d)\n" , link->hl_handle, num); |
714 | |
715 | while (num > 0) { |
716 | pdu = TAILQ_FIRST(&link->hl_txq); |
717 | if (pdu == NULL) { |
718 | aprint_error_dev(link->hl_unit->hci_dev, |
719 | "%d packets completed on handle #%x but none pending!\n" , |
720 | num, link->hl_handle); |
721 | |
722 | return; |
723 | } |
724 | |
725 | if (num >= pdu->lp_pending) { |
726 | num -= pdu->lp_pending; |
727 | pdu->lp_pending = 0; |
728 | |
729 | if (MBUFQ_FIRST(&pdu->lp_data) == NULL) { |
730 | TAILQ_REMOVE(&link->hl_txq, pdu, lp_next); |
731 | chan = pdu->lp_chan; |
732 | if (chan != NULL) { |
733 | chan->lc_pending--; |
734 | (*chan->lc_proto->complete) |
735 | (chan->lc_upper, 1); |
736 | |
737 | if (chan->lc_pending == 0) |
738 | l2cap_start(chan); |
739 | } |
740 | |
741 | pool_put(&l2cap_pdu_pool, pdu); |
742 | } |
743 | } else { |
744 | pdu->lp_pending -= num; |
745 | num = 0; |
746 | } |
747 | } |
748 | } |
749 | |
750 | /******************************************************************************* |
751 | * |
752 | * HCI SCO Connections |
753 | */ |
754 | |
755 | /* |
756 | * Incoming SCO Connection. We check the list for anybody willing |
757 | * to take it. |
758 | */ |
759 | struct hci_link * |
760 | hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr) |
761 | { |
762 | struct sockaddr_bt laddr, raddr; |
763 | struct sco_pcb *pcb, *new; |
764 | struct hci_link *sco, *acl; |
765 | |
766 | memset(&laddr, 0, sizeof(laddr)); |
767 | laddr.bt_len = sizeof(laddr); |
768 | laddr.bt_family = AF_BLUETOOTH; |
769 | bdaddr_copy(&laddr.bt_bdaddr, &unit->hci_bdaddr); |
770 | |
771 | memset(&raddr, 0, sizeof(raddr)); |
772 | raddr.bt_len = sizeof(raddr); |
773 | raddr.bt_family = AF_BLUETOOTH; |
774 | bdaddr_copy(&raddr.bt_bdaddr, bdaddr); |
775 | |
776 | /* |
777 | * There should already be an ACL link up and running before |
778 | * the controller sends us SCO connection requests, but you |
779 | * never know.. |
780 | */ |
781 | acl = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL); |
782 | if (acl == NULL || acl->hl_state != HCI_LINK_OPEN) |
783 | return NULL; |
784 | |
785 | LIST_FOREACH(pcb, &sco_pcb, sp_next) { |
786 | if ((pcb->sp_flags & SP_LISTENING) == 0) |
787 | continue; |
788 | |
789 | new = (*pcb->sp_proto->newconn)(pcb->sp_upper, &laddr, &raddr); |
790 | if (new == NULL) |
791 | continue; |
792 | |
793 | /* |
794 | * Ok, got new pcb so we can start a new link and fill |
795 | * in all the details. |
796 | */ |
797 | bdaddr_copy(&new->sp_laddr, &unit->hci_bdaddr); |
798 | bdaddr_copy(&new->sp_raddr, bdaddr); |
799 | |
800 | sco = hci_link_alloc(unit, bdaddr, HCI_LINK_SCO); |
801 | if (sco == NULL) { |
802 | sco_detach_pcb(&new); |
803 | return NULL; |
804 | } |
805 | |
806 | sco->hl_link = hci_acl_open(unit, bdaddr); |
807 | KASSERT(sco->hl_link == acl); |
808 | |
809 | sco->hl_sco = new; |
810 | new->sp_link = sco; |
811 | |
812 | new->sp_mtu = unit->hci_max_sco_size; |
813 | return sco; |
814 | } |
815 | |
816 | return NULL; |
817 | } |
818 | |
819 | /* |
820 | * receive SCO packet, we only need to strip the header and send |
821 | * it to the right handler |
822 | */ |
823 | void |
824 | hci_sco_recv(struct mbuf *m, struct hci_unit *unit) |
825 | { |
826 | struct hci_link *link; |
827 | hci_scodata_hdr_t hdr; |
828 | uint16_t handle; |
829 | |
830 | KASSERT(m != NULL); |
831 | KASSERT(unit != NULL); |
832 | |
833 | if (m->m_pkthdr.len < sizeof(hdr)) |
834 | goto bad; |
835 | |
836 | m_copydata(m, 0, sizeof(hdr), &hdr); |
837 | m_adj(m, sizeof(hdr)); |
838 | |
839 | KASSERT(hdr.type == HCI_SCO_DATA_PKT); |
840 | |
841 | hdr.con_handle = le16toh(hdr.con_handle); |
842 | handle = HCI_CON_HANDLE(hdr.con_handle); |
843 | |
844 | if (m->m_pkthdr.len != hdr.length) |
845 | goto bad; |
846 | |
847 | link = hci_link_lookup_handle(unit, handle); |
848 | if (link == NULL || link->hl_type == HCI_LINK_ACL) { |
849 | DPRINTF("%s: dumping packet for unknown handle #%d\n" , |
850 | device_xname(unit->hci_dev), handle); |
851 | |
852 | goto bad; |
853 | } |
854 | |
855 | (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m); |
856 | return; |
857 | |
858 | bad: |
859 | m_freem(m); |
860 | } |
861 | |
862 | void |
863 | hci_sco_start(struct hci_link *link) |
864 | { |
865 | } |
866 | |
867 | /* |
868 | * SCO packets have completed at the controller, so we can |
869 | * signal up to free the buffer space. |
870 | */ |
871 | void |
872 | hci_sco_complete(struct hci_link *link, int num) |
873 | { |
874 | |
875 | DPRINTFN(5, "handle #%d (num=%d)\n" , link->hl_handle, num); |
876 | link->hl_sco->sp_pending--; |
877 | (*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num); |
878 | } |
879 | |
880 | /******************************************************************************* |
881 | * |
882 | * Generic HCI Connection alloc/free/lookup etc |
883 | */ |
884 | |
885 | struct hci_link * |
886 | hci_link_alloc(struct hci_unit *unit, bdaddr_t *bdaddr, uint8_t type) |
887 | { |
888 | struct hci_link *link; |
889 | |
890 | KASSERT(unit != NULL); |
891 | |
892 | link = malloc(sizeof(struct hci_link), M_BLUETOOTH, M_NOWAIT | M_ZERO); |
893 | if (link == NULL) |
894 | return NULL; |
895 | |
896 | link->hl_unit = unit; |
897 | link->hl_type = type; |
898 | link->hl_state = HCI_LINK_CLOSED; |
899 | bdaddr_copy(&link->hl_bdaddr, bdaddr); |
900 | |
901 | /* init ACL portion */ |
902 | callout_init(&link->hl_expire, 0); |
903 | callout_setfunc(&link->hl_expire, hci_acl_timeout, link); |
904 | |
905 | TAILQ_INIT(&link->hl_txq); /* outgoing packets */ |
906 | TAILQ_INIT(&link->hl_reqs); /* request queue */ |
907 | |
908 | link->hl_mtu = L2CAP_MTU_DEFAULT; /* L2CAP signal mtu */ |
909 | link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT; /* flush timeout */ |
910 | |
911 | /* init SCO portion */ |
912 | MBUFQ_INIT(&link->hl_data); |
913 | |
914 | /* attach to unit */ |
915 | TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next); |
916 | return link; |
917 | } |
918 | |
919 | void |
920 | hci_link_free(struct hci_link *link, int err) |
921 | { |
922 | struct l2cap_req *req; |
923 | struct l2cap_pdu *pdu; |
924 | struct l2cap_channel *chan, *next; |
925 | |
926 | KASSERT(link != NULL); |
927 | |
928 | DPRINTF("#%d, type = %d, state = %d, refcnt = %d\n" , |
929 | link->hl_handle, link->hl_type, |
930 | link->hl_state, link->hl_refcnt); |
931 | |
932 | /* ACL reference count */ |
933 | if (link->hl_refcnt > 0) { |
934 | next = LIST_FIRST(&l2cap_active_list); |
935 | while ((chan = next) != NULL) { |
936 | next = LIST_NEXT(chan, lc_ncid); |
937 | if (chan->lc_link == link) |
938 | l2cap_close(chan, err); |
939 | } |
940 | } |
941 | KASSERT(link->hl_refcnt == 0); |
942 | |
943 | /* ACL L2CAP requests.. */ |
944 | while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL) |
945 | l2cap_request_free(req); |
946 | |
947 | KASSERT(TAILQ_EMPTY(&link->hl_reqs)); |
948 | |
949 | /* ACL outgoing data queue */ |
950 | while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) { |
951 | TAILQ_REMOVE(&link->hl_txq, pdu, lp_next); |
952 | MBUFQ_DRAIN(&pdu->lp_data); |
953 | if (pdu->lp_pending) |
954 | link->hl_unit->hci_num_acl_pkts += pdu->lp_pending; |
955 | |
956 | pool_put(&l2cap_pdu_pool, pdu); |
957 | } |
958 | |
959 | KASSERT(TAILQ_EMPTY(&link->hl_txq)); |
960 | |
961 | /* ACL incoming data packet */ |
962 | if (link->hl_rxp != NULL) { |
963 | m_freem(link->hl_rxp); |
964 | link->hl_rxp = NULL; |
965 | } |
966 | |
967 | /* SCO master ACL link */ |
968 | if (link->hl_link != NULL) { |
969 | hci_acl_close(link->hl_link, err); |
970 | link->hl_link = NULL; |
971 | } |
972 | |
973 | /* SCO pcb */ |
974 | if (link->hl_sco != NULL) { |
975 | struct sco_pcb *pcb; |
976 | |
977 | pcb = link->hl_sco; |
978 | pcb->sp_link = NULL; |
979 | link->hl_sco = NULL; |
980 | (*pcb->sp_proto->disconnected)(pcb->sp_upper, err); |
981 | } |
982 | |
983 | /* flush any SCO data */ |
984 | MBUFQ_DRAIN(&link->hl_data); |
985 | |
986 | /* |
987 | * Halt the callout - if its already running we cannot free the |
988 | * link structure but the timeout function will call us back in |
989 | * any case. |
990 | */ |
991 | link->hl_state = HCI_LINK_CLOSED; |
992 | callout_stop(&link->hl_expire); |
993 | if (callout_invoking(&link->hl_expire)) |
994 | return; |
995 | |
996 | callout_destroy(&link->hl_expire); |
997 | |
998 | /* |
999 | * If we made a note of clock offset, keep it in a memo |
1000 | * to facilitate reconnections to this device |
1001 | */ |
1002 | if (link->hl_clock != 0) { |
1003 | struct hci_memo *memo; |
1004 | |
1005 | memo = hci_memo_new(link->hl_unit, &link->hl_bdaddr); |
1006 | if (memo != NULL) |
1007 | memo->clock_offset = link->hl_clock; |
1008 | } |
1009 | |
1010 | TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next); |
1011 | free(link, M_BLUETOOTH); |
1012 | } |
1013 | |
1014 | /* |
1015 | * Lookup HCI link by address and type. Note that for SCO links there may |
1016 | * be more than one link per address, so we only return links with no |
1017 | * handle (ie new links) |
1018 | */ |
1019 | struct hci_link * |
1020 | hci_link_lookup_bdaddr(struct hci_unit *unit, bdaddr_t *bdaddr, uint8_t type) |
1021 | { |
1022 | struct hci_link *link; |
1023 | |
1024 | KASSERT(unit != NULL); |
1025 | KASSERT(bdaddr != NULL); |
1026 | |
1027 | TAILQ_FOREACH(link, &unit->hci_links, hl_next) { |
1028 | if (link->hl_type != type) |
1029 | continue; |
1030 | |
1031 | if (type == HCI_LINK_SCO && link->hl_handle != 0) |
1032 | continue; |
1033 | |
1034 | if (bdaddr_same(&link->hl_bdaddr, bdaddr)) |
1035 | break; |
1036 | } |
1037 | |
1038 | return link; |
1039 | } |
1040 | |
1041 | struct hci_link * |
1042 | hci_link_lookup_handle(struct hci_unit *unit, uint16_t handle) |
1043 | { |
1044 | struct hci_link *link; |
1045 | |
1046 | KASSERT(unit != NULL); |
1047 | |
1048 | TAILQ_FOREACH(link, &unit->hci_links, hl_next) { |
1049 | if (handle == link->hl_handle) |
1050 | break; |
1051 | } |
1052 | |
1053 | return link; |
1054 | } |
1055 | |