[BACK]Return to hci_event.c CVS log [TXT][DIR] Up to [local] / sys / netbt

Annotation of sys/netbt/hci_event.c, Revision 1.1.1.1

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

CVSweb