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