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

Cache object: a6434ea74d52a336f3cf31173dc6caf9


[ 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.