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

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

1.1       nbrk        1: /*     $OpenBSD: l2cap_upper.c,v 1.1 2007/06/01 02:46:11 uwe Exp $     */
                      2: /*     $NetBSD: l2cap_upper.c,v 1.8 2007/04/29 20:23:36 msaitoh 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/mbuf.h>
                     39: #include <sys/proc.h>
                     40: #include <sys/queue.h>
                     41: #include <sys/socket.h>
                     42: #include <sys/socketvar.h>
                     43: #include <sys/systm.h>
                     44:
                     45: #include <netbt/bluetooth.h>
                     46: #include <netbt/hci.h>
                     47: #include <netbt/l2cap.h>
                     48:
                     49: /*******************************************************************************
                     50:  *
                     51:  *     L2CAP Channel - Upper Protocol API
                     52:  */
                     53:
                     54: /*
                     55:  * l2cap_attach(handle, btproto, upper)
                     56:  *
                     57:  *     attach new l2cap_channel to handle, populate
                     58:  *     with reasonable defaults
                     59:  */
                     60: int
                     61: l2cap_attach(struct l2cap_channel **handle,
                     62:                const struct btproto *proto, void *upper)
                     63: {
                     64:        struct l2cap_channel *chan;
                     65:
                     66:        KASSERT(handle != NULL);
                     67:        KASSERT(proto != NULL);
                     68:        KASSERT(upper != NULL);
                     69:
                     70:        chan = malloc(sizeof(struct l2cap_channel), M_BLUETOOTH,
                     71:                        M_NOWAIT);
                     72:        if (chan == NULL)
                     73:                return ENOMEM;
                     74:        bzero(chan, sizeof *chan);
                     75:
                     76:        chan->lc_proto = proto;
                     77:        chan->lc_upper = upper;
                     78:
                     79:        chan->lc_state = L2CAP_CLOSED;
                     80:
                     81:        chan->lc_lcid = L2CAP_NULL_CID;
                     82:        chan->lc_rcid = L2CAP_NULL_CID;
                     83:
                     84:        chan->lc_laddr.bt_len = sizeof(struct sockaddr_bt);
                     85:        chan->lc_laddr.bt_family = AF_BLUETOOTH;
                     86:        chan->lc_laddr.bt_psm = L2CAP_PSM_ANY;
                     87:
                     88:        chan->lc_raddr.bt_len = sizeof(struct sockaddr_bt);
                     89:        chan->lc_raddr.bt_family = AF_BLUETOOTH;
                     90:        chan->lc_raddr.bt_psm = L2CAP_PSM_ANY;
                     91:
                     92:        chan->lc_imtu = L2CAP_MTU_DEFAULT;
                     93:        chan->lc_omtu = L2CAP_MTU_DEFAULT;
                     94:        chan->lc_flush = L2CAP_FLUSH_TIMO_DEFAULT;
                     95:
                     96:        memcpy(&chan->lc_iqos, &l2cap_default_qos, sizeof(l2cap_qos_t));
                     97:        memcpy(&chan->lc_oqos, &l2cap_default_qos, sizeof(l2cap_qos_t));
                     98:
                     99:        *handle = chan;
                    100:        return 0;
                    101: }
                    102:
                    103: /*
                    104:  * l2cap_bind(l2cap_channel, sockaddr)
                    105:  *
                    106:  *     set local address of channel
                    107:  */
                    108: int
                    109: l2cap_bind(struct l2cap_channel *chan, struct sockaddr_bt *addr)
                    110: {
                    111:
                    112:        memcpy(&chan->lc_laddr, addr, sizeof(struct sockaddr_bt));
                    113:        return 0;
                    114: }
                    115:
                    116: /*
                    117:  * l2cap_sockaddr(l2cap_channel, sockaddr)
                    118:  *
                    119:  *     get local address of channel
                    120:  */
                    121: int
                    122: l2cap_sockaddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
                    123: {
                    124:
                    125:        memcpy(addr, &chan->lc_laddr, sizeof(struct sockaddr_bt));
                    126:        return 0;
                    127: }
                    128:
                    129: /*
                    130:  * l2cap_connect(l2cap_channel, sockaddr)
                    131:  *
                    132:  *     Initiate a connection to destination. This corresponds to
                    133:  *     "Open Channel Request" in the L2CAP specification and will
                    134:  *     result in one of the following:
                    135:  *
                    136:  *             proto->connected(upper)
                    137:  *             proto->disconnected(upper, error)
                    138:  *
                    139:  *     and, optionally
                    140:  *             proto->connecting(upper)
                    141:  */
                    142: int
                    143: l2cap_connect(struct l2cap_channel *chan, struct sockaddr_bt *dest)
                    144: {
                    145:        struct hci_unit *unit;
                    146:        int err;
                    147:
                    148:        memcpy(&chan->lc_raddr, dest, sizeof(struct sockaddr_bt));
                    149:
                    150:        if (L2CAP_PSM_INVALID(chan->lc_raddr.bt_psm))
                    151:                return EINVAL;
                    152:
                    153:        if (bdaddr_any(&chan->lc_raddr.bt_bdaddr))
                    154:                return EDESTADDRREQ;
                    155:
                    156:        /* set local address if it needs setting */
                    157:        if (bdaddr_any(&chan->lc_laddr.bt_bdaddr)) {
                    158:                err = hci_route_lookup(&chan->lc_laddr.bt_bdaddr,
                    159:                                        &chan->lc_raddr.bt_bdaddr);
                    160:                if (err)
                    161:                        return err;
                    162:        }
                    163:
                    164:        unit = hci_unit_lookup(&chan->lc_laddr.bt_bdaddr);
                    165:        if (unit == NULL)
                    166:                return EHOSTUNREACH;
                    167:
                    168:        /* attach to active list */
                    169:        err = l2cap_cid_alloc(chan);
                    170:        if (err)
                    171:                return err;
                    172:
                    173:        /* open link to remote device */
                    174:        chan->lc_link = hci_acl_open(unit, &chan->lc_raddr.bt_bdaddr);
                    175:        if (chan->lc_link == NULL)
                    176:                return EHOSTUNREACH;
                    177:
                    178:        /* set the link mode */
                    179:        err = l2cap_setmode(chan);
                    180:        if (err == EINPROGRESS) {
                    181:                chan->lc_state = L2CAP_WAIT_SEND_CONNECT_REQ;
                    182:                (*chan->lc_proto->connecting)(chan->lc_upper);
                    183:                return 0;
                    184:        }
                    185:        if (err)
                    186:                goto fail;
                    187:
                    188:        /*
                    189:         * We can queue a connect request now even though the link may
                    190:         * not yet be open; Our mode setting is assured, and the queue
                    191:         * will be started automatically at the right time.
                    192:         */
                    193:        chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP;
                    194:        err = l2cap_send_connect_req(chan);
                    195:        if (err)
                    196:                goto fail;
                    197:
                    198:        return 0;
                    199:
                    200: fail:
                    201:        chan->lc_state = L2CAP_CLOSED;
                    202:        hci_acl_close(chan->lc_link, err);
                    203:        chan->lc_link = NULL;
                    204:        return err;
                    205: }
                    206:
                    207: /*
                    208:  * l2cap_peeraddr(l2cap_channel, sockaddr)
                    209:  *
                    210:  *     get remote address of channel
                    211:  */
                    212: int
                    213: l2cap_peeraddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
                    214: {
                    215:
                    216:        memcpy(addr, &chan->lc_raddr, sizeof(struct sockaddr_bt));
                    217:        return 0;
                    218: }
                    219:
                    220: /*
                    221:  * l2cap_disconnect(l2cap_channel, linger)
                    222:  *
                    223:  *     Initiate L2CAP disconnection. This corresponds to
                    224:  *     "Close Channel Request" in the L2CAP specification
                    225:  *     and will result in a call to
                    226:  *
                    227:  *             proto->disconnected(upper, error)
                    228:  *
                    229:  *     when the disconnection is complete. If linger is set,
                    230:  *     the call will not be made until data has flushed from
                    231:  *     the queue.
                    232:  */
                    233: int
                    234: l2cap_disconnect(struct l2cap_channel *chan, int linger)
                    235: {
                    236:        int err = 0;
                    237:
                    238:        if (chan->lc_state == L2CAP_CLOSED
                    239:            || chan->lc_state == L2CAP_WAIT_DISCONNECT)
                    240:                return EINVAL;
                    241:
                    242:        chan->lc_flags |= L2CAP_SHUTDOWN;
                    243:
                    244:        /*
                    245:         * no need to do anything unless the queue is empty or
                    246:         * we are not lingering..
                    247:         */
                    248:        if ((IF_IS_EMPTY(&chan->lc_txq) && chan->lc_pending == 0)
                    249:            || linger == 0) {
                    250:                chan->lc_state = L2CAP_WAIT_DISCONNECT;
                    251:                err = l2cap_send_disconnect_req(chan);
                    252:                if (err)
                    253:                        l2cap_close(chan, err);
                    254:        }
                    255:        return err;
                    256: }
                    257:
                    258: /*
                    259:  * l2cap_detach(handle)
                    260:  *
                    261:  *     Detach l2cap channel from handle & close it down
                    262:  */
                    263: int
                    264: l2cap_detach(struct l2cap_channel **handle)
                    265: {
                    266:        struct l2cap_channel *chan;
                    267:
                    268:        chan = *handle;
                    269:        *handle = NULL;
                    270:
                    271:        if (chan->lc_state != L2CAP_CLOSED)
                    272:                l2cap_close(chan, 0);
                    273:
                    274:        if (chan->lc_lcid != L2CAP_NULL_CID) {
                    275:                LIST_REMOVE(chan, lc_ncid);
                    276:                chan->lc_lcid = L2CAP_NULL_CID;
                    277:        }
                    278:
                    279:        IF_PURGE(&chan->lc_txq);
                    280:
                    281:        /*
                    282:         * Could implement some kind of delayed expunge to make sure that the
                    283:         * CID is really dead before it becomes available for reuse?
                    284:         */
                    285:
                    286:        free(chan, M_BLUETOOTH);
                    287:        return 0;
                    288: }
                    289:
                    290: /*
                    291:  * l2cap_listen(l2cap_channel)
                    292:  *
                    293:  *     Use this channel as a listening post (until detached). This will
                    294:  *     result in calls to:
                    295:  *
                    296:  *             proto->newconn(upper, laddr, raddr)
                    297:  *
                    298:  *     for incoming connections matching the psm and local address of the
                    299:  *     channel (NULL psm/address are permitted and match any protocol/device).
                    300:  *
                    301:  *     The upper layer should create and return a new channel.
                    302:  *
                    303:  *     You cannot use this channel for anything else subsequent to this call
                    304:  */
                    305: int
                    306: l2cap_listen(struct l2cap_channel *chan)
                    307: {
                    308:        struct l2cap_channel *used, *prev = NULL;
                    309:
                    310:        if (chan->lc_lcid != L2CAP_NULL_CID)
                    311:                return EINVAL;
                    312:
                    313:        if (chan->lc_laddr.bt_psm != L2CAP_PSM_ANY
                    314:            && L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm))
                    315:                return EADDRNOTAVAIL;
                    316:
                    317:        /*
                    318:         * This CID is irrelevant, as the channel is not stored on the active
                    319:         * list and the socket code does not allow operations on listening
                    320:         * sockets, but we set it so the detach code knows to LIST_REMOVE the
                    321:         * channel.
                    322:         */
                    323:        chan->lc_lcid = L2CAP_SIGNAL_CID;
                    324:
                    325:        /*
                    326:         * The list of listening channels is stored in an order such that new
                    327:         * listeners dont usurp current listeners, but that specific listening
                    328:         * takes precedence over promiscuous, and the connect request code can
                    329:         * easily use the first matching entry.
                    330:         */
                    331:        LIST_FOREACH(used, &l2cap_listen_list, lc_ncid) {
                    332:                if (used->lc_laddr.bt_psm < chan->lc_laddr.bt_psm)
                    333:                        break;
                    334:
                    335:                if (used->lc_laddr.bt_psm == chan->lc_laddr.bt_psm
                    336:                        && bdaddr_any(&used->lc_laddr.bt_bdaddr)
                    337:                        && !bdaddr_any(&chan->lc_laddr.bt_bdaddr))
                    338:                        break;
                    339:
                    340:                prev = used;
                    341:        }
                    342:
                    343:        if (prev == NULL)
                    344:                LIST_INSERT_HEAD(&l2cap_listen_list, chan, lc_ncid);
                    345:        else
                    346:                LIST_INSERT_AFTER(prev, chan, lc_ncid);
                    347:
                    348:        return 0;
                    349: }
                    350:
                    351: /*
                    352:  * l2cap_send(l2cap_channel, mbuf)
                    353:  *
                    354:  *     Output SDU on channel described by channel. This corresponds
                    355:  *     to "Send Data Request" in the L2CAP specification. The upper
                    356:  *     layer will be notified when SDU's have completed sending by a
                    357:  *     call to:
                    358:  *
                    359:  *             proto->complete(upper, n)
                    360:  *
                    361:  *     (currently n == 1)
                    362:  *
                    363:  *     Note: I'm not sure how this will work out, but I think that
                    364:  *     if outgoing Retransmission Mode or Flow Control Mode is
                    365:  *     negotiated then this call will not be made until the SDU has
                    366:  *     been acknowleged by the peer L2CAP entity. For 'Best Effort'
                    367:  *     it will be made when the packet has cleared the controller
                    368:  *     buffers.
                    369:  *
                    370:  *     We only support Basic mode so far, so encapsulate with a
                    371:  *     B-Frame header and start sending if we are not already
                    372:  */
                    373: int
                    374: l2cap_send(struct l2cap_channel *chan, struct mbuf *m)
                    375: {
                    376:        l2cap_hdr_t *hdr;
                    377:        int plen;
                    378:
                    379:        if (chan->lc_state == L2CAP_CLOSED) {
                    380:                m_freem(m);
                    381:                return ENOTCONN;
                    382:        }
                    383:
                    384:        plen = m->m_pkthdr.len;
                    385:
                    386:        DPRINTFN(5, "send %d bytes on CID #%d (pending = %d)\n",
                    387:                plen, chan->lc_lcid, chan->lc_pending);
                    388:
                    389:        /* Encapsulate with B-Frame */
                    390:        M_PREPEND(m, sizeof(l2cap_hdr_t), M_DONTWAIT);
                    391:        if (m == NULL)
                    392:                return ENOMEM;
                    393:
                    394:        hdr = mtod(m, l2cap_hdr_t *);
                    395:        hdr->length = htole16(plen);
                    396:        hdr->dcid = htole16(chan->lc_rcid);
                    397:
                    398:        /* Queue it on our list */
                    399:        IF_ENQUEUE(&chan->lc_txq, m);
                    400:
                    401:        /* If we are not sending, then start doing so */
                    402:        if (chan->lc_pending == 0)
                    403:                return l2cap_start(chan);
                    404:
                    405:        return 0;
                    406: }
                    407:
                    408: /*
                    409:  * l2cap_setopt(l2cap_channel, opt, addr)
                    410:  *
                    411:  *     Apply configuration options to channel. This corresponds to
                    412:  *     "Configure Channel Request" in the L2CAP specification.
                    413:  *
                    414:  *     for SO_L2CAP_LM, the settings will take effect when the
                    415:  *     channel is established. If the channel is already open,
                    416:  *     a call to
                    417:  *             proto->linkmode(upper, new)
                    418:  *
                    419:  *     will be made when the change is complete.
                    420:  */
                    421: int
                    422: l2cap_setopt(struct l2cap_channel *chan, int opt, void *addr)
                    423: {
                    424:        int mode, err = 0;
                    425:        uint16_t mtu;
                    426:
                    427:        switch (opt) {
                    428:        case SO_L2CAP_IMTU:     /* set Incoming MTU */
                    429:                mtu = *(uint16_t *)addr;
                    430:                if (mtu < L2CAP_MTU_MINIMUM)
                    431:                        err = EINVAL;
                    432:                else if (chan->lc_state == L2CAP_CLOSED)
                    433:                        chan->lc_imtu = mtu;
                    434:                else
                    435:                        err = EBUSY;
                    436:
                    437:                break;
                    438:
                    439:        case SO_L2CAP_LM:       /* set link mode */
                    440:                mode = *(int *)addr;
                    441:                mode &= (L2CAP_LM_SECURE | L2CAP_LM_ENCRYPT | L2CAP_LM_AUTH);
                    442:
                    443:                if (mode & L2CAP_LM_SECURE)
                    444:                        mode |= L2CAP_LM_ENCRYPT;
                    445:
                    446:                if (mode & L2CAP_LM_ENCRYPT)
                    447:                        mode |= L2CAP_LM_AUTH;
                    448:
                    449:                chan->lc_mode = mode;
                    450:
                    451:                if (chan->lc_state == L2CAP_OPEN)
                    452:                        err = l2cap_setmode(chan);
                    453:
                    454:                break;
                    455:
                    456:        case SO_L2CAP_OQOS:     /* set Outgoing QoS flow spec */
                    457:        case SO_L2CAP_FLUSH:    /* set Outgoing Flush Timeout */
                    458:        default:
                    459:                err = ENOPROTOOPT;
                    460:                break;
                    461:        }
                    462:
                    463:        return err;
                    464: }
                    465:
                    466: /*
                    467:  * l2cap_getopt(l2cap_channel, opt, addr)
                    468:  *
                    469:  *     Return configuration parameters.
                    470:  */
                    471: int
                    472: l2cap_getopt(struct l2cap_channel *chan, int opt, void *addr)
                    473: {
                    474:
                    475:        switch (opt) {
                    476:        case SO_L2CAP_IMTU:     /* get Incoming MTU */
                    477:                *(uint16_t *)addr = chan->lc_imtu;
                    478:                return sizeof(uint16_t);
                    479:
                    480:        case SO_L2CAP_OMTU:     /* get Outgoing MTU */
                    481:                *(uint16_t *)addr = chan->lc_omtu;
                    482:                return sizeof(uint16_t);
                    483:
                    484:        case SO_L2CAP_IQOS:     /* get Incoming QoS flow spec */
                    485:                memcpy(addr, &chan->lc_iqos, sizeof(l2cap_qos_t));
                    486:                return sizeof(l2cap_qos_t);
                    487:
                    488:        case SO_L2CAP_OQOS:     /* get Outgoing QoS flow spec */
                    489:                memcpy(addr, &chan->lc_oqos, sizeof(l2cap_qos_t));
                    490:                return sizeof(l2cap_qos_t);
                    491:
                    492:        case SO_L2CAP_FLUSH:    /* get Flush Timeout */
                    493:                *(uint16_t *)addr = chan->lc_flush;
                    494:                return sizeof(uint16_t);
                    495:
                    496:        case SO_L2CAP_LM:       /* get link mode */
                    497:                *(int *)addr = chan->lc_mode;
                    498:                return sizeof(int);
                    499:
                    500:        default:
                    501:                break;
                    502:        }
                    503:
                    504:        return 0;
                    505: }

CVSweb