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