rfcomm_session.c revision 1.1.2.4 1 1.1.2.4 yamt /* $NetBSD: rfcomm_session.c,v 1.1.2.4 2007/09/03 14:42:43 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.4 yamt __KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.1.2.4 2007/09/03 14:42:43 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.2 yamt /* throw away any remaining credit notes */
232 1.1.2.2 yamt while ((credit = SIMPLEQ_FIRST(&rs->rs_credits)) != NULL) {
233 1.1.2.2 yamt SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
234 1.1.2.2 yamt pool_put(&rfcomm_credit_pool, credit);
235 1.1.2.2 yamt }
236 1.1.2.2 yamt
237 1.1.2.2 yamt KASSERT(SIMPLEQ_EMPTY(&rs->rs_credits));
238 1.1.2.2 yamt
239 1.1.2.2 yamt /* Goodbye! */
240 1.1.2.2 yamt LIST_REMOVE(rs, rs_next);
241 1.1.2.2 yamt l2cap_detach(&rs->rs_l2cap);
242 1.1.2.2 yamt free(rs, M_BLUETOOTH);
243 1.1.2.2 yamt }
244 1.1.2.2 yamt
245 1.1.2.2 yamt /*
246 1.1.2.2 yamt * rfcomm_session_lookup(sockaddr, sockaddr)
247 1.1.2.2 yamt *
248 1.1.2.2 yamt * Find active rfcomm session matching src and dest addresses
249 1.1.2.2 yamt * when src is BDADDR_ANY match any local address
250 1.1.2.2 yamt */
251 1.1.2.2 yamt struct rfcomm_session *
252 1.1.2.2 yamt rfcomm_session_lookup(struct sockaddr_bt *src, struct sockaddr_bt *dest)
253 1.1.2.2 yamt {
254 1.1.2.2 yamt struct rfcomm_session *rs;
255 1.1.2.2 yamt struct sockaddr_bt addr;
256 1.1.2.2 yamt
257 1.1.2.2 yamt LIST_FOREACH(rs, &rfcomm_session_active, rs_next) {
258 1.1.2.2 yamt if (rs->rs_state == RFCOMM_SESSION_CLOSED)
259 1.1.2.2 yamt continue;
260 1.1.2.2 yamt
261 1.1.2.2 yamt l2cap_sockaddr(rs->rs_l2cap, &addr);
262 1.1.2.2 yamt
263 1.1.2.2 yamt if (bdaddr_same(&src->bt_bdaddr, &addr.bt_bdaddr) == 0)
264 1.1.2.2 yamt if (bdaddr_any(&src->bt_bdaddr) == 0)
265 1.1.2.2 yamt continue;
266 1.1.2.2 yamt
267 1.1.2.2 yamt l2cap_peeraddr(rs->rs_l2cap, &addr);
268 1.1.2.2 yamt
269 1.1.2.2 yamt if (addr.bt_psm != dest->bt_psm)
270 1.1.2.2 yamt continue;
271 1.1.2.2 yamt
272 1.1.2.2 yamt if (bdaddr_same(&dest->bt_bdaddr, &addr.bt_bdaddr))
273 1.1.2.2 yamt break;
274 1.1.2.2 yamt }
275 1.1.2.2 yamt
276 1.1.2.2 yamt return rs;
277 1.1.2.2 yamt }
278 1.1.2.2 yamt
279 1.1.2.2 yamt /*
280 1.1.2.2 yamt * rfcomm_session_timeout(rfcomm_session)
281 1.1.2.2 yamt *
282 1.1.2.2 yamt * Session timeouts are scheduled when a session is left or
283 1.1.2.2 yamt * created with no DLCs, and when SABM(0) or DISC(0) are
284 1.1.2.2 yamt * sent.
285 1.1.2.2 yamt *
286 1.1.2.2 yamt * So, if it is in an open state with DLC's attached then
287 1.1.2.2 yamt * we leave it alone, otherwise the session is lost.
288 1.1.2.2 yamt */
289 1.1.2.2 yamt static void
290 1.1.2.2 yamt rfcomm_session_timeout(void *arg)
291 1.1.2.2 yamt {
292 1.1.2.2 yamt struct rfcomm_session *rs = arg;
293 1.1.2.2 yamt struct rfcomm_dlc *dlc;
294 1.1.2.2 yamt int s;
295 1.1.2.2 yamt
296 1.1.2.2 yamt KASSERT(rs != NULL);
297 1.1.2.2 yamt
298 1.1.2.2 yamt s = splsoftnet();
299 1.1.2.2 yamt callout_ack(&rs->rs_timeout);
300 1.1.2.2 yamt
301 1.1.2.2 yamt if (rs->rs_state != RFCOMM_SESSION_OPEN) {
302 1.1.2.2 yamt DPRINTF("timeout\n");
303 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_CLOSED;
304 1.1.2.2 yamt
305 1.1.2.2 yamt while (!LIST_EMPTY(&rs->rs_dlcs)) {
306 1.1.2.2 yamt dlc = LIST_FIRST(&rs->rs_dlcs);
307 1.1.2.2 yamt
308 1.1.2.2 yamt rfcomm_dlc_close(dlc, ETIMEDOUT);
309 1.1.2.2 yamt }
310 1.1.2.2 yamt }
311 1.1.2.2 yamt
312 1.1.2.2 yamt if (LIST_EMPTY(&rs->rs_dlcs)) {
313 1.1.2.2 yamt DPRINTF("expiring\n");
314 1.1.2.2 yamt rfcomm_session_free(rs);
315 1.1.2.2 yamt }
316 1.1.2.2 yamt splx(s);
317 1.1.2.2 yamt }
318 1.1.2.2 yamt
319 1.1.2.2 yamt /***********************************************************************
320 1.1.2.2 yamt *
321 1.1.2.2 yamt * RFCOMM Session L2CAP protocol callbacks
322 1.1.2.2 yamt *
323 1.1.2.2 yamt */
324 1.1.2.2 yamt
325 1.1.2.2 yamt static void
326 1.1.2.2 yamt rfcomm_session_connecting(void *arg)
327 1.1.2.2 yamt {
328 1.1.2.4 yamt /* struct rfcomm_session *rs = arg; */
329 1.1.2.2 yamt
330 1.1.2.2 yamt DPRINTF("Connecting\n");
331 1.1.2.2 yamt }
332 1.1.2.2 yamt
333 1.1.2.2 yamt static void
334 1.1.2.2 yamt rfcomm_session_connected(void *arg)
335 1.1.2.2 yamt {
336 1.1.2.2 yamt struct rfcomm_session *rs = arg;
337 1.1.2.2 yamt
338 1.1.2.2 yamt DPRINTF("Connected\n");
339 1.1.2.2 yamt
340 1.1.2.2 yamt /*
341 1.1.2.2 yamt * L2CAP is open.
342 1.1.2.2 yamt *
343 1.1.2.2 yamt * If we are initiator, we can send our SABM(0)
344 1.1.2.2 yamt * a timeout should be active?
345 1.1.2.2 yamt *
346 1.1.2.2 yamt * We must take note of the L2CAP MTU because currently
347 1.1.2.2 yamt * the L2CAP implementation can only do Basic Mode.
348 1.1.2.2 yamt */
349 1.1.2.2 yamt l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
350 1.1.2.2 yamt
351 1.1.2.2 yamt rs->rs_mtu -= 6; /* (RFCOMM overhead could be this big) */
352 1.1.2.2 yamt if (rs->rs_mtu < RFCOMM_MTU_MIN) {
353 1.1.2.2 yamt rfcomm_session_disconnected(rs, EINVAL);
354 1.1.2.2 yamt return;
355 1.1.2.2 yamt }
356 1.1.2.2 yamt
357 1.1.2.2 yamt if (IS_INITIATOR(rs)) {
358 1.1.2.2 yamt int err;
359 1.1.2.2 yamt
360 1.1.2.2 yamt err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, 0);
361 1.1.2.2 yamt if (err)
362 1.1.2.2 yamt rfcomm_session_disconnected(rs, err);
363 1.1.2.2 yamt
364 1.1.2.2 yamt callout_schedule(&rs->rs_timeout, rfcomm_ack_timeout * hz);
365 1.1.2.2 yamt }
366 1.1.2.2 yamt }
367 1.1.2.2 yamt
368 1.1.2.2 yamt static void
369 1.1.2.2 yamt rfcomm_session_disconnected(void *arg, int err)
370 1.1.2.2 yamt {
371 1.1.2.2 yamt struct rfcomm_session *rs = arg;
372 1.1.2.2 yamt struct rfcomm_dlc *dlc;
373 1.1.2.2 yamt
374 1.1.2.2 yamt DPRINTF("Disconnected\n");
375 1.1.2.2 yamt
376 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_CLOSED;
377 1.1.2.2 yamt
378 1.1.2.2 yamt while (!LIST_EMPTY(&rs->rs_dlcs)) {
379 1.1.2.2 yamt dlc = LIST_FIRST(&rs->rs_dlcs);
380 1.1.2.2 yamt
381 1.1.2.2 yamt rfcomm_dlc_close(dlc, err);
382 1.1.2.2 yamt }
383 1.1.2.2 yamt
384 1.1.2.2 yamt rfcomm_session_free(rs);
385 1.1.2.2 yamt }
386 1.1.2.2 yamt
387 1.1.2.2 yamt static void *
388 1.1.2.2 yamt rfcomm_session_newconn(void *arg, struct sockaddr_bt *laddr,
389 1.1.2.2 yamt struct sockaddr_bt *raddr)
390 1.1.2.2 yamt {
391 1.1.2.2 yamt struct rfcomm_session *new, *rs = arg;
392 1.1.2.2 yamt
393 1.1.2.2 yamt DPRINTF("New Connection\n");
394 1.1.2.2 yamt
395 1.1.2.2 yamt /*
396 1.1.2.2 yamt * Incoming session connect request. We should return a new
397 1.1.2.2 yamt * session pointer if this is acceptable. The L2CAP layer
398 1.1.2.2 yamt * passes local and remote addresses, which we must check as
399 1.1.2.2 yamt * only one RFCOMM session is allowed between any two devices
400 1.1.2.2 yamt */
401 1.1.2.2 yamt new = rfcomm_session_lookup(laddr, raddr);
402 1.1.2.2 yamt if (new != NULL)
403 1.1.2.2 yamt return NULL;
404 1.1.2.2 yamt
405 1.1.2.2 yamt new = rfcomm_session_alloc(&rfcomm_session_active, laddr);
406 1.1.2.2 yamt if (new == NULL)
407 1.1.2.2 yamt return NULL;
408 1.1.2.2 yamt
409 1.1.2.2 yamt new->rs_mtu = rs->rs_mtu;
410 1.1.2.2 yamt new->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
411 1.1.2.2 yamt
412 1.1.2.2 yamt /*
413 1.1.2.2 yamt * schedule an expiry so that if nothing comes of it we
414 1.1.2.2 yamt * can punt.
415 1.1.2.2 yamt */
416 1.1.2.2 yamt callout_schedule(&new->rs_timeout, rfcomm_mcc_timeout * hz);
417 1.1.2.2 yamt
418 1.1.2.2 yamt return new->rs_l2cap;
419 1.1.2.2 yamt }
420 1.1.2.2 yamt
421 1.1.2.2 yamt static void
422 1.1.2.2 yamt rfcomm_session_complete(void *arg, int count)
423 1.1.2.2 yamt {
424 1.1.2.2 yamt struct rfcomm_session *rs = arg;
425 1.1.2.2 yamt struct rfcomm_credit *credit;
426 1.1.2.2 yamt struct rfcomm_dlc *dlc;
427 1.1.2.2 yamt
428 1.1.2.2 yamt /*
429 1.1.2.2 yamt * count L2CAP packets are 'complete', meaning that they are cleared
430 1.1.2.2 yamt * our buffers (for best effort) or arrived safe (for guaranteed) so
431 1.1.2.2 yamt * we can take it off our list and pass the message on, so that
432 1.1.2.2 yamt * eventually the data can be removed from the sockbuf
433 1.1.2.2 yamt */
434 1.1.2.2 yamt while (count-- > 0) {
435 1.1.2.2 yamt credit = SIMPLEQ_FIRST(&rs->rs_credits);
436 1.1.2.2 yamt #ifdef DIAGNOSTIC
437 1.1.2.2 yamt if (credit == NULL) {
438 1.1.2.2 yamt printf("%s: too many packets completed!\n", __func__);
439 1.1.2.2 yamt break;
440 1.1.2.2 yamt }
441 1.1.2.2 yamt #endif
442 1.1.2.2 yamt dlc = credit->rc_dlc;
443 1.1.2.2 yamt if (dlc != NULL) {
444 1.1.2.2 yamt dlc->rd_pending--;
445 1.1.2.2 yamt (*dlc->rd_proto->complete)
446 1.1.2.2 yamt (dlc->rd_upper, credit->rc_len);
447 1.1.2.2 yamt
448 1.1.2.2 yamt /*
449 1.1.2.2 yamt * if not using credit flow control, we may push
450 1.1.2.2 yamt * more data now
451 1.1.2.2 yamt */
452 1.1.2.2 yamt if ((rs->rs_flags & RFCOMM_SESSION_CFC) == 0
453 1.1.2.2 yamt && dlc->rd_state == RFCOMM_DLC_OPEN) {
454 1.1.2.2 yamt rfcomm_dlc_start(dlc);
455 1.1.2.2 yamt }
456 1.1.2.2 yamt
457 1.1.2.2 yamt /*
458 1.1.2.2 yamt * When shutdown is indicated, we are just waiting to
459 1.1.2.2 yamt * clear outgoing data.
460 1.1.2.2 yamt */
461 1.1.2.2 yamt if ((dlc->rd_flags & RFCOMM_DLC_SHUTDOWN)
462 1.1.2.2 yamt && dlc->rd_txbuf == NULL && dlc->rd_pending == 0) {
463 1.1.2.2 yamt dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
464 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
465 1.1.2.2 yamt dlc->rd_dlci);
466 1.1.2.2 yamt callout_schedule(&dlc->rd_timeout,
467 1.1.2.2 yamt rfcomm_ack_timeout * hz);
468 1.1.2.2 yamt }
469 1.1.2.2 yamt }
470 1.1.2.2 yamt
471 1.1.2.2 yamt SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
472 1.1.2.2 yamt pool_put(&rfcomm_credit_pool, credit);
473 1.1.2.2 yamt }
474 1.1.2.2 yamt
475 1.1.2.2 yamt /*
476 1.1.2.2 yamt * If session is closed, we are just waiting to clear the queue
477 1.1.2.2 yamt */
478 1.1.2.2 yamt if (rs->rs_state == RFCOMM_SESSION_CLOSED) {
479 1.1.2.2 yamt if (SIMPLEQ_EMPTY(&rs->rs_credits))
480 1.1.2.2 yamt l2cap_disconnect(rs->rs_l2cap, 0);
481 1.1.2.2 yamt }
482 1.1.2.2 yamt }
483 1.1.2.2 yamt
484 1.1.2.2 yamt /*
485 1.1.2.4 yamt * Link Mode changed
486 1.1.2.4 yamt *
487 1.1.2.4 yamt * This is called when a mode change is complete. Proceed with connections
488 1.1.2.4 yamt * where appropriate, or pass the new mode to any active DLCs.
489 1.1.2.4 yamt */
490 1.1.2.4 yamt static void
491 1.1.2.4 yamt rfcomm_session_linkmode(void *arg, int new)
492 1.1.2.4 yamt {
493 1.1.2.4 yamt struct rfcomm_session *rs = arg;
494 1.1.2.4 yamt struct rfcomm_dlc *dlc, *next;
495 1.1.2.4 yamt int err, mode = 0;
496 1.1.2.4 yamt
497 1.1.2.4 yamt DPRINTF("auth %s, encrypt %s, secure %s\n",
498 1.1.2.4 yamt (new & L2CAP_LM_AUTH ? "on" : "off"),
499 1.1.2.4 yamt (new & L2CAP_LM_ENCRYPT ? "on" : "off"),
500 1.1.2.4 yamt (new & L2CAP_LM_SECURE ? "on" : "off"));
501 1.1.2.4 yamt
502 1.1.2.4 yamt if (new & L2CAP_LM_AUTH)
503 1.1.2.4 yamt mode |= RFCOMM_LM_AUTH;
504 1.1.2.4 yamt
505 1.1.2.4 yamt if (new & L2CAP_LM_ENCRYPT)
506 1.1.2.4 yamt mode |= RFCOMM_LM_ENCRYPT;
507 1.1.2.4 yamt
508 1.1.2.4 yamt if (new & L2CAP_LM_SECURE)
509 1.1.2.4 yamt mode |= RFCOMM_LM_SECURE;
510 1.1.2.4 yamt
511 1.1.2.4 yamt next = LIST_FIRST(&rs->rs_dlcs);
512 1.1.2.4 yamt while ((dlc = next) != NULL) {
513 1.1.2.4 yamt next = LIST_NEXT(dlc, rd_next);
514 1.1.2.4 yamt
515 1.1.2.4 yamt switch (dlc->rd_state) {
516 1.1.2.4 yamt case RFCOMM_DLC_WAIT_SEND_SABM: /* we are connecting */
517 1.1.2.4 yamt if ((mode & dlc->rd_mode) != dlc->rd_mode) {
518 1.1.2.4 yamt rfcomm_dlc_close(dlc, ECONNABORTED);
519 1.1.2.4 yamt } else {
520 1.1.2.4 yamt err = rfcomm_session_send_frame(rs,
521 1.1.2.4 yamt RFCOMM_FRAME_SABM, dlc->rd_dlci);
522 1.1.2.4 yamt if (err) {
523 1.1.2.4 yamt rfcomm_dlc_close(dlc, err);
524 1.1.2.4 yamt } else {
525 1.1.2.4 yamt dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
526 1.1.2.4 yamt callout_schedule(&dlc->rd_timeout,
527 1.1.2.4 yamt rfcomm_ack_timeout * hz);
528 1.1.2.4 yamt break;
529 1.1.2.4 yamt }
530 1.1.2.4 yamt }
531 1.1.2.4 yamt
532 1.1.2.4 yamt /*
533 1.1.2.4 yamt * If we aborted the connection and there are no more DLCs
534 1.1.2.4 yamt * on the session, it is our responsibility to disconnect.
535 1.1.2.4 yamt */
536 1.1.2.4 yamt if (!LIST_EMPTY(&rs->rs_dlcs))
537 1.1.2.4 yamt break;
538 1.1.2.4 yamt
539 1.1.2.4 yamt rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
540 1.1.2.4 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
541 1.1.2.4 yamt callout_schedule(&rs->rs_timeout, rfcomm_ack_timeout * hz);
542 1.1.2.4 yamt break;
543 1.1.2.4 yamt
544 1.1.2.4 yamt case RFCOMM_DLC_WAIT_SEND_UA: /* they are connecting */
545 1.1.2.4 yamt if ((mode & dlc->rd_mode) != dlc->rd_mode) {
546 1.1.2.4 yamt rfcomm_session_send_frame(rs,
547 1.1.2.4 yamt RFCOMM_FRAME_DM, dlc->rd_dlci);
548 1.1.2.4 yamt rfcomm_dlc_close(dlc, ECONNABORTED);
549 1.1.2.4 yamt break;
550 1.1.2.4 yamt }
551 1.1.2.4 yamt
552 1.1.2.4 yamt err = rfcomm_session_send_frame(rs,
553 1.1.2.4 yamt RFCOMM_FRAME_UA, dlc->rd_dlci);
554 1.1.2.4 yamt if (err) {
555 1.1.2.4 yamt rfcomm_session_send_frame(rs,
556 1.1.2.4 yamt RFCOMM_FRAME_DM, dlc->rd_dlci);
557 1.1.2.4 yamt rfcomm_dlc_close(dlc, err);
558 1.1.2.4 yamt break;
559 1.1.2.4 yamt }
560 1.1.2.4 yamt
561 1.1.2.4 yamt err = rfcomm_dlc_open(dlc);
562 1.1.2.4 yamt if (err) {
563 1.1.2.4 yamt rfcomm_session_send_frame(rs,
564 1.1.2.4 yamt RFCOMM_FRAME_DM, dlc->rd_dlci);
565 1.1.2.4 yamt rfcomm_dlc_close(dlc, err);
566 1.1.2.4 yamt break;
567 1.1.2.4 yamt }
568 1.1.2.4 yamt
569 1.1.2.4 yamt break;
570 1.1.2.4 yamt
571 1.1.2.4 yamt case RFCOMM_DLC_WAIT_RECV_UA:
572 1.1.2.4 yamt case RFCOMM_DLC_OPEN: /* already established */
573 1.1.2.4 yamt (*dlc->rd_proto->linkmode)(dlc->rd_upper, mode);
574 1.1.2.4 yamt break;
575 1.1.2.4 yamt
576 1.1.2.4 yamt default:
577 1.1.2.4 yamt break;
578 1.1.2.4 yamt }
579 1.1.2.4 yamt }
580 1.1.2.4 yamt }
581 1.1.2.4 yamt
582 1.1.2.4 yamt /*
583 1.1.2.2 yamt * Receive data from L2CAP layer for session. There is always exactly one
584 1.1.2.2 yamt * RFCOMM frame contained in each L2CAP frame.
585 1.1.2.2 yamt */
586 1.1.2.2 yamt static void
587 1.1.2.2 yamt rfcomm_session_input(void *arg, struct mbuf *m)
588 1.1.2.2 yamt {
589 1.1.2.2 yamt struct rfcomm_session *rs = arg;
590 1.1.2.2 yamt int dlci, len, type, pf;
591 1.1.2.2 yamt uint8_t fcs, b;
592 1.1.2.2 yamt
593 1.1.2.2 yamt KASSERT(m != NULL);
594 1.1.2.2 yamt KASSERT(rs != NULL);
595 1.1.2.2 yamt
596 1.1.2.2 yamt /*
597 1.1.2.2 yamt * UIH frames: FCS is only calculated on address and control fields
598 1.1.2.2 yamt * For other frames: FCS is calculated on address, control and length
599 1.1.2.2 yamt * Length may extend to two octets
600 1.1.2.2 yamt */
601 1.1.2.2 yamt fcs = 0xff;
602 1.1.2.2 yamt
603 1.1.2.2 yamt if (m->m_pkthdr.len < 4) {
604 1.1.2.2 yamt DPRINTF("short frame (%d), discarded\n", m->m_pkthdr.len);
605 1.1.2.2 yamt goto done;
606 1.1.2.2 yamt }
607 1.1.2.2 yamt
608 1.1.2.2 yamt /* address - one octet */
609 1.1.2.2 yamt m_copydata(m, 0, 1, &b);
610 1.1.2.2 yamt m_adj(m, 1);
611 1.1.2.2 yamt fcs = FCS(fcs, b);
612 1.1.2.2 yamt dlci = RFCOMM_DLCI(b);
613 1.1.2.2 yamt
614 1.1.2.2 yamt /* control - one octet */
615 1.1.2.2 yamt m_copydata(m, 0, 1, &b);
616 1.1.2.2 yamt m_adj(m, 1);
617 1.1.2.2 yamt fcs = FCS(fcs, b);
618 1.1.2.2 yamt type = RFCOMM_TYPE(b);
619 1.1.2.2 yamt pf = RFCOMM_PF(b);
620 1.1.2.2 yamt
621 1.1.2.2 yamt /* length - may be two octets */
622 1.1.2.2 yamt m_copydata(m, 0, 1, &b);
623 1.1.2.2 yamt m_adj(m, 1);
624 1.1.2.2 yamt if (type != RFCOMM_FRAME_UIH)
625 1.1.2.2 yamt fcs = FCS(fcs, b);
626 1.1.2.2 yamt len = (b >> 1) & 0x7f;
627 1.1.2.2 yamt
628 1.1.2.2 yamt if (RFCOMM_EA(b) == 0) {
629 1.1.2.2 yamt if (m->m_pkthdr.len < 2) {
630 1.1.2.2 yamt DPRINTF("short frame (%d, EA = 0), discarded\n",
631 1.1.2.2 yamt m->m_pkthdr.len);
632 1.1.2.2 yamt goto done;
633 1.1.2.2 yamt }
634 1.1.2.2 yamt
635 1.1.2.2 yamt m_copydata(m, 0, 1, &b);
636 1.1.2.2 yamt m_adj(m, 1);
637 1.1.2.2 yamt if (type != RFCOMM_FRAME_UIH)
638 1.1.2.2 yamt fcs = FCS(fcs, b);
639 1.1.2.2 yamt
640 1.1.2.2 yamt len |= (b << 7);
641 1.1.2.2 yamt }
642 1.1.2.2 yamt
643 1.1.2.2 yamt /* FCS byte is last octet in frame */
644 1.1.2.2 yamt m_copydata(m, m->m_pkthdr.len - 1, 1, &b);
645 1.1.2.2 yamt m_adj(m, -1);
646 1.1.2.2 yamt fcs = FCS(fcs, b);
647 1.1.2.2 yamt
648 1.1.2.2 yamt if (fcs != 0xcf) {
649 1.1.2.2 yamt DPRINTF("Bad FCS value (%#2.2x), frame discarded\n", fcs);
650 1.1.2.2 yamt goto done;
651 1.1.2.2 yamt }
652 1.1.2.2 yamt
653 1.1.2.2 yamt DPRINTFN(10, "dlci %d, type %2.2x, len = %d\n", dlci, type, len);
654 1.1.2.2 yamt
655 1.1.2.2 yamt switch (type) {
656 1.1.2.2 yamt case RFCOMM_FRAME_SABM:
657 1.1.2.2 yamt if (pf)
658 1.1.2.2 yamt rfcomm_session_recv_sabm(rs, dlci);
659 1.1.2.2 yamt break;
660 1.1.2.2 yamt
661 1.1.2.2 yamt case RFCOMM_FRAME_DISC:
662 1.1.2.2 yamt if (pf)
663 1.1.2.2 yamt rfcomm_session_recv_disc(rs, dlci);
664 1.1.2.2 yamt break;
665 1.1.2.2 yamt
666 1.1.2.2 yamt case RFCOMM_FRAME_UA:
667 1.1.2.2 yamt if (pf)
668 1.1.2.2 yamt rfcomm_session_recv_ua(rs, dlci);
669 1.1.2.2 yamt break;
670 1.1.2.2 yamt
671 1.1.2.2 yamt case RFCOMM_FRAME_DM:
672 1.1.2.2 yamt rfcomm_session_recv_dm(rs, dlci);
673 1.1.2.2 yamt break;
674 1.1.2.2 yamt
675 1.1.2.2 yamt case RFCOMM_FRAME_UIH:
676 1.1.2.2 yamt rfcomm_session_recv_uih(rs, dlci, pf, m, len);
677 1.1.2.2 yamt return; /* (no release) */
678 1.1.2.2 yamt
679 1.1.2.2 yamt default:
680 1.1.2.2 yamt UNKNOWN(type);
681 1.1.2.2 yamt break;
682 1.1.2.2 yamt }
683 1.1.2.2 yamt
684 1.1.2.2 yamt done:
685 1.1.2.2 yamt m_freem(m);
686 1.1.2.2 yamt }
687 1.1.2.2 yamt
688 1.1.2.2 yamt /***********************************************************************
689 1.1.2.2 yamt *
690 1.1.2.2 yamt * RFCOMM Session receive processing
691 1.1.2.2 yamt */
692 1.1.2.2 yamt
693 1.1.2.2 yamt /*
694 1.1.2.2 yamt * rfcomm_session_recv_sabm(rfcomm_session, dlci)
695 1.1.2.2 yamt *
696 1.1.2.2 yamt * Set Asyncrhonous Balanced Mode - open the channel.
697 1.1.2.2 yamt */
698 1.1.2.2 yamt static void
699 1.1.2.2 yamt rfcomm_session_recv_sabm(struct rfcomm_session *rs, int dlci)
700 1.1.2.2 yamt {
701 1.1.2.2 yamt struct rfcomm_dlc *dlc;
702 1.1.2.2 yamt int err;
703 1.1.2.2 yamt
704 1.1.2.2 yamt DPRINTFN(5, "SABM(%d)\n", dlci);
705 1.1.2.2 yamt
706 1.1.2.2 yamt if (dlci == 0) { /* Open Session */
707 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_OPEN;
708 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
709 1.1.2.2 yamt LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
710 1.1.2.2 yamt if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
711 1.1.2.2 yamt rfcomm_dlc_connect(dlc);
712 1.1.2.2 yamt }
713 1.1.2.2 yamt return;
714 1.1.2.2 yamt }
715 1.1.2.2 yamt
716 1.1.2.2 yamt if (rs->rs_state != RFCOMM_SESSION_OPEN) {
717 1.1.2.2 yamt DPRINTF("session was not even open!\n");
718 1.1.2.2 yamt return;
719 1.1.2.2 yamt }
720 1.1.2.2 yamt
721 1.1.2.2 yamt /* validate direction bit */
722 1.1.2.2 yamt if ((IS_INITIATOR(rs) && !RFCOMM_DIRECTION(dlci))
723 1.1.2.2 yamt || (!IS_INITIATOR(rs) && RFCOMM_DIRECTION(dlci))) {
724 1.1.2.2 yamt DPRINTF("Invalid direction bit on DLCI\n");
725 1.1.2.2 yamt return;
726 1.1.2.2 yamt }
727 1.1.2.2 yamt
728 1.1.2.2 yamt /*
729 1.1.2.2 yamt * look for our DLC - this may exist if we received PN
730 1.1.2.2 yamt * already, or we may have to fabricate a new one.
731 1.1.2.2 yamt */
732 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, dlci);
733 1.1.2.2 yamt if (dlc == NULL) {
734 1.1.2.2 yamt dlc = rfcomm_dlc_newconn(rs, dlci);
735 1.1.2.2 yamt if (dlc == NULL)
736 1.1.2.2 yamt return; /* (DM is sent) */
737 1.1.2.2 yamt }
738 1.1.2.2 yamt
739 1.1.2.2 yamt /*
740 1.1.2.4 yamt * ..but if this DLC is not waiting to connect, they did
741 1.1.2.4 yamt * something wrong, ignore it.
742 1.1.2.2 yamt */
743 1.1.2.2 yamt if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
744 1.1.2.2 yamt return;
745 1.1.2.2 yamt
746 1.1.2.4 yamt /* set link mode */
747 1.1.2.4 yamt err = rfcomm_dlc_setmode(dlc);
748 1.1.2.4 yamt if (err == EINPROGRESS) {
749 1.1.2.4 yamt dlc->rd_state = RFCOMM_DLC_WAIT_SEND_UA;
750 1.1.2.4 yamt (*dlc->rd_proto->connecting)(dlc->rd_upper);
751 1.1.2.4 yamt return;
752 1.1.2.4 yamt }
753 1.1.2.4 yamt if (err)
754 1.1.2.4 yamt goto close;
755 1.1.2.2 yamt
756 1.1.2.4 yamt err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
757 1.1.2.4 yamt if (err)
758 1.1.2.4 yamt goto close;
759 1.1.2.4 yamt
760 1.1.2.4 yamt /* and mark it open */
761 1.1.2.4 yamt err = rfcomm_dlc_open(dlc);
762 1.1.2.4 yamt if (err)
763 1.1.2.4 yamt goto close;
764 1.1.2.4 yamt
765 1.1.2.4 yamt return;
766 1.1.2.4 yamt
767 1.1.2.4 yamt close:
768 1.1.2.4 yamt rfcomm_dlc_close(dlc, err);
769 1.1.2.2 yamt }
770 1.1.2.2 yamt
771 1.1.2.2 yamt /*
772 1.1.2.2 yamt * Receive Disconnect Command
773 1.1.2.2 yamt */
774 1.1.2.2 yamt static void
775 1.1.2.2 yamt rfcomm_session_recv_disc(struct rfcomm_session *rs, int dlci)
776 1.1.2.2 yamt {
777 1.1.2.2 yamt struct rfcomm_dlc *dlc;
778 1.1.2.2 yamt
779 1.1.2.2 yamt DPRINTFN(5, "DISC(%d)\n", dlci);
780 1.1.2.2 yamt
781 1.1.2.2 yamt if (dlci == 0) {
782 1.1.2.2 yamt /*
783 1.1.2.2 yamt * Disconnect Session
784 1.1.2.2 yamt *
785 1.1.2.2 yamt * We set the session state to CLOSED so that when
786 1.1.2.2 yamt * the UA frame is clear the session will be closed
787 1.1.2.2 yamt * automatically. We wont bother to close any DLC's
788 1.1.2.2 yamt * just yet as there should be none. In the unlikely
789 1.1.2.2 yamt * event that something is left, it will get flushed
790 1.1.2.2 yamt * out as the session goes down.
791 1.1.2.2 yamt */
792 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
793 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_CLOSED;
794 1.1.2.2 yamt return;
795 1.1.2.2 yamt }
796 1.1.2.2 yamt
797 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, dlci);
798 1.1.2.2 yamt if (dlc == NULL) {
799 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
800 1.1.2.2 yamt return;
801 1.1.2.2 yamt }
802 1.1.2.2 yamt
803 1.1.2.2 yamt rfcomm_dlc_close(dlc, ECONNRESET);
804 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
805 1.1.2.2 yamt }
806 1.1.2.2 yamt
807 1.1.2.2 yamt /*
808 1.1.2.2 yamt * Receive Unnumbered Acknowledgement Response
809 1.1.2.2 yamt *
810 1.1.2.2 yamt * This should be a response to a DISC or SABM frame that we
811 1.1.2.2 yamt * have previously sent. If unexpected, ignore it.
812 1.1.2.2 yamt */
813 1.1.2.2 yamt static void
814 1.1.2.2 yamt rfcomm_session_recv_ua(struct rfcomm_session *rs, int dlci)
815 1.1.2.2 yamt {
816 1.1.2.2 yamt struct rfcomm_dlc *dlc;
817 1.1.2.2 yamt
818 1.1.2.2 yamt DPRINTFN(5, "UA(%d)\n", dlci);
819 1.1.2.2 yamt
820 1.1.2.2 yamt if (dlci == 0) {
821 1.1.2.2 yamt switch (rs->rs_state) {
822 1.1.2.2 yamt case RFCOMM_SESSION_WAIT_CONNECT: /* We sent SABM */
823 1.1.2.2 yamt callout_stop(&rs->rs_timeout);
824 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_OPEN;
825 1.1.2.2 yamt LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
826 1.1.2.2 yamt if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
827 1.1.2.2 yamt rfcomm_dlc_connect(dlc);
828 1.1.2.2 yamt }
829 1.1.2.2 yamt break;
830 1.1.2.2 yamt
831 1.1.2.2 yamt case RFCOMM_SESSION_WAIT_DISCONNECT: /* We sent DISC */
832 1.1.2.2 yamt callout_stop(&rs->rs_timeout);
833 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_CLOSED;
834 1.1.2.2 yamt l2cap_disconnect(rs->rs_l2cap, 0);
835 1.1.2.2 yamt break;
836 1.1.2.2 yamt
837 1.1.2.2 yamt default:
838 1.1.2.2 yamt DPRINTF("Received spurious UA(0)!\n");
839 1.1.2.2 yamt break;
840 1.1.2.2 yamt }
841 1.1.2.2 yamt
842 1.1.2.2 yamt return;
843 1.1.2.2 yamt }
844 1.1.2.2 yamt
845 1.1.2.2 yamt /*
846 1.1.2.2 yamt * If we have no DLC on this dlci, we may have aborted
847 1.1.2.2 yamt * without shutting down properly, so check if the session
848 1.1.2.2 yamt * needs disconnecting.
849 1.1.2.2 yamt */
850 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, dlci);
851 1.1.2.2 yamt if (dlc == NULL)
852 1.1.2.2 yamt goto check;
853 1.1.2.2 yamt
854 1.1.2.2 yamt switch (dlc->rd_state) {
855 1.1.2.4 yamt case RFCOMM_DLC_WAIT_RECV_UA: /* We sent SABM */
856 1.1.2.4 yamt rfcomm_dlc_open(dlc);
857 1.1.2.2 yamt return;
858 1.1.2.2 yamt
859 1.1.2.2 yamt case RFCOMM_DLC_WAIT_DISCONNECT: /* We sent DISC */
860 1.1.2.2 yamt rfcomm_dlc_close(dlc, 0);
861 1.1.2.2 yamt break;
862 1.1.2.2 yamt
863 1.1.2.2 yamt default:
864 1.1.2.2 yamt DPRINTF("Received spurious UA(%d)!\n", dlci);
865 1.1.2.2 yamt return;
866 1.1.2.2 yamt }
867 1.1.2.2 yamt
868 1.1.2.2 yamt check: /* last one out turns out the light */
869 1.1.2.2 yamt if (LIST_EMPTY(&rs->rs_dlcs)) {
870 1.1.2.2 yamt rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
871 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
872 1.1.2.2 yamt callout_schedule(&rs->rs_timeout, rfcomm_ack_timeout * hz);
873 1.1.2.2 yamt }
874 1.1.2.2 yamt }
875 1.1.2.2 yamt
876 1.1.2.2 yamt /*
877 1.1.2.2 yamt * Receive Disconnected Mode Response
878 1.1.2.2 yamt *
879 1.1.2.2 yamt * If this does not apply to a known DLC then we may ignore it.
880 1.1.2.2 yamt */
881 1.1.2.2 yamt static void
882 1.1.2.2 yamt rfcomm_session_recv_dm(struct rfcomm_session *rs, int dlci)
883 1.1.2.2 yamt {
884 1.1.2.2 yamt struct rfcomm_dlc *dlc;
885 1.1.2.2 yamt
886 1.1.2.2 yamt DPRINTFN(5, "DM(%d)\n", dlci);
887 1.1.2.2 yamt
888 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, dlci);
889 1.1.2.2 yamt if (dlc == NULL)
890 1.1.2.2 yamt return;
891 1.1.2.2 yamt
892 1.1.2.2 yamt if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT)
893 1.1.2.2 yamt rfcomm_dlc_close(dlc, ECONNREFUSED);
894 1.1.2.2 yamt else
895 1.1.2.2 yamt rfcomm_dlc_close(dlc, ECONNRESET);
896 1.1.2.2 yamt }
897 1.1.2.2 yamt
898 1.1.2.2 yamt /*
899 1.1.2.2 yamt * Receive Unnumbered Information with Header check (MCC or data packet)
900 1.1.2.2 yamt */
901 1.1.2.2 yamt static void
902 1.1.2.2 yamt rfcomm_session_recv_uih(struct rfcomm_session *rs, int dlci,
903 1.1.2.2 yamt int pf, struct mbuf *m, int len)
904 1.1.2.2 yamt {
905 1.1.2.2 yamt struct rfcomm_dlc *dlc;
906 1.1.2.2 yamt uint8_t credits = 0;
907 1.1.2.2 yamt
908 1.1.2.2 yamt DPRINTFN(10, "UIH(%d)\n", dlci);
909 1.1.2.2 yamt
910 1.1.2.2 yamt if (dlci == 0) {
911 1.1.2.2 yamt rfcomm_session_recv_mcc(rs, m);
912 1.1.2.2 yamt return;
913 1.1.2.2 yamt }
914 1.1.2.2 yamt
915 1.1.2.2 yamt if (m->m_pkthdr.len != len + pf) {
916 1.1.2.2 yamt DPRINTF("Bad Frame Length (%d), frame discarded\n",
917 1.1.2.2 yamt m->m_pkthdr.len);
918 1.1.2.2 yamt
919 1.1.2.2 yamt goto discard;
920 1.1.2.2 yamt }
921 1.1.2.2 yamt
922 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, dlci);
923 1.1.2.2 yamt if (dlc == NULL) {
924 1.1.2.2 yamt DPRINTF("UIH received for non existent DLC, discarded\n");
925 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
926 1.1.2.2 yamt goto discard;
927 1.1.2.2 yamt }
928 1.1.2.2 yamt
929 1.1.2.2 yamt if (dlc->rd_state != RFCOMM_DLC_OPEN) {
930 1.1.2.2 yamt DPRINTF("non-open DLC (state = %d), discarded\n",
931 1.1.2.2 yamt dlc->rd_state);
932 1.1.2.2 yamt goto discard;
933 1.1.2.2 yamt }
934 1.1.2.2 yamt
935 1.1.2.2 yamt /* if PF is set, credits were included */
936 1.1.2.2 yamt if (rs->rs_flags & RFCOMM_SESSION_CFC) {
937 1.1.2.2 yamt if (pf != 0) {
938 1.1.2.2 yamt if (m->m_pkthdr.len < sizeof(credits)) {
939 1.1.2.2 yamt DPRINTF("Bad PF value, UIH discarded\n");
940 1.1.2.2 yamt goto discard;
941 1.1.2.2 yamt }
942 1.1.2.2 yamt
943 1.1.2.2 yamt m_copydata(m, 0, sizeof(credits), &credits);
944 1.1.2.2 yamt m_adj(m, sizeof(credits));
945 1.1.2.2 yamt
946 1.1.2.2 yamt dlc->rd_txcred += credits;
947 1.1.2.2 yamt
948 1.1.2.2 yamt if (credits > 0 && dlc->rd_txbuf != NULL)
949 1.1.2.2 yamt rfcomm_dlc_start(dlc);
950 1.1.2.2 yamt }
951 1.1.2.2 yamt
952 1.1.2.2 yamt if (len == 0)
953 1.1.2.2 yamt goto discard;
954 1.1.2.2 yamt
955 1.1.2.2 yamt if (dlc->rd_rxcred == 0) {
956 1.1.2.2 yamt DPRINTF("Credit limit reached, UIH discarded\n");
957 1.1.2.2 yamt goto discard;
958 1.1.2.2 yamt }
959 1.1.2.2 yamt
960 1.1.2.2 yamt if (len > dlc->rd_rxsize) {
961 1.1.2.2 yamt DPRINTF("UIH frame exceeds rxsize, discarded\n");
962 1.1.2.2 yamt goto discard;
963 1.1.2.2 yamt }
964 1.1.2.2 yamt
965 1.1.2.2 yamt dlc->rd_rxcred--;
966 1.1.2.2 yamt dlc->rd_rxsize -= len;
967 1.1.2.2 yamt }
968 1.1.2.2 yamt
969 1.1.2.2 yamt (*dlc->rd_proto->input)(dlc->rd_upper, m);
970 1.1.2.2 yamt return;
971 1.1.2.2 yamt
972 1.1.2.2 yamt discard:
973 1.1.2.2 yamt m_freem(m);
974 1.1.2.2 yamt }
975 1.1.2.2 yamt
976 1.1.2.2 yamt /*
977 1.1.2.2 yamt * Receive Multiplexer Control Command
978 1.1.2.2 yamt */
979 1.1.2.2 yamt static void
980 1.1.2.2 yamt rfcomm_session_recv_mcc(struct rfcomm_session *rs, struct mbuf *m)
981 1.1.2.2 yamt {
982 1.1.2.2 yamt int type, cr, len;
983 1.1.2.2 yamt uint8_t b;
984 1.1.2.2 yamt
985 1.1.2.2 yamt /*
986 1.1.2.2 yamt * Extract MCC header.
987 1.1.2.2 yamt *
988 1.1.2.2 yamt * Fields are variable length using extension bit = 1 to signify the
989 1.1.2.2 yamt * last octet in the sequence.
990 1.1.2.2 yamt *
991 1.1.2.2 yamt * Only single octet types are defined in TS 07.10/RFCOMM spec
992 1.1.2.2 yamt *
993 1.1.2.2 yamt * Length can realistically only use 15 bits (max RFCOMM MTU)
994 1.1.2.2 yamt */
995 1.1.2.2 yamt if (m->m_pkthdr.len < sizeof(b)) {
996 1.1.2.2 yamt DPRINTF("Short MCC header, discarded\n");
997 1.1.2.2 yamt goto release;
998 1.1.2.2 yamt }
999 1.1.2.2 yamt
1000 1.1.2.2 yamt m_copydata(m, 0, sizeof(b), &b);
1001 1.1.2.2 yamt m_adj(m, sizeof(b));
1002 1.1.2.2 yamt
1003 1.1.2.2 yamt if (RFCOMM_EA(b) == 0) { /* verify no extensions */
1004 1.1.2.4 yamt DPRINTF("MCC type EA = 0, discarded\n");
1005 1.1.2.2 yamt goto release;
1006 1.1.2.2 yamt }
1007 1.1.2.2 yamt
1008 1.1.2.2 yamt type = RFCOMM_MCC_TYPE(b);
1009 1.1.2.2 yamt cr = RFCOMM_CR(b);
1010 1.1.2.2 yamt
1011 1.1.2.2 yamt len = 0;
1012 1.1.2.2 yamt do {
1013 1.1.2.2 yamt if (m->m_pkthdr.len < sizeof(b)) {
1014 1.1.2.2 yamt DPRINTF("Short MCC header, discarded\n");
1015 1.1.2.2 yamt goto release;
1016 1.1.2.2 yamt }
1017 1.1.2.2 yamt
1018 1.1.2.2 yamt m_copydata(m, 0, sizeof(b), &b);
1019 1.1.2.2 yamt m_adj(m, sizeof(b));
1020 1.1.2.2 yamt
1021 1.1.2.2 yamt len = (len << 7) | (b >> 1);
1022 1.1.2.2 yamt len = min(len, RFCOMM_MTU_MAX);
1023 1.1.2.2 yamt } while (RFCOMM_EA(b) == 0);
1024 1.1.2.2 yamt
1025 1.1.2.2 yamt if (len != m->m_pkthdr.len) {
1026 1.1.2.2 yamt DPRINTF("Incorrect MCC length, discarded\n");
1027 1.1.2.2 yamt goto release;
1028 1.1.2.2 yamt }
1029 1.1.2.2 yamt
1030 1.1.2.2 yamt DPRINTFN(2, "MCC %s type %2.2x (%d bytes)\n",
1031 1.1.2.2 yamt (cr ? "command" : "response"), type, len);
1032 1.1.2.2 yamt
1033 1.1.2.2 yamt /*
1034 1.1.2.2 yamt * pass to command handler
1035 1.1.2.2 yamt */
1036 1.1.2.2 yamt switch(type) {
1037 1.1.2.2 yamt case RFCOMM_MCC_TEST: /* Test */
1038 1.1.2.2 yamt rfcomm_session_recv_mcc_test(rs, cr, m);
1039 1.1.2.2 yamt break;
1040 1.1.2.2 yamt
1041 1.1.2.2 yamt case RFCOMM_MCC_FCON: /* Flow Control On */
1042 1.1.2.2 yamt rfcomm_session_recv_mcc_fcon(rs, cr);
1043 1.1.2.2 yamt break;
1044 1.1.2.2 yamt
1045 1.1.2.2 yamt case RFCOMM_MCC_FCOFF: /* Flow Control Off */
1046 1.1.2.2 yamt rfcomm_session_recv_mcc_fcoff(rs, cr);
1047 1.1.2.2 yamt break;
1048 1.1.2.2 yamt
1049 1.1.2.2 yamt case RFCOMM_MCC_MSC: /* Modem Status Command */
1050 1.1.2.2 yamt rfcomm_session_recv_mcc_msc(rs, cr, m);
1051 1.1.2.2 yamt break;
1052 1.1.2.2 yamt
1053 1.1.2.2 yamt case RFCOMM_MCC_RPN: /* Remote Port Negotiation */
1054 1.1.2.2 yamt rfcomm_session_recv_mcc_rpn(rs, cr, m);
1055 1.1.2.2 yamt break;
1056 1.1.2.2 yamt
1057 1.1.2.2 yamt case RFCOMM_MCC_RLS: /* Remote Line Status */
1058 1.1.2.2 yamt rfcomm_session_recv_mcc_rls(rs, cr, m);
1059 1.1.2.2 yamt break;
1060 1.1.2.2 yamt
1061 1.1.2.2 yamt case RFCOMM_MCC_PN: /* Parameter Negotiation */
1062 1.1.2.2 yamt rfcomm_session_recv_mcc_pn(rs, cr, m);
1063 1.1.2.2 yamt break;
1064 1.1.2.2 yamt
1065 1.1.2.2 yamt case RFCOMM_MCC_NSC: /* Non Supported Command */
1066 1.1.2.2 yamt rfcomm_session_recv_mcc_nsc(rs, cr, m);
1067 1.1.2.2 yamt break;
1068 1.1.2.2 yamt
1069 1.1.2.2 yamt default:
1070 1.1.2.2 yamt b = RFCOMM_MKMCC_TYPE(cr, type);
1071 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_NSC, &b, sizeof(b));
1072 1.1.2.2 yamt }
1073 1.1.2.2 yamt
1074 1.1.2.2 yamt release:
1075 1.1.2.2 yamt m_freem(m);
1076 1.1.2.2 yamt }
1077 1.1.2.2 yamt
1078 1.1.2.2 yamt /*
1079 1.1.2.2 yamt * process TEST command/response
1080 1.1.2.2 yamt */
1081 1.1.2.2 yamt static void
1082 1.1.2.2 yamt rfcomm_session_recv_mcc_test(struct rfcomm_session *rs, int cr, struct mbuf *m)
1083 1.1.2.2 yamt {
1084 1.1.2.2 yamt void *data;
1085 1.1.2.2 yamt int len;
1086 1.1.2.2 yamt
1087 1.1.2.2 yamt if (cr == 0) /* ignore ack */
1088 1.1.2.2 yamt return;
1089 1.1.2.2 yamt
1090 1.1.2.2 yamt /*
1091 1.1.2.2 yamt * we must send all the data they included back as is
1092 1.1.2.2 yamt */
1093 1.1.2.2 yamt
1094 1.1.2.2 yamt len = m->m_pkthdr.len;
1095 1.1.2.2 yamt if (len > RFCOMM_MTU_MAX)
1096 1.1.2.2 yamt return;
1097 1.1.2.2 yamt
1098 1.1.2.2 yamt data = malloc(len, M_BLUETOOTH, M_NOWAIT);
1099 1.1.2.2 yamt if (data == NULL)
1100 1.1.2.2 yamt return;
1101 1.1.2.2 yamt
1102 1.1.2.2 yamt m_copydata(m, 0, len, data);
1103 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_TEST, data, len);
1104 1.1.2.2 yamt free(data, M_BLUETOOTH);
1105 1.1.2.2 yamt }
1106 1.1.2.2 yamt
1107 1.1.2.2 yamt /*
1108 1.1.2.2 yamt * process Flow Control ON command/response
1109 1.1.2.2 yamt */
1110 1.1.2.2 yamt static void
1111 1.1.2.2 yamt rfcomm_session_recv_mcc_fcon(struct rfcomm_session *rs, int cr)
1112 1.1.2.2 yamt {
1113 1.1.2.2 yamt
1114 1.1.2.2 yamt if (cr == 0) /* ignore ack */
1115 1.1.2.2 yamt return;
1116 1.1.2.2 yamt
1117 1.1.2.2 yamt rs->rs_flags |= RFCOMM_SESSION_RFC;
1118 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCON, NULL, 0);
1119 1.1.2.2 yamt }
1120 1.1.2.2 yamt
1121 1.1.2.2 yamt /*
1122 1.1.2.2 yamt * process Flow Control OFF command/response
1123 1.1.2.2 yamt */
1124 1.1.2.2 yamt static void
1125 1.1.2.2 yamt rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *rs, int cr)
1126 1.1.2.2 yamt {
1127 1.1.2.2 yamt
1128 1.1.2.2 yamt if (cr == 0) /* ignore ack */
1129 1.1.2.2 yamt return;
1130 1.1.2.2 yamt
1131 1.1.2.2 yamt rs->rs_flags &= ~RFCOMM_SESSION_RFC;
1132 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCOFF, NULL, 0);
1133 1.1.2.2 yamt }
1134 1.1.2.2 yamt
1135 1.1.2.2 yamt /*
1136 1.1.2.2 yamt * process Modem Status Command command/response
1137 1.1.2.2 yamt */
1138 1.1.2.2 yamt static void
1139 1.1.2.2 yamt rfcomm_session_recv_mcc_msc(struct rfcomm_session *rs, int cr, struct mbuf *m)
1140 1.1.2.2 yamt {
1141 1.1.2.2 yamt struct rfcomm_mcc_msc msc; /* (3 octets) */
1142 1.1.2.2 yamt struct rfcomm_dlc *dlc;
1143 1.1.2.2 yamt int len = 0;
1144 1.1.2.2 yamt
1145 1.1.2.2 yamt /* [ADDRESS] */
1146 1.1.2.2 yamt if (m->m_pkthdr.len < sizeof(msc.address))
1147 1.1.2.2 yamt return;
1148 1.1.2.2 yamt
1149 1.1.2.2 yamt m_copydata(m, 0, sizeof(msc.address), &msc.address);
1150 1.1.2.2 yamt m_adj(m, sizeof(msc.address));
1151 1.1.2.2 yamt len += sizeof(msc.address);
1152 1.1.2.2 yamt
1153 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, RFCOMM_DLCI(msc.address));
1154 1.1.2.2 yamt
1155 1.1.2.2 yamt if (cr == 0) { /* ignore acks */
1156 1.1.2.2 yamt if (dlc != NULL)
1157 1.1.2.2 yamt callout_stop(&dlc->rd_timeout);
1158 1.1.2.2 yamt
1159 1.1.2.2 yamt return;
1160 1.1.2.2 yamt }
1161 1.1.2.2 yamt
1162 1.1.2.2 yamt if (dlc == NULL) {
1163 1.1.2.2 yamt rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM,
1164 1.1.2.2 yamt RFCOMM_DLCI(msc.address));
1165 1.1.2.2 yamt return;
1166 1.1.2.2 yamt }
1167 1.1.2.2 yamt
1168 1.1.2.2 yamt /* [SIGNALS] */
1169 1.1.2.2 yamt if (m->m_pkthdr.len < sizeof(msc.modem))
1170 1.1.2.2 yamt return;
1171 1.1.2.2 yamt
1172 1.1.2.2 yamt m_copydata(m, 0, sizeof(msc.modem), &msc.modem);
1173 1.1.2.2 yamt m_adj(m, sizeof(msc.modem));
1174 1.1.2.2 yamt len += sizeof(msc.modem);
1175 1.1.2.2 yamt
1176 1.1.2.2 yamt dlc->rd_rmodem = msc.modem;
1177 1.1.2.4 yamt /* XXX how do we signal this upstream? */
1178 1.1.2.2 yamt
1179 1.1.2.2 yamt if (RFCOMM_EA(msc.modem) == 0) {
1180 1.1.2.2 yamt if (m->m_pkthdr.len < sizeof(msc.brk))
1181 1.1.2.2 yamt return;
1182 1.1.2.2 yamt
1183 1.1.2.2 yamt m_copydata(m, 0, sizeof(msc.brk), &msc.brk);
1184 1.1.2.2 yamt m_adj(m, sizeof(msc.brk));
1185 1.1.2.2 yamt len += sizeof(msc.brk);
1186 1.1.2.2 yamt
1187 1.1.2.4 yamt /* XXX how do we signal this upstream? */
1188 1.1.2.2 yamt }
1189 1.1.2.2 yamt
1190 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_MSC, &msc, len);
1191 1.1.2.2 yamt }
1192 1.1.2.2 yamt
1193 1.1.2.2 yamt /*
1194 1.1.2.2 yamt * process Remote Port Negotiation command/response
1195 1.1.2.2 yamt */
1196 1.1.2.2 yamt static void
1197 1.1.2.2 yamt rfcomm_session_recv_mcc_rpn(struct rfcomm_session *rs, int cr, struct mbuf *m)
1198 1.1.2.2 yamt {
1199 1.1.2.2 yamt struct rfcomm_mcc_rpn rpn;
1200 1.1.2.2 yamt uint16_t mask;
1201 1.1.2.2 yamt
1202 1.1.2.2 yamt if (cr == 0) /* ignore ack */
1203 1.1.2.2 yamt return;
1204 1.1.2.2 yamt
1205 1.1.2.2 yamt /* default values */
1206 1.1.2.2 yamt rpn.bit_rate = RFCOMM_RPN_BR_9600;
1207 1.1.2.2 yamt rpn.line_settings = RFCOMM_RPN_8_N_1;
1208 1.1.2.2 yamt rpn.flow_control = RFCOMM_RPN_FLOW_NONE;
1209 1.1.2.2 yamt rpn.xon_char = RFCOMM_RPN_XON_CHAR;
1210 1.1.2.2 yamt rpn.xoff_char = RFCOMM_RPN_XOFF_CHAR;
1211 1.1.2.2 yamt
1212 1.1.2.2 yamt if (m->m_pkthdr.len == sizeof(rpn)) {
1213 1.1.2.2 yamt m_copydata(m, 0, sizeof(rpn), &rpn);
1214 1.1.2.2 yamt rpn.param_mask = RFCOMM_RPN_PM_ALL;
1215 1.1.2.2 yamt } else if (m->m_pkthdr.len == 1) {
1216 1.1.2.2 yamt m_copydata(m, 0, 1, &rpn);
1217 1.1.2.2 yamt rpn.param_mask = le16toh(rpn.param_mask);
1218 1.1.2.2 yamt } else {
1219 1.1.2.2 yamt DPRINTF("Bad RPN length (%d)\n", m->m_pkthdr.len);
1220 1.1.2.2 yamt return;
1221 1.1.2.2 yamt }
1222 1.1.2.2 yamt
1223 1.1.2.2 yamt mask = 0;
1224 1.1.2.2 yamt
1225 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_RATE)
1226 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_RATE;
1227 1.1.2.2 yamt
1228 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_DATA
1229 1.1.2.2 yamt && RFCOMM_RPN_DATA_BITS(rpn.line_settings) == RFCOMM_RPN_DATA_8)
1230 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_DATA;
1231 1.1.2.2 yamt
1232 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_STOP
1233 1.1.2.2 yamt && RFCOMM_RPN_STOP_BITS(rpn.line_settings) == RFCOMM_RPN_STOP_1)
1234 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_STOP;
1235 1.1.2.2 yamt
1236 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_PARITY
1237 1.1.2.2 yamt && RFCOMM_RPN_PARITY(rpn.line_settings) == RFCOMM_RPN_PARITY_NONE)
1238 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_PARITY;
1239 1.1.2.2 yamt
1240 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_XON
1241 1.1.2.2 yamt && rpn.xon_char == RFCOMM_RPN_XON_CHAR)
1242 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_XON;
1243 1.1.2.2 yamt
1244 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_XOFF
1245 1.1.2.2 yamt && rpn.xoff_char == RFCOMM_RPN_XOFF_CHAR)
1246 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_XOFF;
1247 1.1.2.2 yamt
1248 1.1.2.2 yamt if (rpn.param_mask & RFCOMM_RPN_PM_FLOW
1249 1.1.2.2 yamt && rpn.flow_control == RFCOMM_RPN_FLOW_NONE)
1250 1.1.2.2 yamt mask |= RFCOMM_RPN_PM_FLOW;
1251 1.1.2.2 yamt
1252 1.1.2.2 yamt rpn.param_mask = htole16(mask);
1253 1.1.2.2 yamt
1254 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RPN, &rpn, sizeof(rpn));
1255 1.1.2.2 yamt }
1256 1.1.2.2 yamt
1257 1.1.2.2 yamt /*
1258 1.1.2.2 yamt * process Remote Line Status command/response
1259 1.1.2.2 yamt */
1260 1.1.2.2 yamt static void
1261 1.1.2.2 yamt rfcomm_session_recv_mcc_rls(struct rfcomm_session *rs, int cr, struct mbuf *m)
1262 1.1.2.2 yamt {
1263 1.1.2.2 yamt struct rfcomm_mcc_rls rls;
1264 1.1.2.2 yamt
1265 1.1.2.2 yamt if (cr == 0) /* ignore ack */
1266 1.1.2.2 yamt return;
1267 1.1.2.2 yamt
1268 1.1.2.2 yamt if (m->m_pkthdr.len != sizeof(rls)) {
1269 1.1.2.2 yamt DPRINTF("Bad RLS length %d\n", m->m_pkthdr.len);
1270 1.1.2.2 yamt return;
1271 1.1.2.2 yamt }
1272 1.1.2.2 yamt
1273 1.1.2.2 yamt m_copydata(m, 0, sizeof(rls), &rls);
1274 1.1.2.2 yamt
1275 1.1.2.2 yamt /*
1276 1.1.2.2 yamt * So far as I can tell, we just send back what
1277 1.1.2.2 yamt * they sent us. This signifies errors that seem
1278 1.1.2.2 yamt * irrelevent for RFCOMM over L2CAP.
1279 1.1.2.2 yamt */
1280 1.1.2.2 yamt rls.address |= 0x03; /* EA = 1, CR = 1 */
1281 1.1.2.2 yamt rls.status &= 0x0f; /* only 4 bits valid */
1282 1.1.2.2 yamt
1283 1.1.2.2 yamt rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RLS, &rls, sizeof(rls));
1284 1.1.2.2 yamt }
1285 1.1.2.2 yamt
1286 1.1.2.2 yamt /*
1287 1.1.2.2 yamt * process Parameter Negotiation command/response
1288 1.1.2.2 yamt */
1289 1.1.2.2 yamt static void
1290 1.1.2.2 yamt rfcomm_session_recv_mcc_pn(struct rfcomm_session *rs, int cr, struct mbuf *m)
1291 1.1.2.2 yamt {
1292 1.1.2.2 yamt struct rfcomm_dlc *dlc;
1293 1.1.2.2 yamt struct rfcomm_mcc_pn pn;
1294 1.1.2.2 yamt int err;
1295 1.1.2.2 yamt
1296 1.1.2.2 yamt if (m->m_pkthdr.len != sizeof(pn)) {
1297 1.1.2.2 yamt DPRINTF("Bad PN length %d\n", m->m_pkthdr.len);
1298 1.1.2.2 yamt return;
1299 1.1.2.2 yamt }
1300 1.1.2.2 yamt
1301 1.1.2.2 yamt m_copydata(m, 0, sizeof(pn), &pn);
1302 1.1.2.2 yamt
1303 1.1.2.2 yamt pn.dlci &= 0x3f;
1304 1.1.2.2 yamt pn.mtu = le16toh(pn.mtu);
1305 1.1.2.2 yamt
1306 1.1.2.2 yamt dlc = rfcomm_dlc_lookup(rs, pn.dlci);
1307 1.1.2.2 yamt if (cr) { /* Command */
1308 1.1.2.2 yamt /*
1309 1.1.2.2 yamt * If there is no DLC present, this is a new
1310 1.1.2.2 yamt * connection so attempt to make one
1311 1.1.2.2 yamt */
1312 1.1.2.2 yamt if (dlc == NULL) {
1313 1.1.2.2 yamt dlc = rfcomm_dlc_newconn(rs, pn.dlci);
1314 1.1.2.2 yamt if (dlc == NULL)
1315 1.1.2.2 yamt return; /* (DM is sent) */
1316 1.1.2.2 yamt }
1317 1.1.2.2 yamt
1318 1.1.2.2 yamt /* accept any valid MTU, and offer it back */
1319 1.1.2.2 yamt pn.mtu = min(pn.mtu, RFCOMM_MTU_MAX);
1320 1.1.2.2 yamt pn.mtu = min(pn.mtu, rs->rs_mtu);
1321 1.1.2.2 yamt pn.mtu = max(pn.mtu, RFCOMM_MTU_MIN);
1322 1.1.2.2 yamt dlc->rd_mtu = pn.mtu;
1323 1.1.2.2 yamt pn.mtu = htole16(pn.mtu);
1324 1.1.2.2 yamt
1325 1.1.2.2 yamt /* credits are only set before DLC is open */
1326 1.1.2.2 yamt if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT
1327 1.1.2.2 yamt && (pn.flow_control & 0xf0) == 0xf0) {
1328 1.1.2.2 yamt rs->rs_flags |= RFCOMM_SESSION_CFC;
1329 1.1.2.2 yamt dlc->rd_txcred = pn.credits & 0x07;
1330 1.1.2.2 yamt
1331 1.1.2.2 yamt dlc->rd_rxcred = (dlc->rd_rxsize / dlc->rd_mtu);
1332 1.1.2.2 yamt dlc->rd_rxcred = min(dlc->rd_rxcred,
1333 1.1.2.2 yamt RFCOMM_CREDITS_DEFAULT);
1334 1.1.2.2 yamt
1335 1.1.2.2 yamt pn.flow_control = 0xe0;
1336 1.1.2.2 yamt pn.credits = dlc->rd_rxcred;
1337 1.1.2.2 yamt } else {
1338 1.1.2.2 yamt pn.flow_control = 0x00;
1339 1.1.2.2 yamt pn.credits = 0x00;
1340 1.1.2.2 yamt }
1341 1.1.2.2 yamt
1342 1.1.2.2 yamt /* unused fields must be ignored and set to zero */
1343 1.1.2.2 yamt pn.ack_timer = 0;
1344 1.1.2.2 yamt pn.max_retrans = 0;
1345 1.1.2.2 yamt
1346 1.1.2.2 yamt /* send our response */
1347 1.1.2.2 yamt err = rfcomm_session_send_mcc(rs, 0,
1348 1.1.2.2 yamt RFCOMM_MCC_PN, &pn, sizeof(pn));
1349 1.1.2.2 yamt if (err)
1350 1.1.2.2 yamt goto close;
1351 1.1.2.2 yamt
1352 1.1.2.2 yamt } else { /* Response */
1353 1.1.2.2 yamt /* ignore responses with no matching DLC */
1354 1.1.2.2 yamt if (dlc == NULL)
1355 1.1.2.2 yamt return;
1356 1.1.2.2 yamt
1357 1.1.2.2 yamt callout_stop(&dlc->rd_timeout);
1358 1.1.2.2 yamt
1359 1.1.2.2 yamt if (pn.mtu > RFCOMM_MTU_MAX || pn.mtu > dlc->rd_mtu) {
1360 1.1.2.2 yamt dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
1361 1.1.2.2 yamt err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
1362 1.1.2.2 yamt pn.dlci);
1363 1.1.2.2 yamt if (err)
1364 1.1.2.2 yamt goto close;
1365 1.1.2.2 yamt
1366 1.1.2.2 yamt callout_schedule(&dlc->rd_timeout,
1367 1.1.2.2 yamt rfcomm_ack_timeout * hz);
1368 1.1.2.2 yamt return;
1369 1.1.2.2 yamt }
1370 1.1.2.2 yamt dlc->rd_mtu = pn.mtu;
1371 1.1.2.2 yamt
1372 1.1.2.4 yamt /* if DLC is not waiting to connect, we are done */
1373 1.1.2.4 yamt if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
1374 1.1.2.4 yamt return;
1375 1.1.2.4 yamt
1376 1.1.2.4 yamt /* set initial credits according to RFCOMM spec */
1377 1.1.2.4 yamt if ((pn.flow_control & 0xf0) == 0xe0) {
1378 1.1.2.2 yamt rs->rs_flags |= RFCOMM_SESSION_CFC;
1379 1.1.2.2 yamt dlc->rd_txcred = (pn.credits & 0x07);
1380 1.1.2.2 yamt }
1381 1.1.2.2 yamt
1382 1.1.2.4 yamt callout_schedule(&dlc->rd_timeout, rfcomm_ack_timeout * hz);
1383 1.1.2.4 yamt
1384 1.1.2.4 yamt /* set link mode */
1385 1.1.2.4 yamt err = rfcomm_dlc_setmode(dlc);
1386 1.1.2.4 yamt if (err == EINPROGRESS) {
1387 1.1.2.4 yamt dlc->rd_state = RFCOMM_DLC_WAIT_SEND_SABM;
1388 1.1.2.4 yamt (*dlc->rd_proto->connecting)(dlc->rd_upper);
1389 1.1.2.4 yamt return;
1390 1.1.2.4 yamt }
1391 1.1.2.4 yamt if (err)
1392 1.1.2.4 yamt goto close;
1393 1.1.2.4 yamt
1394 1.1.2.4 yamt /* we can proceed now */
1395 1.1.2.2 yamt err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, pn.dlci);
1396 1.1.2.2 yamt if (err)
1397 1.1.2.2 yamt goto close;
1398 1.1.2.2 yamt
1399 1.1.2.4 yamt dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
1400 1.1.2.2 yamt }
1401 1.1.2.2 yamt return;
1402 1.1.2.2 yamt
1403 1.1.2.2 yamt close:
1404 1.1.2.2 yamt rfcomm_dlc_close(dlc, err);
1405 1.1.2.2 yamt }
1406 1.1.2.2 yamt
1407 1.1.2.2 yamt /*
1408 1.1.2.2 yamt * process Non Supported Command command/response
1409 1.1.2.2 yamt */
1410 1.1.2.2 yamt static void
1411 1.1.2.3 yamt rfcomm_session_recv_mcc_nsc(struct rfcomm_session *rs,
1412 1.1.2.3 yamt int cr, struct mbuf *m)
1413 1.1.2.2 yamt {
1414 1.1.2.3 yamt struct rfcomm_dlc *dlc, *next;
1415 1.1.2.2 yamt
1416 1.1.2.2 yamt /*
1417 1.1.2.2 yamt * Since we did nothing that is not mandatory,
1418 1.1.2.2 yamt * we just abort the whole session..
1419 1.1.2.2 yamt */
1420 1.1.2.3 yamt
1421 1.1.2.3 yamt next = LIST_FIRST(&rs->rs_dlcs);
1422 1.1.2.3 yamt while ((dlc = next) != NULL) {
1423 1.1.2.3 yamt next = LIST_NEXT(dlc, rd_next);
1424 1.1.2.2 yamt rfcomm_dlc_close(dlc, ECONNABORTED);
1425 1.1.2.3 yamt }
1426 1.1.2.2 yamt
1427 1.1.2.2 yamt rfcomm_session_free(rs);
1428 1.1.2.2 yamt }
1429 1.1.2.2 yamt
1430 1.1.2.2 yamt /***********************************************************************
1431 1.1.2.2 yamt *
1432 1.1.2.2 yamt * RFCOMM Session outward frame/uih/mcc building
1433 1.1.2.2 yamt */
1434 1.1.2.2 yamt
1435 1.1.2.2 yamt /*
1436 1.1.2.2 yamt * SABM/DISC/DM/UA frames are all minimal and mostly identical.
1437 1.1.2.2 yamt */
1438 1.1.2.2 yamt int
1439 1.1.2.2 yamt rfcomm_session_send_frame(struct rfcomm_session *rs, int type, int dlci)
1440 1.1.2.2 yamt {
1441 1.1.2.2 yamt struct rfcomm_cmd_hdr *hdr;
1442 1.1.2.2 yamt struct rfcomm_credit *credit;
1443 1.1.2.2 yamt struct mbuf *m;
1444 1.1.2.2 yamt uint8_t fcs, cr;
1445 1.1.2.2 yamt
1446 1.1.2.2 yamt credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
1447 1.1.2.2 yamt if (credit == NULL)
1448 1.1.2.2 yamt return ENOMEM;
1449 1.1.2.2 yamt
1450 1.1.2.2 yamt m = m_gethdr(M_DONTWAIT, MT_DATA);
1451 1.1.2.2 yamt if (m == NULL) {
1452 1.1.2.2 yamt pool_put(&rfcomm_credit_pool, credit);
1453 1.1.2.2 yamt return ENOMEM;
1454 1.1.2.2 yamt }
1455 1.1.2.2 yamt
1456 1.1.2.2 yamt /*
1457 1.1.2.2 yamt * The CR (command/response) bit identifies the frame either as a
1458 1.1.2.2 yamt * commmand or a response and is used along with the DLCI to form
1459 1.1.2.2 yamt * the address. Commands contain the non-initiator address, whereas
1460 1.1.2.2 yamt * responses contain the initiator address, so the CR value is
1461 1.1.2.2 yamt * also dependent on the session direction.
1462 1.1.2.2 yamt */
1463 1.1.2.2 yamt if (type == RFCOMM_FRAME_UA || type == RFCOMM_FRAME_DM)
1464 1.1.2.2 yamt cr = IS_INITIATOR(rs) ? 0 : 1;
1465 1.1.2.2 yamt else
1466 1.1.2.2 yamt cr = IS_INITIATOR(rs) ? 1 : 0;
1467 1.1.2.2 yamt
1468 1.1.2.2 yamt hdr = mtod(m, struct rfcomm_cmd_hdr *);
1469 1.1.2.2 yamt hdr->address = RFCOMM_MKADDRESS(cr, dlci);
1470 1.1.2.2 yamt hdr->control = RFCOMM_MKCONTROL(type, 1); /* PF = 1 */
1471 1.1.2.2 yamt hdr->length = (0x00 << 1) | 0x01; /* len = 0x00, EA = 1 */
1472 1.1.2.2 yamt
1473 1.1.2.2 yamt fcs = 0xff;
1474 1.1.2.2 yamt fcs = FCS(fcs, hdr->address);
1475 1.1.2.2 yamt fcs = FCS(fcs, hdr->control);
1476 1.1.2.2 yamt fcs = FCS(fcs, hdr->length);
1477 1.1.2.2 yamt fcs = 0xff - fcs; /* ones complement */
1478 1.1.2.2 yamt hdr->fcs = fcs;
1479 1.1.2.2 yamt
1480 1.1.2.2 yamt m->m_pkthdr.len = m->m_len = sizeof(struct rfcomm_cmd_hdr);
1481 1.1.2.2 yamt
1482 1.1.2.2 yamt /* empty credit note */
1483 1.1.2.2 yamt credit->rc_dlc = NULL;
1484 1.1.2.2 yamt credit->rc_len = m->m_pkthdr.len;
1485 1.1.2.2 yamt SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
1486 1.1.2.2 yamt
1487 1.1.2.2 yamt DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n",
1488 1.1.2.2 yamt dlci, type, m->m_pkthdr.len, fcs);
1489 1.1.2.2 yamt
1490 1.1.2.2 yamt return l2cap_send(rs->rs_l2cap, m);
1491 1.1.2.2 yamt }
1492 1.1.2.2 yamt
1493 1.1.2.2 yamt /*
1494 1.1.2.2 yamt * rfcomm_session_send_uih(rfcomm_session, rfcomm_dlc, credits, mbuf)
1495 1.1.2.2 yamt *
1496 1.1.2.2 yamt * UIH frame is per DLC data or Multiplexer Control Commands
1497 1.1.2.2 yamt * when no DLC is given. Data mbuf is optional (just credits
1498 1.1.2.2 yamt * will be sent in that case)
1499 1.1.2.2 yamt */
1500 1.1.2.2 yamt int
1501 1.1.2.2 yamt rfcomm_session_send_uih(struct rfcomm_session *rs, struct rfcomm_dlc *dlc,
1502 1.1.2.2 yamt int credits, struct mbuf *m)
1503 1.1.2.2 yamt {
1504 1.1.2.2 yamt struct rfcomm_credit *credit;
1505 1.1.2.2 yamt struct mbuf *m0 = NULL;
1506 1.1.2.2 yamt int err, len;
1507 1.1.2.2 yamt uint8_t fcs, *hdr;
1508 1.1.2.2 yamt
1509 1.1.2.2 yamt KASSERT(rs != NULL);
1510 1.1.2.2 yamt
1511 1.1.2.2 yamt len = (m == NULL) ? 0 : m->m_pkthdr.len;
1512 1.1.2.2 yamt KASSERT(!(credits == 0 && len == 0));
1513 1.1.2.2 yamt
1514 1.1.2.2 yamt /*
1515 1.1.2.2 yamt * Make a credit note for the completion notification
1516 1.1.2.2 yamt */
1517 1.1.2.2 yamt credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
1518 1.1.2.2 yamt if (credit == NULL)
1519 1.1.2.2 yamt goto nomem;
1520 1.1.2.2 yamt
1521 1.1.2.2 yamt credit->rc_len = len;
1522 1.1.2.2 yamt credit->rc_dlc = dlc;
1523 1.1.2.2 yamt
1524 1.1.2.2 yamt /*
1525 1.1.2.2 yamt * Wrap UIH frame information around payload.
1526 1.1.2.2 yamt *
1527 1.1.2.2 yamt * [ADDRESS] [CONTROL] [LENGTH] [CREDITS] [...] [FCS]
1528 1.1.2.2 yamt *
1529 1.1.2.2 yamt * Address is one octet.
1530 1.1.2.2 yamt * Control is one octet.
1531 1.1.2.2 yamt * Length is one or two octets.
1532 1.1.2.2 yamt * Credits may be one octet.
1533 1.1.2.2 yamt *
1534 1.1.2.2 yamt * FCS is one octet and calculated on address and
1535 1.1.2.2 yamt * control octets only.
1536 1.1.2.2 yamt *
1537 1.1.2.2 yamt * If there are credits to be sent, we will set the PF
1538 1.1.2.2 yamt * flag and include them in the frame.
1539 1.1.2.2 yamt */
1540 1.1.2.2 yamt m0 = m_gethdr(M_DONTWAIT, MT_DATA);
1541 1.1.2.2 yamt if (m0 == NULL)
1542 1.1.2.2 yamt goto nomem;
1543 1.1.2.2 yamt
1544 1.1.2.2 yamt MH_ALIGN(m0, 5); /* (max 5 header octets) */
1545 1.1.2.2 yamt hdr = mtod(m0, uint8_t *);
1546 1.1.2.2 yamt
1547 1.1.2.2 yamt /* CR bit is set according to the initiator of the session */
1548 1.1.2.2 yamt *hdr = RFCOMM_MKADDRESS((IS_INITIATOR(rs) ? 1 : 0),
1549 1.1.2.2 yamt (dlc ? dlc->rd_dlci : 0));
1550 1.1.2.2 yamt fcs = FCS(0xff, *hdr);
1551 1.1.2.2 yamt hdr++;
1552 1.1.2.2 yamt
1553 1.1.2.2 yamt /* PF bit is set if credits are being sent */
1554 1.1.2.2 yamt *hdr = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, (credits > 0 ? 1 : 0));
1555 1.1.2.2 yamt fcs = FCS(fcs, *hdr);
1556 1.1.2.2 yamt hdr++;
1557 1.1.2.2 yamt
1558 1.1.2.2 yamt if (len < (1 << 7)) {
1559 1.1.2.2 yamt *hdr++ = ((len << 1) & 0xfe) | 0x01; /* 7 bits, EA = 1 */
1560 1.1.2.2 yamt } else {
1561 1.1.2.2 yamt *hdr++ = ((len << 1) & 0xfe); /* 7 bits, EA = 0 */
1562 1.1.2.2 yamt *hdr++ = ((len >> 7) & 0xff); /* 8 bits, no EA */
1563 1.1.2.2 yamt }
1564 1.1.2.2 yamt
1565 1.1.2.2 yamt if (credits > 0)
1566 1.1.2.2 yamt *hdr++ = (uint8_t)credits;
1567 1.1.2.2 yamt
1568 1.1.2.2 yamt m0->m_len = hdr - mtod(m0, uint8_t *);
1569 1.1.2.2 yamt
1570 1.1.2.2 yamt /* Append payload */
1571 1.1.2.2 yamt m0->m_next = m;
1572 1.1.2.2 yamt m = NULL;
1573 1.1.2.2 yamt
1574 1.1.2.2 yamt m0->m_pkthdr.len = m0->m_len + len;
1575 1.1.2.2 yamt
1576 1.1.2.2 yamt /* Append FCS */
1577 1.1.2.2 yamt fcs = 0xff - fcs; /* ones complement */
1578 1.1.2.2 yamt len = m0->m_pkthdr.len;
1579 1.1.2.2 yamt m_copyback(m0, len, sizeof(fcs), &fcs);
1580 1.1.2.2 yamt if (m0->m_pkthdr.len != len + sizeof(fcs))
1581 1.1.2.2 yamt goto nomem;
1582 1.1.2.2 yamt
1583 1.1.2.2 yamt DPRINTFN(10, "dlci %d, pktlen %d (%d data, %d credits), fcs=%#2.2x\n",
1584 1.1.2.2 yamt dlc ? dlc->rd_dlci : 0, m0->m_pkthdr.len, credit->rc_len,
1585 1.1.2.2 yamt credits, fcs);
1586 1.1.2.2 yamt
1587 1.1.2.2 yamt /*
1588 1.1.2.2 yamt * UIH frame ready to go..
1589 1.1.2.2 yamt */
1590 1.1.2.2 yamt err = l2cap_send(rs->rs_l2cap, m0);
1591 1.1.2.2 yamt if (err)
1592 1.1.2.2 yamt goto fail;
1593 1.1.2.2 yamt
1594 1.1.2.2 yamt SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
1595 1.1.2.2 yamt return 0;
1596 1.1.2.2 yamt
1597 1.1.2.2 yamt nomem:
1598 1.1.2.2 yamt err = ENOMEM;
1599 1.1.2.2 yamt
1600 1.1.2.2 yamt if (m0 != NULL)
1601 1.1.2.2 yamt m_freem(m0);
1602 1.1.2.2 yamt
1603 1.1.2.2 yamt if (m != NULL)
1604 1.1.2.2 yamt m_freem(m);
1605 1.1.2.2 yamt
1606 1.1.2.2 yamt fail:
1607 1.1.2.2 yamt if (credit != NULL)
1608 1.1.2.2 yamt pool_put(&rfcomm_credit_pool, credit);
1609 1.1.2.2 yamt
1610 1.1.2.2 yamt return err;
1611 1.1.2.2 yamt }
1612 1.1.2.2 yamt
1613 1.1.2.2 yamt /*
1614 1.1.2.2 yamt * send Multiplexer Control Command (or Response) on session
1615 1.1.2.2 yamt */
1616 1.1.2.2 yamt int
1617 1.1.2.2 yamt rfcomm_session_send_mcc(struct rfcomm_session *rs, int cr,
1618 1.1.2.2 yamt uint8_t type, void *data, int len)
1619 1.1.2.2 yamt {
1620 1.1.2.2 yamt struct mbuf *m;
1621 1.1.2.2 yamt uint8_t *hdr;
1622 1.1.2.2 yamt int hlen;
1623 1.1.2.2 yamt
1624 1.1.2.2 yamt m = m_gethdr(M_DONTWAIT, MT_DATA);
1625 1.1.2.2 yamt if (m == NULL)
1626 1.1.2.2 yamt return ENOMEM;
1627 1.1.2.2 yamt
1628 1.1.2.2 yamt hdr = mtod(m, uint8_t *);
1629 1.1.2.2 yamt
1630 1.1.2.2 yamt /*
1631 1.1.2.2 yamt * Technically the type field can extend past one octet, but none
1632 1.1.2.2 yamt * currently defined will do that.
1633 1.1.2.2 yamt */
1634 1.1.2.2 yamt *hdr++ = RFCOMM_MKMCC_TYPE(cr, type);
1635 1.1.2.2 yamt
1636 1.1.2.2 yamt /*
1637 1.1.2.2 yamt * In the frame, the max length size is 2 octets (15 bits) whereas
1638 1.1.2.2 yamt * no max length size is specified for MCC commands. We must allow
1639 1.1.2.2 yamt * for 3 octets since for MCC frames we use 7 bits + EA in each.
1640 1.1.2.2 yamt *
1641 1.1.2.2 yamt * Only test data can possibly be that big.
1642 1.1.2.2 yamt *
1643 1.1.2.2 yamt * XXX Should we check this against the MTU?
1644 1.1.2.2 yamt */
1645 1.1.2.2 yamt if (len < (1 << 7)) {
1646 1.1.2.2 yamt *hdr++ = ((len << 1) & 0xfe) | 0x01; /* 7 bits, EA = 1 */
1647 1.1.2.2 yamt } else if (len < (1 << 14)) {
1648 1.1.2.2 yamt *hdr++ = ((len << 1) & 0xfe); /* 7 bits, EA = 0 */
1649 1.1.2.2 yamt *hdr++ = ((len >> 6) & 0xfe) | 0x01; /* 7 bits, EA = 1 */
1650 1.1.2.2 yamt } else if (len < (1 << 15)) {
1651 1.1.2.2 yamt *hdr++ = ((len << 1) & 0xfe); /* 7 bits, EA = 0 */
1652 1.1.2.2 yamt *hdr++ = ((len >> 6) & 0xfe); /* 7 bits, EA = 0 */
1653 1.1.2.2 yamt *hdr++ = ((len >> 13) & 0x02) | 0x01; /* 1 bit, EA = 1 */
1654 1.1.2.2 yamt } else {
1655 1.1.2.2 yamt DPRINTF("incredible length! (%d)\n", len);
1656 1.1.2.2 yamt m_freem(m);
1657 1.1.2.2 yamt return EMSGSIZE;
1658 1.1.2.2 yamt }
1659 1.1.2.2 yamt
1660 1.1.2.2 yamt /*
1661 1.1.2.2 yamt * add command data (to same mbuf if possible)
1662 1.1.2.2 yamt */
1663 1.1.2.2 yamt hlen = hdr - mtod(m, uint8_t *);
1664 1.1.2.2 yamt
1665 1.1.2.2 yamt if (len > 0) {
1666 1.1.2.2 yamt m->m_pkthdr.len = m->m_len = MHLEN;
1667 1.1.2.2 yamt m_copyback(m, hlen, len, data);
1668 1.1.2.2 yamt if (m->m_pkthdr.len != max(MHLEN, hlen + len)) {
1669 1.1.2.2 yamt m_freem(m);
1670 1.1.2.2 yamt return ENOMEM;
1671 1.1.2.2 yamt }
1672 1.1.2.2 yamt }
1673 1.1.2.2 yamt
1674 1.1.2.2 yamt m->m_pkthdr.len = hlen + len;
1675 1.1.2.2 yamt m->m_len = min(MHLEN, m->m_pkthdr.len);
1676 1.1.2.2 yamt
1677 1.1.2.2 yamt DPRINTFN(5, "%s type %2.2x len %d\n",
1678 1.1.2.2 yamt (cr ? "command" : "response"), type, m->m_pkthdr.len);
1679 1.1.2.2 yamt
1680 1.1.2.2 yamt return rfcomm_session_send_uih(rs, NULL, 0, m);
1681 1.1.2.2 yamt }
1682