The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netbt/hci_link.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: f1e5e988dcbe9a676d90167ad7a22586


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.