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

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

1.1       nbrk        1: /*     $OpenBSD: rfcomm_session.c,v 1.1 2007/06/01 02:46:12 uwe Exp $  */
                      2: /*     $NetBSD: rfcomm_session.c,v 1.9 2007/04/21 06:15:23 plunky Exp $        */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2006 Itronix Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Written by Iain Hibbert for Itronix Inc.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. The name of Itronix Inc. may not be used to endorse
                     19:  *    or promote products derived from this software without specific
                     20:  *    prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     24:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     25:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
                     26:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     27:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     28:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
                     29:  * ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     32:  * POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/cdefs.h>
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/kernel.h>
                     39: #include <sys/mbuf.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/types.h>
                     43:
                     44: #include <netbt/bluetooth.h>
                     45: #include <netbt/hci.h>
                     46: #include <netbt/l2cap.h>
                     47: #include <netbt/rfcomm.h>
                     48:
                     49: /******************************************************************************
                     50:  *
                     51:  * RFCOMM Multiplexer Sessions sit directly on L2CAP channels, and can
                     52:  * multiplex up to 30 incoming and 30 outgoing connections.
                     53:  * Only one Multiplexer is allowed between any two devices.
                     54:  */
                     55:
                     56: static void rfcomm_session_timeout(void *);
                     57: static void rfcomm_session_recv_sabm(struct rfcomm_session *, int);
                     58: static void rfcomm_session_recv_disc(struct rfcomm_session *, int);
                     59: static void rfcomm_session_recv_ua(struct rfcomm_session *, int);
                     60: static void rfcomm_session_recv_dm(struct rfcomm_session *, int);
                     61: static void rfcomm_session_recv_uih(struct rfcomm_session *, int, int, struct mbuf *, int);
                     62: static void rfcomm_session_recv_mcc(struct rfcomm_session *, struct mbuf *);
                     63: static void rfcomm_session_recv_mcc_test(struct rfcomm_session *, int, struct mbuf *);
                     64: static void rfcomm_session_recv_mcc_fcon(struct rfcomm_session *, int);
                     65: static void rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *, int);
                     66: static void rfcomm_session_recv_mcc_msc(struct rfcomm_session *, int, struct mbuf *);
                     67: static void rfcomm_session_recv_mcc_rpn(struct rfcomm_session *, int, struct mbuf *);
                     68: static void rfcomm_session_recv_mcc_rls(struct rfcomm_session *, int, struct mbuf *);
                     69: static void rfcomm_session_recv_mcc_pn(struct rfcomm_session *, int, struct mbuf *);
                     70: static void rfcomm_session_recv_mcc_nsc(struct rfcomm_session *, int, struct mbuf *);
                     71:
                     72: /* L2CAP callbacks */
                     73: static void rfcomm_session_connecting(void *);
                     74: static void rfcomm_session_connected(void *);
                     75: static void rfcomm_session_disconnected(void *, int);
                     76: static void *rfcomm_session_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
                     77: static void rfcomm_session_complete(void *, int);
                     78: static void rfcomm_session_linkmode(void *, int);
                     79: static void rfcomm_session_input(void *, struct mbuf *);
                     80:
                     81: static const struct btproto rfcomm_session_proto = {
                     82:        rfcomm_session_connecting,
                     83:        rfcomm_session_connected,
                     84:        rfcomm_session_disconnected,
                     85:        rfcomm_session_newconn,
                     86:        rfcomm_session_complete,
                     87:        rfcomm_session_linkmode,
                     88:        rfcomm_session_input,
                     89: };
                     90:
                     91: struct rfcomm_session_list
                     92:        rfcomm_session_active = LIST_HEAD_INITIALIZER(rfcomm_session_active);
                     93:
                     94: struct rfcomm_session_list
                     95:        rfcomm_session_listen = LIST_HEAD_INITIALIZER(rfcomm_session_listen);
                     96:
                     97: struct pool rfcomm_credit_pool;
                     98:
                     99: /*
                    100:  * RFCOMM System Parameters (see section 5.3)
                    101:  */
                    102: int rfcomm_mtu_default = 127;  /* bytes */
                    103: int rfcomm_ack_timeout = 20;   /* seconds */
                    104: int rfcomm_mcc_timeout = 20;   /* seconds */
                    105:
                    106: /*
                    107:  * Reversed CRC table as per TS 07.10 Annex B.3.5
                    108:  */
                    109: static const uint8_t crctable[256] = { /* reversed, 8-bit, poly=0x07 */
                    110:        0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
                    111:        0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
                    112:        0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
                    113:        0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
                    114:
                    115:        0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
                    116:        0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
                    117:        0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
                    118:        0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
                    119:
                    120:        0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
                    121:        0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
                    122:        0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
                    123:        0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
                    124:
                    125:        0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
                    126:        0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
                    127:        0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
                    128:        0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
                    129:
                    130:        0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
                    131:        0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
                    132:        0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
                    133:        0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
                    134:
                    135:        0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
                    136:        0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
                    137:        0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
                    138:        0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
                    139:
                    140:        0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
                    141:        0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
                    142:        0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
                    143:        0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
                    144:
                    145:        0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
                    146:        0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
                    147:        0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
                    148:        0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
                    149: };
                    150:
                    151: #define FCS(f, d)      crctable[(f) ^ (d)]
                    152:
                    153: /*
                    154:  * rfcomm_init()
                    155:  *
                    156:  * initialize the "credit pool".
                    157:  */
                    158: void
                    159: rfcomm_init(void)
                    160: {
                    161:        pool_init(&rfcomm_credit_pool, 0, 0, 0, 0, "rfcomm_credit", NULL);
                    162: }
                    163:
                    164: /*
                    165:  * rfcomm_session_alloc(list, sockaddr)
                    166:  *
                    167:  * allocate a new session and fill in the blanks, then
                    168:  * attach session to front of specified list (active or listen)
                    169:  */
                    170: struct rfcomm_session *
                    171: rfcomm_session_alloc(struct rfcomm_session_list *list,
                    172:                        struct sockaddr_bt *laddr)
                    173: {
                    174:        struct rfcomm_session *rs;
                    175:        int err;
                    176:
                    177:        rs = malloc(sizeof(*rs), M_BLUETOOTH, M_NOWAIT);
                    178:        if (rs == NULL)
                    179:                return NULL;
                    180:        bzero(rs, sizeof *rs);
                    181:
                    182:        rs->rs_state = RFCOMM_SESSION_CLOSED;
                    183:
                    184:        timeout_set(&rs->rs_timeout, rfcomm_session_timeout, rs);
                    185:
                    186:        SIMPLEQ_INIT(&rs->rs_credits);
                    187:        LIST_INIT(&rs->rs_dlcs);
                    188:
                    189:        err = l2cap_attach(&rs->rs_l2cap, &rfcomm_session_proto, rs);
                    190:        if (err) {
                    191:                free(rs, M_BLUETOOTH);
                    192:                return NULL;
                    193:        }
                    194:
                    195:        (void)l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
                    196:
                    197:        if (laddr->bt_psm == L2CAP_PSM_ANY)
                    198:                laddr->bt_psm = L2CAP_PSM_RFCOMM;
                    199:
                    200:        (void)l2cap_bind(rs->rs_l2cap, laddr);
                    201:
                    202:        LIST_INSERT_HEAD(list, rs, rs_next);
                    203:
                    204:        return rs;
                    205: }
                    206:
                    207: /*
                    208:  * rfcomm_session_free(rfcomm_session)
                    209:  *
                    210:  * release a session, including any cleanup
                    211:  */
                    212: void
                    213: rfcomm_session_free(struct rfcomm_session *rs)
                    214: {
                    215:        struct rfcomm_credit *credit;
                    216:
                    217:        KASSERT(rs != NULL);
                    218:        KASSERT(LIST_EMPTY(&rs->rs_dlcs));
                    219:
                    220:        rs->rs_state = RFCOMM_SESSION_CLOSED;
                    221:
                    222:        /*
                    223:         * If the callout is already invoked we have no way to stop it,
                    224:         * but it will call us back right away (there are no DLC's) so
                    225:         * not to worry.
                    226:         */
                    227:        timeout_del(&rs->rs_timeout);
                    228:        if (timeout_triggered(&rs->rs_timeout))
                    229:                return;
                    230:
                    231:        /*
                    232:         * Take care that rfcomm_session_disconnected() doesnt call
                    233:         * us back either as it will do if the l2cap_channel has not
                    234:         * been closed when we detach it..
                    235:         */
                    236:        if (rs->rs_flags & RFCOMM_SESSION_FREE)
                    237:                return;
                    238:
                    239:        rs->rs_flags |= RFCOMM_SESSION_FREE;
                    240:
                    241:        /* throw away any remaining credit notes */
                    242:        while ((credit = SIMPLEQ_FIRST(&rs->rs_credits)) != NULL) {
                    243:                SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
                    244:                pool_put(&rfcomm_credit_pool, credit);
                    245:        }
                    246:
                    247:        KASSERT(SIMPLEQ_EMPTY(&rs->rs_credits));
                    248:
                    249:        /* Goodbye! */
                    250:        LIST_REMOVE(rs, rs_next);
                    251:        l2cap_detach(&rs->rs_l2cap);
                    252:        free(rs, M_BLUETOOTH);
                    253: }
                    254:
                    255: /*
                    256:  * rfcomm_session_lookup(sockaddr, sockaddr)
                    257:  *
                    258:  * Find active rfcomm session matching src and dest addresses
                    259:  * when src is BDADDR_ANY match any local address
                    260:  */
                    261: struct rfcomm_session *
                    262: rfcomm_session_lookup(struct sockaddr_bt *src, struct sockaddr_bt *dest)
                    263: {
                    264:        struct rfcomm_session *rs;
                    265:        struct sockaddr_bt addr;
                    266:
                    267:        LIST_FOREACH(rs, &rfcomm_session_active, rs_next) {
                    268:                if (rs->rs_state == RFCOMM_SESSION_CLOSED)
                    269:                        continue;
                    270:
                    271:                l2cap_sockaddr(rs->rs_l2cap, &addr);
                    272:
                    273:                if (bdaddr_same(&src->bt_bdaddr, &addr.bt_bdaddr) == 0)
                    274:                        if (bdaddr_any(&src->bt_bdaddr) == 0)
                    275:                                continue;
                    276:
                    277:                l2cap_peeraddr(rs->rs_l2cap, &addr);
                    278:
                    279:                if (addr.bt_psm != dest->bt_psm)
                    280:                        continue;
                    281:
                    282:                if (bdaddr_same(&dest->bt_bdaddr, &addr.bt_bdaddr))
                    283:                        break;
                    284:        }
                    285:
                    286:        return rs;
                    287: }
                    288:
                    289: /*
                    290:  * rfcomm_session_timeout(rfcomm_session)
                    291:  *
                    292:  * Session timeouts are scheduled when a session is left or
                    293:  * created with no DLCs, and when SABM(0) or DISC(0) are
                    294:  * sent.
                    295:  *
                    296:  * So, if it is in an open state with DLC's attached then
                    297:  * we leave it alone, otherwise the session is lost.
                    298:  */
                    299: static void
                    300: rfcomm_session_timeout(void *arg)
                    301: {
                    302:        struct rfcomm_session *rs = arg;
                    303:        struct rfcomm_dlc *dlc;
                    304:        int s;
                    305:
                    306:        KASSERT(rs != NULL);
                    307:
                    308:        s = splsoftnet();
                    309:
                    310:        if (rs->rs_state != RFCOMM_SESSION_OPEN) {
                    311:                DPRINTF("timeout\n");
                    312:                rs->rs_state = RFCOMM_SESSION_CLOSED;
                    313:
                    314:                while (!LIST_EMPTY(&rs->rs_dlcs)) {
                    315:                        dlc = LIST_FIRST(&rs->rs_dlcs);
                    316:
                    317:                        rfcomm_dlc_close(dlc, ETIMEDOUT);
                    318:                }
                    319:        }
                    320:
                    321:        if (LIST_EMPTY(&rs->rs_dlcs)) {
                    322:                DPRINTF("expiring\n");
                    323:                rfcomm_session_free(rs);
                    324:        }
                    325:        splx(s);
                    326: }
                    327:
                    328: /***********************************************************************
                    329:  *
                    330:  *     RFCOMM Session L2CAP protocol callbacks
                    331:  *
                    332:  */
                    333:
                    334: static void
                    335: rfcomm_session_connecting(void *arg)
                    336: {
                    337:        /* struct rfcomm_session *rs = arg; */
                    338:
                    339:        DPRINTF("Connecting\n");
                    340: }
                    341:
                    342: static void
                    343: rfcomm_session_connected(void *arg)
                    344: {
                    345:        struct rfcomm_session *rs = arg;
                    346:
                    347:        DPRINTF("Connected\n");
                    348:
                    349:        /*
                    350:         * L2CAP is open.
                    351:         *
                    352:         * If we are initiator, we can send our SABM(0)
                    353:         * a timeout should be active?
                    354:         *
                    355:         * We must take note of the L2CAP MTU because currently
                    356:         * the L2CAP implementation can only do Basic Mode.
                    357:         */
                    358:        l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
                    359:
                    360:        rs->rs_mtu -= 6; /* (RFCOMM overhead could be this big) */
                    361:        if (rs->rs_mtu < RFCOMM_MTU_MIN) {
                    362:                rfcomm_session_disconnected(rs, EINVAL);
                    363:                return;
                    364:        }
                    365:
                    366:        if (IS_INITIATOR(rs)) {
                    367:                int err;
                    368:
                    369:                err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, 0);
                    370:                if (err)
                    371:                        rfcomm_session_disconnected(rs, err);
                    372:
                    373:                timeout_add(&rs->rs_timeout, rfcomm_ack_timeout * hz);
                    374:        }
                    375: }
                    376:
                    377: static void
                    378: rfcomm_session_disconnected(void *arg, int err)
                    379: {
                    380:        struct rfcomm_session *rs = arg;
                    381:        struct rfcomm_dlc *dlc;
                    382:
                    383:        DPRINTF("Disconnected\n");
                    384:
                    385:        rs->rs_state = RFCOMM_SESSION_CLOSED;
                    386:
                    387:        while (!LIST_EMPTY(&rs->rs_dlcs)) {
                    388:                dlc = LIST_FIRST(&rs->rs_dlcs);
                    389:
                    390:                rfcomm_dlc_close(dlc, err);
                    391:        }
                    392:
                    393:        rfcomm_session_free(rs);
                    394: }
                    395:
                    396: static void *
                    397: rfcomm_session_newconn(void *arg, struct sockaddr_bt *laddr,
                    398:                                struct sockaddr_bt *raddr)
                    399: {
                    400:        struct rfcomm_session *new, *rs = arg;
                    401:
                    402:        DPRINTF("New Connection\n");
                    403:
                    404:        /*
                    405:         * Incoming session connect request. We should return a new
                    406:         * session pointer if this is acceptable. The L2CAP layer
                    407:         * passes local and remote addresses, which we must check as
                    408:         * only one RFCOMM session is allowed between any two devices
                    409:         */
                    410:        new = rfcomm_session_lookup(laddr, raddr);
                    411:        if (new != NULL)
                    412:                return NULL;
                    413:
                    414:        new = rfcomm_session_alloc(&rfcomm_session_active, laddr);
                    415:        if (new == NULL)
                    416:                return NULL;
                    417:
                    418:        new->rs_mtu = rs->rs_mtu;
                    419:        new->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
                    420:
                    421:        /*
                    422:         * schedule an expiry so that if nothing comes of it we
                    423:         * can punt.
                    424:         */
                    425:        timeout_add(&new->rs_timeout, rfcomm_mcc_timeout * hz);
                    426:
                    427:        return new->rs_l2cap;
                    428: }
                    429:
                    430: static void
                    431: rfcomm_session_complete(void *arg, int count)
                    432: {
                    433:        struct rfcomm_session *rs = arg;
                    434:        struct rfcomm_credit *credit;
                    435:        struct rfcomm_dlc *dlc;
                    436:
                    437:        /*
                    438:         * count L2CAP packets are 'complete', meaning that they are cleared
                    439:         * our buffers (for best effort) or arrived safe (for guaranteed) so
                    440:         * we can take it off our list and pass the message on, so that
                    441:         * eventually the data can be removed from the sockbuf
                    442:         */
                    443:        while (count-- > 0) {
                    444:                credit = SIMPLEQ_FIRST(&rs->rs_credits);
                    445: #ifdef DIAGNOSTIC
                    446:                if (credit == NULL) {
                    447:                        printf("%s: too many packets completed!\n", __func__);
                    448:                        break;
                    449:                }
                    450: #endif
                    451:                dlc = credit->rc_dlc;
                    452:                if (dlc != NULL) {
                    453:                        dlc->rd_pending--;
                    454:                        (*dlc->rd_proto->complete)
                    455:                                        (dlc->rd_upper, credit->rc_len);
                    456:
                    457:                        /*
                    458:                         * if not using credit flow control, we may push
                    459:                         * more data now
                    460:                         */
                    461:                        if ((rs->rs_flags & RFCOMM_SESSION_CFC) == 0
                    462:                            && dlc->rd_state == RFCOMM_DLC_OPEN) {
                    463:                                rfcomm_dlc_start(dlc);
                    464:                        }
                    465:
                    466:                        /*
                    467:                         * When shutdown is indicated, we are just waiting to
                    468:                         * clear outgoing data.
                    469:                         */
                    470:                        if ((dlc->rd_flags & RFCOMM_DLC_SHUTDOWN)
                    471:                            && dlc->rd_txbuf == NULL && dlc->rd_pending == 0) {
                    472:                                dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
                    473:                                rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
                    474:                                                            dlc->rd_dlci);
                    475:                                timeout_add(&dlc->rd_timeout,
                    476:                                    rfcomm_ack_timeout * hz);
                    477:                        }
                    478:                }
                    479:
                    480:                SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
                    481:                pool_put(&rfcomm_credit_pool, credit);
                    482:        }
                    483:
                    484:        /*
                    485:         * If session is closed, we are just waiting to clear the queue
                    486:         */
                    487:        if (rs->rs_state == RFCOMM_SESSION_CLOSED) {
                    488:                if (SIMPLEQ_EMPTY(&rs->rs_credits))
                    489:                        l2cap_disconnect(rs->rs_l2cap, 0);
                    490:        }
                    491: }
                    492:
                    493: /*
                    494:  * Link Mode changed
                    495:  *
                    496:  * This is called when a mode change is complete. Proceed with connections
                    497:  * where appropriate, or pass the new mode to any active DLCs.
                    498:  */
                    499: static void
                    500: rfcomm_session_linkmode(void *arg, int new)
                    501: {
                    502:        struct rfcomm_session *rs = arg;
                    503:        struct rfcomm_dlc *dlc, *next;
                    504:        int err, mode = 0;
                    505:
                    506:        DPRINTF("auth %s, encrypt %s, secure %s\n",
                    507:                (new & L2CAP_LM_AUTH ? "on" : "off"),
                    508:                (new & L2CAP_LM_ENCRYPT ? "on" : "off"),
                    509:                (new & L2CAP_LM_SECURE ? "on" : "off"));
                    510:
                    511:        if (new & L2CAP_LM_AUTH)
                    512:                mode |= RFCOMM_LM_AUTH;
                    513:
                    514:        if (new & L2CAP_LM_ENCRYPT)
                    515:                mode |= RFCOMM_LM_ENCRYPT;
                    516:
                    517:        if (new & L2CAP_LM_SECURE)
                    518:                mode |= RFCOMM_LM_SECURE;
                    519:
                    520:        next = LIST_FIRST(&rs->rs_dlcs);
                    521:        while ((dlc = next) != NULL) {
                    522:                next = LIST_NEXT(dlc, rd_next);
                    523:
                    524:                switch (dlc->rd_state) {
                    525:                case RFCOMM_DLC_WAIT_SEND_SABM: /* we are connecting */
                    526:                        if ((mode & dlc->rd_mode) != dlc->rd_mode) {
                    527:                                rfcomm_dlc_close(dlc, ECONNABORTED);
                    528:                        } else {
                    529:                                err = rfcomm_session_send_frame(rs,
                    530:                                            RFCOMM_FRAME_SABM, dlc->rd_dlci);
                    531:                                if (err) {
                    532:                                        rfcomm_dlc_close(dlc, err);
                    533:                                } else {
                    534:                                        dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
                    535:                                        timeout_add(&dlc->rd_timeout,
                    536:                                            rfcomm_ack_timeout * hz);
                    537:                                        break;
                    538:                                }
                    539:                        }
                    540:
                    541:                        /*
                    542:                         * If we aborted the connection and there are no more DLCs
                    543:                         * on the session, it is our responsibility to disconnect.
                    544:                         */
                    545:                        if (!LIST_EMPTY(&rs->rs_dlcs))
                    546:                                break;
                    547:
                    548:                        rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
                    549:                        rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
                    550:                        timeout_add(&rs->rs_timeout, rfcomm_ack_timeout * hz);
                    551:                        break;
                    552:
                    553:                case RFCOMM_DLC_WAIT_SEND_UA: /* they are connecting */
                    554:                        if ((mode & dlc->rd_mode) != dlc->rd_mode) {
                    555:                                rfcomm_session_send_frame(rs,
                    556:                                            RFCOMM_FRAME_DM, dlc->rd_dlci);
                    557:                                rfcomm_dlc_close(dlc, ECONNABORTED);
                    558:                                break;
                    559:                        }
                    560:
                    561:                        err = rfcomm_session_send_frame(rs,
                    562:                                            RFCOMM_FRAME_UA, dlc->rd_dlci);
                    563:                        if (err) {
                    564:                                rfcomm_session_send_frame(rs,
                    565:                                                RFCOMM_FRAME_DM, dlc->rd_dlci);
                    566:                                rfcomm_dlc_close(dlc, err);
                    567:                                break;
                    568:                        }
                    569:
                    570:                        err = rfcomm_dlc_open(dlc);
                    571:                        if (err) {
                    572:                                rfcomm_session_send_frame(rs,
                    573:                                                RFCOMM_FRAME_DM, dlc->rd_dlci);
                    574:                                rfcomm_dlc_close(dlc, err);
                    575:                                break;
                    576:                        }
                    577:
                    578:                        break;
                    579:
                    580:                case RFCOMM_DLC_WAIT_RECV_UA:
                    581:                case RFCOMM_DLC_OPEN: /* already established */
                    582:                        (*dlc->rd_proto->linkmode)(dlc->rd_upper, mode);
                    583:                        break;
                    584:
                    585:                default:
                    586:                        break;
                    587:                }
                    588:        }
                    589: }
                    590:
                    591: /*
                    592:  * Receive data from L2CAP layer for session. There is always exactly one
                    593:  * RFCOMM frame contained in each L2CAP frame.
                    594:  */
                    595: static void
                    596: rfcomm_session_input(void *arg, struct mbuf *m)
                    597: {
                    598:        struct rfcomm_session *rs = arg;
                    599:        int dlci, len, type, pf;
                    600:        uint8_t fcs, b;
                    601:
                    602:        KASSERT(m != NULL);
                    603:        KASSERT(rs != NULL);
                    604:
                    605:        /*
                    606:         * UIH frames: FCS is only calculated on address and control fields
                    607:         * For other frames: FCS is calculated on address, control and length
                    608:         * Length may extend to two octets
                    609:         */
                    610:        fcs = 0xff;
                    611:
                    612:        if (m->m_pkthdr.len < 4) {
                    613:                DPRINTF("short frame (%d), discarded\n", m->m_pkthdr.len);
                    614:                goto done;
                    615:        }
                    616:
                    617:        /* address - one octet */
                    618:        m_copydata(m, 0, 1, &b);
                    619:        m_adj(m, 1);
                    620:        fcs = FCS(fcs, b);
                    621:        dlci = RFCOMM_DLCI(b);
                    622:
                    623:        /* control - one octet */
                    624:        m_copydata(m, 0, 1, &b);
                    625:        m_adj(m, 1);
                    626:        fcs = FCS(fcs, b);
                    627:        type = RFCOMM_TYPE(b);
                    628:        pf = RFCOMM_PF(b);
                    629:
                    630:        /* length - may be two octets */
                    631:        m_copydata(m, 0, 1, &b);
                    632:        m_adj(m, 1);
                    633:        if (type != RFCOMM_FRAME_UIH)
                    634:                fcs = FCS(fcs, b);
                    635:        len = (b >> 1) & 0x7f;
                    636:
                    637:        if (RFCOMM_EA(b) == 0) {
                    638:                if (m->m_pkthdr.len < 2) {
                    639:                        DPRINTF("short frame (%d, EA = 0), discarded\n",
                    640:                                m->m_pkthdr.len);
                    641:                        goto done;
                    642:                }
                    643:
                    644:                m_copydata(m, 0, 1, &b);
                    645:                m_adj(m, 1);
                    646:                if (type != RFCOMM_FRAME_UIH)
                    647:                        fcs = FCS(fcs, b);
                    648:
                    649:                len |= (b << 7);
                    650:        }
                    651:
                    652:        /* FCS byte is last octet in frame */
                    653:        m_copydata(m, m->m_pkthdr.len - 1, 1, &b);
                    654:        m_adj(m, -1);
                    655:        fcs = FCS(fcs, b);
                    656:
                    657:        if (fcs != 0xcf) {
                    658:                DPRINTF("Bad FCS value (%#2.2x), frame discarded\n", fcs);
                    659:                goto done;
                    660:        }
                    661:
                    662:        DPRINTFN(10, "dlci %d, type %2.2x, len = %d\n", dlci, type, len);
                    663:
                    664:        switch (type) {
                    665:        case RFCOMM_FRAME_SABM:
                    666:                if (pf)
                    667:                        rfcomm_session_recv_sabm(rs, dlci);
                    668:                break;
                    669:
                    670:        case RFCOMM_FRAME_DISC:
                    671:                if (pf)
                    672:                        rfcomm_session_recv_disc(rs, dlci);
                    673:                break;
                    674:
                    675:        case RFCOMM_FRAME_UA:
                    676:                if (pf)
                    677:                        rfcomm_session_recv_ua(rs, dlci);
                    678:                break;
                    679:
                    680:        case RFCOMM_FRAME_DM:
                    681:                rfcomm_session_recv_dm(rs, dlci);
                    682:                break;
                    683:
                    684:        case RFCOMM_FRAME_UIH:
                    685:                rfcomm_session_recv_uih(rs, dlci, pf, m, len);
                    686:                return; /* (no release) */
                    687:
                    688:        default:
                    689:                UNKNOWN(type);
                    690:                break;
                    691:        }
                    692:
                    693: done:
                    694:        m_freem(m);
                    695: }
                    696:
                    697: /***********************************************************************
                    698:  *
                    699:  *     RFCOMM Session receive processing
                    700:  */
                    701:
                    702: /*
                    703:  * rfcomm_session_recv_sabm(rfcomm_session, dlci)
                    704:  *
                    705:  * Set Asyncrhonous Balanced Mode - open the channel.
                    706:  */
                    707: static void
                    708: rfcomm_session_recv_sabm(struct rfcomm_session *rs, int dlci)
                    709: {
                    710:        struct rfcomm_dlc *dlc;
                    711:        int err;
                    712:
                    713:        DPRINTFN(5, "SABM(%d)\n", dlci);
                    714:
                    715:        if (dlci == 0) {        /* Open Session */
                    716:                rs->rs_state = RFCOMM_SESSION_OPEN;
                    717:                rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
                    718:                LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
                    719:                        if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
                    720:                                rfcomm_dlc_connect(dlc);
                    721:                }
                    722:                return;
                    723:        }
                    724:
                    725:        if (rs->rs_state != RFCOMM_SESSION_OPEN) {
                    726:                DPRINTF("session was not even open!\n");
                    727:                return;
                    728:        }
                    729:
                    730:        /* validate direction bit */
                    731:        if ((IS_INITIATOR(rs) && !RFCOMM_DIRECTION(dlci))
                    732:            || (!IS_INITIATOR(rs) && RFCOMM_DIRECTION(dlci))) {
                    733:                DPRINTF("Invalid direction bit on DLCI\n");
                    734:                return;
                    735:        }
                    736:
                    737:        /*
                    738:         * look for our DLC - this may exist if we received PN
                    739:         * already, or we may have to fabricate a new one.
                    740:         */
                    741:        dlc = rfcomm_dlc_lookup(rs, dlci);
                    742:        if (dlc == NULL) {
                    743:                dlc = rfcomm_dlc_newconn(rs, dlci);
                    744:                if (dlc == NULL)
                    745:                        return; /* (DM is sent) */
                    746:        }
                    747:
                    748:        /*
                    749:         * ..but if this DLC is not waiting to connect, they did
                    750:         * something wrong, ignore it.
                    751:         */
                    752:        if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
                    753:                return;
                    754:
                    755:        /* set link mode */
                    756:        err = rfcomm_dlc_setmode(dlc);
                    757:        if (err == EINPROGRESS) {
                    758:                dlc->rd_state = RFCOMM_DLC_WAIT_SEND_UA;
                    759:                (*dlc->rd_proto->connecting)(dlc->rd_upper);
                    760:                return;
                    761:        }
                    762:        if (err)
                    763:                goto close;
                    764:
                    765:        err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
                    766:        if (err)
                    767:                goto close;
                    768:
                    769:        /* and mark it open */
                    770:        err = rfcomm_dlc_open(dlc);
                    771:        if (err)
                    772:                goto close;
                    773:
                    774:        return;
                    775:
                    776: close:
                    777:        rfcomm_dlc_close(dlc, err);
                    778: }
                    779:
                    780: /*
                    781:  * Receive Disconnect Command
                    782:  */
                    783: static void
                    784: rfcomm_session_recv_disc(struct rfcomm_session *rs, int dlci)
                    785: {
                    786:        struct rfcomm_dlc *dlc;
                    787:
                    788:        DPRINTFN(5, "DISC(%d)\n", dlci);
                    789:
                    790:        if (dlci == 0) {
                    791:                /*
                    792:                 * Disconnect Session
                    793:                 *
                    794:                 * We set the session state to CLOSED so that when
                    795:                 * the UA frame is clear the session will be closed
                    796:                 * automatically. We wont bother to close any DLC's
                    797:                 * just yet as there should be none. In the unlikely
                    798:                 * event that something is left, it will get flushed
                    799:                 * out as the session goes down.
                    800:                 */
                    801:                rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
                    802:                rs->rs_state = RFCOMM_SESSION_CLOSED;
                    803:                return;
                    804:        }
                    805:
                    806:        dlc = rfcomm_dlc_lookup(rs, dlci);
                    807:        if (dlc == NULL) {
                    808:                rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
                    809:                return;
                    810:        }
                    811:
                    812:        rfcomm_dlc_close(dlc, ECONNRESET);
                    813:        rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
                    814: }
                    815:
                    816: /*
                    817:  * Receive Unnumbered Acknowledgement Response
                    818:  *
                    819:  * This should be a response to a DISC or SABM frame that we
                    820:  * have previously sent. If unexpected, ignore it.
                    821:  */
                    822: static void
                    823: rfcomm_session_recv_ua(struct rfcomm_session *rs, int dlci)
                    824: {
                    825:        struct rfcomm_dlc *dlc;
                    826:
                    827:        DPRINTFN(5, "UA(%d)\n", dlci);
                    828:
                    829:        if (dlci == 0) {
                    830:                switch (rs->rs_state) {
                    831:                case RFCOMM_SESSION_WAIT_CONNECT:       /* We sent SABM */
                    832:                        timeout_del(&rs->rs_timeout);
                    833:                        rs->rs_state = RFCOMM_SESSION_OPEN;
                    834:                        LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
                    835:                                if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
                    836:                                        rfcomm_dlc_connect(dlc);
                    837:                        }
                    838:                        break;
                    839:
                    840:                case RFCOMM_SESSION_WAIT_DISCONNECT:    /* We sent DISC */
                    841:                        timeout_del(&rs->rs_timeout);
                    842:                        rs->rs_state = RFCOMM_SESSION_CLOSED;
                    843:                        l2cap_disconnect(rs->rs_l2cap, 0);
                    844:                        break;
                    845:
                    846:                default:
                    847:                        DPRINTF("Received spurious UA(0)!\n");
                    848:                        break;
                    849:                }
                    850:
                    851:                return;
                    852:        }
                    853:
                    854:        /*
                    855:         * If we have no DLC on this dlci, we may have aborted
                    856:         * without shutting down properly, so check if the session
                    857:         * needs disconnecting.
                    858:         */
                    859:        dlc = rfcomm_dlc_lookup(rs, dlci);
                    860:        if (dlc == NULL)
                    861:                goto check;
                    862:
                    863:        switch (dlc->rd_state) {
                    864:        case RFCOMM_DLC_WAIT_RECV_UA:           /* We sent SABM */
                    865:                rfcomm_dlc_open(dlc);
                    866:                return;
                    867:
                    868:        case RFCOMM_DLC_WAIT_DISCONNECT:        /* We sent DISC */
                    869:                rfcomm_dlc_close(dlc, 0);
                    870:                break;
                    871:
                    872:        default:
                    873:                DPRINTF("Received spurious UA(%d)!\n", dlci);
                    874:                return;
                    875:        }
                    876:
                    877: check: /* last one out turns out the light */
                    878:        if (LIST_EMPTY(&rs->rs_dlcs)) {
                    879:                rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
                    880:                rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
                    881:                timeout_add(&rs->rs_timeout, rfcomm_ack_timeout * hz);
                    882:        }
                    883: }
                    884:
                    885: /*
                    886:  * Receive Disconnected Mode Response
                    887:  *
                    888:  * If this does not apply to a known DLC then we may ignore it.
                    889:  */
                    890: static void
                    891: rfcomm_session_recv_dm(struct rfcomm_session *rs, int dlci)
                    892: {
                    893:        struct rfcomm_dlc *dlc;
                    894:
                    895:        DPRINTFN(5, "DM(%d)\n", dlci);
                    896:
                    897:        dlc = rfcomm_dlc_lookup(rs, dlci);
                    898:        if (dlc == NULL)
                    899:                return;
                    900:
                    901:        if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT)
                    902:                rfcomm_dlc_close(dlc, ECONNREFUSED);
                    903:        else
                    904:                rfcomm_dlc_close(dlc, ECONNRESET);
                    905: }
                    906:
                    907: /*
                    908:  * Receive Unnumbered Information with Header check (MCC or data packet)
                    909:  */
                    910: static void
                    911: rfcomm_session_recv_uih(struct rfcomm_session *rs, int dlci,
                    912:                        int pf, struct mbuf *m, int len)
                    913: {
                    914:        struct rfcomm_dlc *dlc;
                    915:        uint8_t credits = 0;
                    916:
                    917:        DPRINTFN(10, "UIH(%d)\n", dlci);
                    918:
                    919:        if (dlci == 0) {
                    920:                rfcomm_session_recv_mcc(rs, m);
                    921:                return;
                    922:        }
                    923:
                    924:        if (m->m_pkthdr.len != len + pf) {
                    925:                DPRINTF("Bad Frame Length (%d), frame discarded\n",
                    926:                            m->m_pkthdr.len);
                    927:
                    928:                goto discard;
                    929:        }
                    930:
                    931:        dlc = rfcomm_dlc_lookup(rs, dlci);
                    932:        if (dlc == NULL) {
                    933:                DPRINTF("UIH received for non existent DLC, discarded\n");
                    934:                rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
                    935:                goto discard;
                    936:        }
                    937:
                    938:        if (dlc->rd_state != RFCOMM_DLC_OPEN) {
                    939:                DPRINTF("non-open DLC (state = %d), discarded\n",
                    940:                                dlc->rd_state);
                    941:                goto discard;
                    942:        }
                    943:
                    944:        /* if PF is set, credits were included */
                    945:        if (rs->rs_flags & RFCOMM_SESSION_CFC) {
                    946:                if (pf != 0) {
                    947:                        if (m->m_pkthdr.len < sizeof(credits)) {
                    948:                                DPRINTF("Bad PF value, UIH discarded\n");
                    949:                                goto discard;
                    950:                        }
                    951:
                    952:                        m_copydata(m, 0, sizeof(credits), &credits);
                    953:                        m_adj(m, sizeof(credits));
                    954:
                    955:                        dlc->rd_txcred += credits;
                    956:
                    957:                        if (credits > 0 && dlc->rd_txbuf != NULL)
                    958:                                rfcomm_dlc_start(dlc);
                    959:                }
                    960:
                    961:                if (len == 0)
                    962:                        goto discard;
                    963:
                    964:                if (dlc->rd_rxcred == 0) {
                    965:                        DPRINTF("Credit limit reached, UIH discarded\n");
                    966:                        goto discard;
                    967:                }
                    968:
                    969:                if (len > dlc->rd_rxsize) {
                    970:                        DPRINTF("UIH frame exceeds rxsize, discarded\n");
                    971:                        goto discard;
                    972:                }
                    973:
                    974:                dlc->rd_rxcred--;
                    975:                dlc->rd_rxsize -= len;
                    976:        }
                    977:
                    978:        (*dlc->rd_proto->input)(dlc->rd_upper, m);
                    979:        return;
                    980:
                    981: discard:
                    982:        m_freem(m);
                    983: }
                    984:
                    985: /*
                    986:  * Receive Multiplexer Control Command
                    987:  */
                    988: static void
                    989: rfcomm_session_recv_mcc(struct rfcomm_session *rs, struct mbuf *m)
                    990: {
                    991:        int type, cr, len;
                    992:        uint8_t b;
                    993:
                    994:        /*
                    995:         * Extract MCC header.
                    996:         *
                    997:         * Fields are variable length using extension bit = 1 to signify the
                    998:         * last octet in the sequence.
                    999:         *
                   1000:         * Only single octet types are defined in TS 07.10/RFCOMM spec
                   1001:         *
                   1002:         * Length can realistically only use 15 bits (max RFCOMM MTU)
                   1003:         */
                   1004:        if (m->m_pkthdr.len < sizeof(b)) {
                   1005:                DPRINTF("Short MCC header, discarded\n");
                   1006:                goto release;
                   1007:        }
                   1008:
                   1009:        m_copydata(m, 0, sizeof(b), &b);
                   1010:        m_adj(m, sizeof(b));
                   1011:
                   1012:        if (RFCOMM_EA(b) == 0) {        /* verify no extensions */
                   1013:                DPRINTF("MCC type EA = 0, discarded\n");
                   1014:                goto release;
                   1015:        }
                   1016:
                   1017:        type = RFCOMM_MCC_TYPE(b);
                   1018:        cr = RFCOMM_CR(b);
                   1019:
                   1020:        len = 0;
                   1021:        do {
                   1022:                if (m->m_pkthdr.len < sizeof(b)) {
                   1023:                        DPRINTF("Short MCC header, discarded\n");
                   1024:                        goto release;
                   1025:                }
                   1026:
                   1027:                m_copydata(m, 0, sizeof(b), &b);
                   1028:                m_adj(m, sizeof(b));
                   1029:
                   1030:                len = (len << 7) | (b >> 1);
                   1031:                len = min(len, RFCOMM_MTU_MAX);
                   1032:        } while (RFCOMM_EA(b) == 0);
                   1033:
                   1034:        if (len != m->m_pkthdr.len) {
                   1035:                DPRINTF("Incorrect MCC length, discarded\n");
                   1036:                goto release;
                   1037:        }
                   1038:
                   1039:        DPRINTFN(2, "MCC %s type %2.2x (%d bytes)\n",
                   1040:                (cr ? "command" : "response"), type, len);
                   1041:
                   1042:        /*
                   1043:         * pass to command handler
                   1044:         */
                   1045:        switch(type) {
                   1046:        case RFCOMM_MCC_TEST:   /* Test */
                   1047:                rfcomm_session_recv_mcc_test(rs, cr, m);
                   1048:                break;
                   1049:
                   1050:        case RFCOMM_MCC_FCON:   /* Flow Control On */
                   1051:                rfcomm_session_recv_mcc_fcon(rs, cr);
                   1052:                break;
                   1053:
                   1054:        case RFCOMM_MCC_FCOFF:  /* Flow Control Off */
                   1055:                rfcomm_session_recv_mcc_fcoff(rs, cr);
                   1056:                break;
                   1057:
                   1058:        case RFCOMM_MCC_MSC:    /* Modem Status Command */
                   1059:                rfcomm_session_recv_mcc_msc(rs, cr, m);
                   1060:                break;
                   1061:
                   1062:        case RFCOMM_MCC_RPN:    /* Remote Port Negotiation */
                   1063:                rfcomm_session_recv_mcc_rpn(rs, cr, m);
                   1064:                break;
                   1065:
                   1066:        case RFCOMM_MCC_RLS:    /* Remote Line Status */
                   1067:                rfcomm_session_recv_mcc_rls(rs, cr, m);
                   1068:                break;
                   1069:
                   1070:        case RFCOMM_MCC_PN:     /* Parameter Negotiation */
                   1071:                rfcomm_session_recv_mcc_pn(rs, cr, m);
                   1072:                break;
                   1073:
                   1074:        case RFCOMM_MCC_NSC:    /* Non Supported Command */
                   1075:                rfcomm_session_recv_mcc_nsc(rs, cr, m);
                   1076:                break;
                   1077:
                   1078:        default:
                   1079:                b = RFCOMM_MKMCC_TYPE(cr, type);
                   1080:                rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_NSC, &b, sizeof(b));
                   1081:        }
                   1082:
                   1083: release:
                   1084:        m_freem(m);
                   1085: }
                   1086:
                   1087: /*
                   1088:  * process TEST command/response
                   1089:  */
                   1090: static void
                   1091: rfcomm_session_recv_mcc_test(struct rfcomm_session *rs, int cr, struct mbuf *m)
                   1092: {
                   1093:        void *data;
                   1094:        int len;
                   1095:
                   1096:        if (cr == 0)    /* ignore ack */
                   1097:                return;
                   1098:
                   1099:        /*
                   1100:         * we must send all the data they included back as is
                   1101:         */
                   1102:
                   1103:        len = m->m_pkthdr.len;
                   1104:        if (len > RFCOMM_MTU_MAX)
                   1105:                return;
                   1106:
                   1107:        data = malloc(len, M_BLUETOOTH, M_NOWAIT);
                   1108:        if (data == NULL)
                   1109:                return;
                   1110:
                   1111:        m_copydata(m, 0, len, data);
                   1112:        rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_TEST, data, len);
                   1113:        free(data, M_BLUETOOTH);
                   1114: }
                   1115:
                   1116: /*
                   1117:  * process Flow Control ON command/response
                   1118:  */
                   1119: static void
                   1120: rfcomm_session_recv_mcc_fcon(struct rfcomm_session *rs, int cr)
                   1121: {
                   1122:
                   1123:        if (cr == 0)    /* ignore ack */
                   1124:                return;
                   1125:
                   1126:        rs->rs_flags |= RFCOMM_SESSION_RFC;
                   1127:        rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCON, NULL, 0);
                   1128: }
                   1129:
                   1130: /*
                   1131:  * process Flow Control OFF command/response
                   1132:  */
                   1133: static void
                   1134: rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *rs, int cr)
                   1135: {
                   1136:
                   1137:        if (cr == 0)    /* ignore ack */
                   1138:                return;
                   1139:
                   1140:        rs->rs_flags &= ~RFCOMM_SESSION_RFC;
                   1141:        rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCOFF, NULL, 0);
                   1142: }
                   1143:
                   1144: /*
                   1145:  * process Modem Status Command command/response
                   1146:  */
                   1147: static void
                   1148: rfcomm_session_recv_mcc_msc(struct rfcomm_session *rs, int cr, struct mbuf *m)
                   1149: {
                   1150:        struct rfcomm_mcc_msc msc;      /* (3 octets) */
                   1151:        struct rfcomm_dlc *dlc;
                   1152:        int len = 0;
                   1153:
                   1154:        /* [ADDRESS] */
                   1155:        if (m->m_pkthdr.len < sizeof(msc.address))
                   1156:                return;
                   1157:
                   1158:        m_copydata(m, 0, sizeof(msc.address), &msc.address);
                   1159:        m_adj(m, sizeof(msc.address));
                   1160:        len += sizeof(msc.address);
                   1161:
                   1162:        dlc = rfcomm_dlc_lookup(rs, RFCOMM_DLCI(msc.address));
                   1163:
                   1164:        if (cr == 0) {  /* ignore acks */
                   1165:                if (dlc != NULL)
                   1166:                        timeout_del(&dlc->rd_timeout);
                   1167:
                   1168:                return;
                   1169:        }
                   1170:
                   1171:        if (dlc == NULL) {
                   1172:                rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM,
                   1173:                                                RFCOMM_DLCI(msc.address));
                   1174:                return;
                   1175:        }
                   1176:
                   1177:        /* [SIGNALS] */
                   1178:        if (m->m_pkthdr.len < sizeof(msc.modem))
                   1179:                return;
                   1180:
                   1181:        m_copydata(m, 0, sizeof(msc.modem), &msc.modem);
                   1182:        m_adj(m, sizeof(msc.modem));
                   1183:        len += sizeof(msc.modem);
                   1184:
                   1185:        dlc->rd_rmodem = msc.modem;
                   1186:        /* XXX how do we signal this upstream? */
                   1187:
                   1188:        if (RFCOMM_EA(msc.modem) == 0) {
                   1189:                if (m->m_pkthdr.len < sizeof(msc.brk))
                   1190:                        return;
                   1191:
                   1192:                m_copydata(m, 0, sizeof(msc.brk), &msc.brk);
                   1193:                m_adj(m, sizeof(msc.brk));
                   1194:                len += sizeof(msc.brk);
                   1195:
                   1196:                /* XXX how do we signal this upstream? */
                   1197:        }
                   1198:
                   1199:        rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_MSC, &msc, len);
                   1200: }
                   1201:
                   1202: /*
                   1203:  * process Remote Port Negotiation command/response
                   1204:  */
                   1205: static void
                   1206: rfcomm_session_recv_mcc_rpn(struct rfcomm_session *rs, int cr, struct mbuf *m)
                   1207: {
                   1208:        struct rfcomm_mcc_rpn rpn;
                   1209:        uint16_t mask;
                   1210:
                   1211:        if (cr == 0)    /* ignore ack */
                   1212:                return;
                   1213:
                   1214:        /* default values */
                   1215:        rpn.bit_rate = RFCOMM_RPN_BR_9600;
                   1216:        rpn.line_settings = RFCOMM_RPN_8_N_1;
                   1217:        rpn.flow_control = RFCOMM_RPN_FLOW_NONE;
                   1218:        rpn.xon_char = RFCOMM_RPN_XON_CHAR;
                   1219:        rpn.xoff_char = RFCOMM_RPN_XOFF_CHAR;
                   1220:
                   1221:        if (m->m_pkthdr.len == sizeof(rpn)) {
                   1222:                m_copydata(m, 0, sizeof(rpn), (caddr_t)&rpn);
                   1223:                rpn.param_mask = RFCOMM_RPN_PM_ALL;
                   1224:        } else if (m->m_pkthdr.len == 1) {
                   1225:                m_copydata(m, 0, 1, (caddr_t)&rpn);
                   1226:                rpn.param_mask = letoh16(rpn.param_mask);
                   1227:        } else {
                   1228:                DPRINTF("Bad RPN length (%d)\n", m->m_pkthdr.len);
                   1229:                return;
                   1230:        }
                   1231:
                   1232:        mask = 0;
                   1233:
                   1234:        if (rpn.param_mask & RFCOMM_RPN_PM_RATE)
                   1235:                mask |= RFCOMM_RPN_PM_RATE;
                   1236:
                   1237:        if (rpn.param_mask & RFCOMM_RPN_PM_DATA
                   1238:            && RFCOMM_RPN_DATA_BITS(rpn.line_settings) == RFCOMM_RPN_DATA_8)
                   1239:                mask |= RFCOMM_RPN_PM_DATA;
                   1240:
                   1241:        if (rpn.param_mask & RFCOMM_RPN_PM_STOP
                   1242:            && RFCOMM_RPN_STOP_BITS(rpn.line_settings) == RFCOMM_RPN_STOP_1)
                   1243:                mask |= RFCOMM_RPN_PM_STOP;
                   1244:
                   1245:        if (rpn.param_mask & RFCOMM_RPN_PM_PARITY
                   1246:            && RFCOMM_RPN_PARITY(rpn.line_settings) == RFCOMM_RPN_PARITY_NONE)
                   1247:                mask |= RFCOMM_RPN_PM_PARITY;
                   1248:
                   1249:        if (rpn.param_mask & RFCOMM_RPN_PM_XON
                   1250:            && rpn.xon_char == RFCOMM_RPN_XON_CHAR)
                   1251:                mask |= RFCOMM_RPN_PM_XON;
                   1252:
                   1253:        if (rpn.param_mask & RFCOMM_RPN_PM_XOFF
                   1254:            && rpn.xoff_char == RFCOMM_RPN_XOFF_CHAR)
                   1255:                mask |= RFCOMM_RPN_PM_XOFF;
                   1256:
                   1257:        if (rpn.param_mask & RFCOMM_RPN_PM_FLOW
                   1258:            && rpn.flow_control == RFCOMM_RPN_FLOW_NONE)
                   1259:                mask |= RFCOMM_RPN_PM_FLOW;
                   1260:
                   1261:        rpn.param_mask = htole16(mask);
                   1262:
                   1263:        rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RPN, &rpn, sizeof(rpn));
                   1264: }
                   1265:
                   1266: /*
                   1267:  * process Remote Line Status command/response
                   1268:  */
                   1269: static void
                   1270: rfcomm_session_recv_mcc_rls(struct rfcomm_session *rs, int cr, struct mbuf *m)
                   1271: {
                   1272:        struct rfcomm_mcc_rls rls;
                   1273:
                   1274:        if (cr == 0)    /* ignore ack */
                   1275:                return;
                   1276:
                   1277:        if (m->m_pkthdr.len != sizeof(rls)) {
                   1278:                DPRINTF("Bad RLS length %d\n", m->m_pkthdr.len);
                   1279:                return;
                   1280:        }
                   1281:
                   1282:        m_copydata(m, 0, sizeof(rls), (caddr_t)&rls);
                   1283:
                   1284:        /*
                   1285:         * So far as I can tell, we just send back what
                   1286:         * they sent us. This signifies errors that seem
                   1287:         * irrelevent for RFCOMM over L2CAP.
                   1288:         */
                   1289:        rls.address |= 0x03;    /* EA = 1, CR = 1 */
                   1290:        rls.status &= 0x0f;     /* only 4 bits valid */
                   1291:
                   1292:        rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RLS, &rls, sizeof(rls));
                   1293: }
                   1294:
                   1295: /*
                   1296:  * process Parameter Negotiation command/response
                   1297:  */
                   1298: static void
                   1299: rfcomm_session_recv_mcc_pn(struct rfcomm_session *rs, int cr, struct mbuf *m)
                   1300: {
                   1301:        struct rfcomm_dlc *dlc;
                   1302:        struct rfcomm_mcc_pn pn;
                   1303:        int err;
                   1304:
                   1305:        if (m->m_pkthdr.len != sizeof(pn)) {
                   1306:                DPRINTF("Bad PN length %d\n", m->m_pkthdr.len);
                   1307:                return;
                   1308:        }
                   1309:
                   1310:        m_copydata(m, 0, sizeof(pn), (caddr_t)&pn);
                   1311:
                   1312:        pn.dlci &= 0x3f;
                   1313:        pn.mtu = letoh16(pn.mtu);
                   1314:
                   1315:        dlc = rfcomm_dlc_lookup(rs, pn.dlci);
                   1316:        if (cr) {       /* Command */
                   1317:                /*
                   1318:                 * If there is no DLC present, this is a new
                   1319:                 * connection so attempt to make one
                   1320:                 */
                   1321:                if (dlc == NULL) {
                   1322:                        dlc = rfcomm_dlc_newconn(rs, pn.dlci);
                   1323:                        if (dlc == NULL)
                   1324:                                return; /* (DM is sent) */
                   1325:                }
                   1326:
                   1327:                /* accept any valid MTU, and offer it back */
                   1328:                pn.mtu = min(pn.mtu, RFCOMM_MTU_MAX);
                   1329:                pn.mtu = min(pn.mtu, rs->rs_mtu);
                   1330:                pn.mtu = max(pn.mtu, RFCOMM_MTU_MIN);
                   1331:                dlc->rd_mtu = pn.mtu;
                   1332:                pn.mtu = htole16(pn.mtu);
                   1333:
                   1334:                /* credits are only set before DLC is open */
                   1335:                if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT
                   1336:                    && (pn.flow_control & 0xf0) == 0xf0) {
                   1337:                        rs->rs_flags |= RFCOMM_SESSION_CFC;
                   1338:                        dlc->rd_txcred = pn.credits & 0x07;
                   1339:
                   1340:                        dlc->rd_rxcred = (dlc->rd_rxsize / dlc->rd_mtu);
                   1341:                        dlc->rd_rxcred = min(dlc->rd_rxcred,
                   1342:                                                RFCOMM_CREDITS_DEFAULT);
                   1343:
                   1344:                        pn.flow_control = 0xe0;
                   1345:                        pn.credits = dlc->rd_rxcred;
                   1346:                } else {
                   1347:                        pn.flow_control = 0x00;
                   1348:                        pn.credits = 0x00;
                   1349:                }
                   1350:
                   1351:                /* unused fields must be ignored and set to zero */
                   1352:                pn.ack_timer = 0;
                   1353:                pn.max_retrans = 0;
                   1354:
                   1355:                /* send our response */
                   1356:                err = rfcomm_session_send_mcc(rs, 0,
                   1357:                                        RFCOMM_MCC_PN, &pn, sizeof(pn));
                   1358:                if (err)
                   1359:                        goto close;
                   1360:
                   1361:        } else {        /* Response */
                   1362:                /* ignore responses with no matching DLC */
                   1363:                if (dlc == NULL)
                   1364:                        return;
                   1365:
                   1366:                timeout_del(&dlc->rd_timeout);
                   1367:
                   1368:                if (pn.mtu > RFCOMM_MTU_MAX || pn.mtu > dlc->rd_mtu) {
                   1369:                        dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
                   1370:                        err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
                   1371:                                                        pn.dlci);
                   1372:                        if (err)
                   1373:                                goto close;
                   1374:
                   1375:                        timeout_add(&dlc->rd_timeout,
                   1376:                            rfcomm_ack_timeout * hz);
                   1377:                        return;
                   1378:                }
                   1379:                dlc->rd_mtu = pn.mtu;
                   1380:
                   1381:                /* if DLC is not waiting to connect, we are done */
                   1382:                if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
                   1383:                        return;
                   1384:
                   1385:                /* set initial credits according to RFCOMM spec */
                   1386:                if ((pn.flow_control & 0xf0) == 0xe0) {
                   1387:                        rs->rs_flags |= RFCOMM_SESSION_CFC;
                   1388:                        dlc->rd_txcred = (pn.credits & 0x07);
                   1389:                }
                   1390:
                   1391:                timeout_add(&dlc->rd_timeout, rfcomm_ack_timeout * hz);
                   1392:
                   1393:                /* set link mode */
                   1394:                err = rfcomm_dlc_setmode(dlc);
                   1395:                if (err == EINPROGRESS) {
                   1396:                        dlc->rd_state = RFCOMM_DLC_WAIT_SEND_SABM;
                   1397:                        (*dlc->rd_proto->connecting)(dlc->rd_upper);
                   1398:                        return;
                   1399:                }
                   1400:                if (err)
                   1401:                        goto close;
                   1402:
                   1403:                /* we can proceed now */
                   1404:                err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, pn.dlci);
                   1405:                if (err)
                   1406:                        goto close;
                   1407:
                   1408:                dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
                   1409:        }
                   1410:        return;
                   1411:
                   1412: close:
                   1413:        rfcomm_dlc_close(dlc, err);
                   1414: }
                   1415:
                   1416: /*
                   1417:  * process Non Supported Command command/response
                   1418:  */
                   1419: static void
                   1420: rfcomm_session_recv_mcc_nsc(struct rfcomm_session *rs,
                   1421:     int cr, struct mbuf *m)
                   1422: {
                   1423:        struct rfcomm_dlc *dlc, *next;
                   1424:
                   1425:        /*
                   1426:         * Since we did nothing that is not mandatory,
                   1427:         * we just abort the whole session..
                   1428:         */
                   1429:
                   1430:        next = LIST_FIRST(&rs->rs_dlcs);
                   1431:        while ((dlc = next) != NULL) {
                   1432:                next = LIST_NEXT(dlc, rd_next);
                   1433:                rfcomm_dlc_close(dlc, ECONNABORTED);
                   1434:        }
                   1435:
                   1436:        rfcomm_session_free(rs);
                   1437: }
                   1438:
                   1439: /***********************************************************************
                   1440:  *
                   1441:  *     RFCOMM Session outward frame/uih/mcc building
                   1442:  */
                   1443:
                   1444: /*
                   1445:  * SABM/DISC/DM/UA frames are all minimal and mostly identical.
                   1446:  */
                   1447: int
                   1448: rfcomm_session_send_frame(struct rfcomm_session *rs, int type, int dlci)
                   1449: {
                   1450:        struct rfcomm_cmd_hdr *hdr;
                   1451:        struct rfcomm_credit *credit;
                   1452:        struct mbuf *m;
                   1453:        uint8_t fcs, cr;
                   1454:
                   1455:        credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
                   1456:        if (credit == NULL)
                   1457:                return ENOMEM;
                   1458:
                   1459:        m = m_gethdr(M_DONTWAIT, MT_DATA);
                   1460:        if (m == NULL) {
                   1461:                pool_put(&rfcomm_credit_pool, credit);
                   1462:                return ENOMEM;
                   1463:        }
                   1464:
                   1465:        /*
                   1466:         * The CR (command/response) bit identifies the frame either as a
                   1467:         * commmand or a response and is used along with the DLCI to form
                   1468:         * the address. Commands contain the non-initiator address, whereas
                   1469:         * responses contain the initiator address, so the CR value is
                   1470:         * also dependent on the session direction.
                   1471:         */
                   1472:        if (type == RFCOMM_FRAME_UA || type == RFCOMM_FRAME_DM)
                   1473:                cr = IS_INITIATOR(rs) ? 0 : 1;
                   1474:        else
                   1475:                cr = IS_INITIATOR(rs) ? 1 : 0;
                   1476:
                   1477:        hdr = mtod(m, struct rfcomm_cmd_hdr *);
                   1478:        hdr->address = RFCOMM_MKADDRESS(cr, dlci);
                   1479:        hdr->control = RFCOMM_MKCONTROL(type, 1);   /* PF = 1 */
                   1480:        hdr->length = (0x00 << 1) | 0x01;           /* len = 0x00, EA = 1 */
                   1481:
                   1482:        fcs = 0xff;
                   1483:        fcs = FCS(fcs, hdr->address);
                   1484:        fcs = FCS(fcs, hdr->control);
                   1485:        fcs = FCS(fcs, hdr->length);
                   1486:        fcs = 0xff - fcs;       /* ones complement */
                   1487:        hdr->fcs = fcs;
                   1488:
                   1489:        m->m_pkthdr.len = m->m_len = sizeof(struct rfcomm_cmd_hdr);
                   1490:
                   1491:        /* empty credit note */
                   1492:        credit->rc_dlc = NULL;
                   1493:        credit->rc_len = m->m_pkthdr.len;
                   1494:        SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
                   1495:
                   1496:        DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n",
                   1497:                dlci, type, m->m_pkthdr.len, fcs);
                   1498:
                   1499:        return l2cap_send(rs->rs_l2cap, m);
                   1500: }
                   1501:
                   1502: /*
                   1503:  * rfcomm_session_send_uih(rfcomm_session, rfcomm_dlc, credits, mbuf)
                   1504:  *
                   1505:  * UIH frame is per DLC data or Multiplexer Control Commands
                   1506:  * when no DLC is given. Data mbuf is optional (just credits
                   1507:  * will be sent in that case)
                   1508:  */
                   1509: int
                   1510: rfcomm_session_send_uih(struct rfcomm_session *rs, struct rfcomm_dlc *dlc,
                   1511:                        int credits, struct mbuf *m)
                   1512: {
                   1513:        struct rfcomm_credit *credit;
                   1514:        struct mbuf *m0 = NULL;
                   1515:        int err, len;
                   1516:        uint8_t fcs, *hdr;
                   1517:
                   1518:        KASSERT(rs != NULL);
                   1519:
                   1520:        len = (m == NULL) ? 0 : m->m_pkthdr.len;
                   1521:        KASSERT(!(credits == 0 && len == 0));
                   1522:
                   1523:        /*
                   1524:         * Make a credit note for the completion notification
                   1525:         */
                   1526:        credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
                   1527:        if (credit == NULL)
                   1528:                goto nomem;
                   1529:
                   1530:        credit->rc_len = len;
                   1531:        credit->rc_dlc = dlc;
                   1532:
                   1533:        /*
                   1534:         * Wrap UIH frame information around payload.
                   1535:         *
                   1536:         * [ADDRESS] [CONTROL] [LENGTH] [CREDITS] [...] [FCS]
                   1537:         *
                   1538:         * Address is one octet.
                   1539:         * Control is one octet.
                   1540:         * Length is one or two octets.
                   1541:         * Credits may be one octet.
                   1542:         *
                   1543:         * FCS is one octet and calculated on address and
                   1544:         *      control octets only.
                   1545:         *
                   1546:         * If there are credits to be sent, we will set the PF
                   1547:         * flag and include them in the frame.
                   1548:         */
                   1549:        m0 = m_gethdr(M_DONTWAIT, MT_DATA);
                   1550:        if (m0 == NULL)
                   1551:                goto nomem;
                   1552:
                   1553:        MH_ALIGN(m0, 5);        /* (max 5 header octets) */
                   1554:        hdr = mtod(m0, uint8_t *);
                   1555:
                   1556:        /* CR bit is set according to the initiator of the session */
                   1557:        *hdr = RFCOMM_MKADDRESS((IS_INITIATOR(rs) ? 1 : 0),
                   1558:                                (dlc ? dlc->rd_dlci : 0));
                   1559:        fcs = FCS(0xff, *hdr);
                   1560:        hdr++;
                   1561:
                   1562:        /* PF bit is set if credits are being sent */
                   1563:        *hdr = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, (credits > 0 ? 1 : 0));
                   1564:        fcs = FCS(fcs, *hdr);
                   1565:        hdr++;
                   1566:
                   1567:        if (len < (1 << 7)) {
                   1568:                *hdr++ = ((len << 1) & 0xfe) | 0x01;    /* 7 bits, EA = 1 */
                   1569:        } else {
                   1570:                *hdr++ = ((len << 1) & 0xfe);           /* 7 bits, EA = 0 */
                   1571:                *hdr++ = ((len >> 7) & 0xff);           /* 8 bits, no EA */
                   1572:        }
                   1573:
                   1574:        if (credits > 0)
                   1575:                *hdr++ = (uint8_t)credits;
                   1576:
                   1577:        m0->m_len = hdr - mtod(m0, uint8_t *);
                   1578:
                   1579:        /* Append payload */
                   1580:        m0->m_next = m;
                   1581:        m = NULL;
                   1582:
                   1583:        m0->m_pkthdr.len = m0->m_len + len;
                   1584:
                   1585:        /* Append FCS */
                   1586:        fcs = 0xff - fcs;       /* ones complement */
                   1587:        len = m0->m_pkthdr.len;
                   1588:        m_copyback(m0, len, sizeof(fcs), &fcs);
                   1589:        if (m0->m_pkthdr.len != len + sizeof(fcs))
                   1590:                goto nomem;
                   1591:
                   1592:        DPRINTFN(10, "dlci %d, pktlen %d (%d data, %d credits), fcs=%#2.2x\n",
                   1593:                dlc ? dlc->rd_dlci : 0, m0->m_pkthdr.len, credit->rc_len,
                   1594:                credits, fcs);
                   1595:
                   1596:        /*
                   1597:         * UIH frame ready to go..
                   1598:         */
                   1599:        err = l2cap_send(rs->rs_l2cap, m0);
                   1600:        if (err)
                   1601:                goto fail;
                   1602:
                   1603:        SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
                   1604:        return 0;
                   1605:
                   1606: nomem:
                   1607:        err = ENOMEM;
                   1608:
                   1609:        if (m0 != NULL)
                   1610:                m_freem(m0);
                   1611:
                   1612:        if (m != NULL)
                   1613:                m_freem(m);
                   1614:
                   1615: fail:
                   1616:        if (credit != NULL)
                   1617:                pool_put(&rfcomm_credit_pool, credit);
                   1618:
                   1619:        return err;
                   1620: }
                   1621:
                   1622: /*
                   1623:  * send Multiplexer Control Command (or Response) on session
                   1624:  */
                   1625: int
                   1626: rfcomm_session_send_mcc(struct rfcomm_session *rs, int cr,
                   1627:                        uint8_t type, void *data, int len)
                   1628: {
                   1629:        struct mbuf *m;
                   1630:        uint8_t *hdr;
                   1631:        int hlen;
                   1632:
                   1633:        m = m_gethdr(M_DONTWAIT, MT_DATA);
                   1634:        if (m == NULL)
                   1635:                return ENOMEM;
                   1636:
                   1637:        hdr = mtod(m, uint8_t *);
                   1638:
                   1639:        /*
                   1640:         * Technically the type field can extend past one octet, but none
                   1641:         * currently defined will do that.
                   1642:         */
                   1643:        *hdr++ = RFCOMM_MKMCC_TYPE(cr, type);
                   1644:
                   1645:        /*
                   1646:         * In the frame, the max length size is 2 octets (15 bits) whereas
                   1647:         * no max length size is specified for MCC commands. We must allow
                   1648:         * for 3 octets since for MCC frames we use 7 bits + EA in each.
                   1649:         *
                   1650:         * Only test data can possibly be that big.
                   1651:         *
                   1652:         * XXX Should we check this against the MTU?
                   1653:         */
                   1654:        if (len < (1 << 7)) {
                   1655:                *hdr++ = ((len << 1) & 0xfe) | 0x01;    /* 7 bits, EA = 1 */
                   1656:        } else if (len < (1 << 14)) {
                   1657:                *hdr++ = ((len << 1) & 0xfe);           /* 7 bits, EA = 0 */
                   1658:                *hdr++ = ((len >> 6) & 0xfe) | 0x01;    /* 7 bits, EA = 1 */
                   1659:        } else if (len < (1 << 15)) {
                   1660:                *hdr++ = ((len << 1) & 0xfe);           /* 7 bits, EA = 0 */
                   1661:                *hdr++ = ((len >> 6) & 0xfe);           /* 7 bits, EA = 0 */
                   1662:                *hdr++ = ((len >> 13) & 0x02) | 0x01;   /* 1 bit,  EA = 1 */
                   1663:        } else {
                   1664:                DPRINTF("incredible length! (%d)\n", len);
                   1665:                m_freem(m);
                   1666:                return EMSGSIZE;
                   1667:        }
                   1668:
                   1669:        /*
                   1670:         * add command data (to same mbuf if possible)
                   1671:         */
                   1672:        hlen = hdr - mtod(m, uint8_t *);
                   1673:
                   1674:        if (len > 0) {
                   1675:                m->m_pkthdr.len = m->m_len = MHLEN;
                   1676:                m_copyback(m, hlen, len, data);
                   1677:                if (m->m_pkthdr.len != max(MHLEN, hlen + len)) {
                   1678:                        m_freem(m);
                   1679:                        return ENOMEM;
                   1680:                }
                   1681:        }
                   1682:
                   1683:        m->m_pkthdr.len = hlen + len;
                   1684:        m->m_len = min(MHLEN, m->m_pkthdr.len);
                   1685:
                   1686:        DPRINTFN(5, "%s type %2.2x len %d\n",
                   1687:                (cr ? "command" : "response"), type, m->m_pkthdr.len);
                   1688:
                   1689:        return rfcomm_session_send_uih(rs, NULL, 0, m);
                   1690: }

CVSweb