xref: /freebsd/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c (revision 8b3ae668b13db776ced151f20e9ad3d23eca545d)
1 /*
2  * ng_btsocket_rfcomm.c
3  */
4 
5 /*-
6  * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $Id: ng_btsocket_rfcomm.c,v 1.28 2003/09/14 23:29:06 max Exp $
31  * $FreeBSD$
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bitstring.h>
37 #include <sys/domain.h>
38 #include <sys/endian.h>
39 #include <sys/errno.h>
40 #include <sys/filedesc.h>
41 #include <sys/ioccom.h>
42 #include <sys/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/mutex.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/queue.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/sysctl.h>
53 #include <sys/taskqueue.h>
54 #include <sys/uio.h>
55 #include <netgraph/ng_message.h>
56 #include <netgraph/netgraph.h>
57 #include <netgraph/bluetooth/include/ng_bluetooth.h>
58 #include <netgraph/bluetooth/include/ng_hci.h>
59 #include <netgraph/bluetooth/include/ng_l2cap.h>
60 #include <netgraph/bluetooth/include/ng_btsocket.h>
61 #include <netgraph/bluetooth/include/ng_btsocket_l2cap.h>
62 #include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h>
63 
64 /* MALLOC define */
65 #ifdef NG_SEPARATE_MALLOC
66 MALLOC_DEFINE(M_NETGRAPH_BTSOCKET_RFCOMM, "netgraph_btsocks_rfcomm",
67 		"Netgraph Bluetooth RFCOMM sockets");
68 #else
69 #define M_NETGRAPH_BTSOCKET_RFCOMM M_NETGRAPH
70 #endif /* NG_SEPARATE_MALLOC */
71 
72 /* Debug */
73 #define NG_BTSOCKET_RFCOMM_INFO \
74 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_INFO_LEVEL) \
75 		printf
76 
77 #define NG_BTSOCKET_RFCOMM_WARN \
78 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_WARN_LEVEL) \
79 		printf
80 
81 #define NG_BTSOCKET_RFCOMM_ERR \
82 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_ERR_LEVEL) \
83 		printf
84 
85 #define NG_BTSOCKET_RFCOMM_ALERT \
86 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_ALERT_LEVEL) \
87 		printf
88 
89 #define	ALOT	0x7fff
90 
91 /* Local prototypes */
92 static void ng_btsocket_rfcomm_upcall
93 	(struct socket *so, void *arg, int waitflag);
94 static void ng_btsocket_rfcomm_sessions_task
95 	(void *ctx, int pending);
96 static void ng_btsocket_rfcomm_session_task
97 	(ng_btsocket_rfcomm_session_p s);
98 #define ng_btsocket_rfcomm_task_wakeup() \
99 	taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_rfcomm_task)
100 
101 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_connect_ind
102 	(ng_btsocket_rfcomm_session_p s, int channel);
103 static void ng_btsocket_rfcomm_connect_cfm
104 	(ng_btsocket_rfcomm_session_p s);
105 
106 static int ng_btsocket_rfcomm_session_create
107 	(ng_btsocket_rfcomm_session_p *sp, struct socket *l2so,
108 	 bdaddr_p src, bdaddr_p dst, struct thread *td);
109 static int ng_btsocket_rfcomm_session_accept
110 	(ng_btsocket_rfcomm_session_p s0);
111 static int ng_btsocket_rfcomm_session_connect
112 	(ng_btsocket_rfcomm_session_p s);
113 static int ng_btsocket_rfcomm_session_receive
114 	(ng_btsocket_rfcomm_session_p s);
115 static int ng_btsocket_rfcomm_session_send
116 	(ng_btsocket_rfcomm_session_p s);
117 static void ng_btsocket_rfcomm_session_clean
118 	(ng_btsocket_rfcomm_session_p s);
119 static void ng_btsocket_rfcomm_session_process_pcb
120 	(ng_btsocket_rfcomm_session_p s);
121 static ng_btsocket_rfcomm_session_p ng_btsocket_rfcomm_session_by_addr
122 	(bdaddr_p src, bdaddr_p dst);
123 
124 static int ng_btsocket_rfcomm_receive_frame
125 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
126 static int ng_btsocket_rfcomm_receive_sabm
127 	(ng_btsocket_rfcomm_session_p s, int dlci);
128 static int ng_btsocket_rfcomm_receive_disc
129 	(ng_btsocket_rfcomm_session_p s, int dlci);
130 static int ng_btsocket_rfcomm_receive_ua
131 	(ng_btsocket_rfcomm_session_p s, int dlci);
132 static int ng_btsocket_rfcomm_receive_dm
133 	(ng_btsocket_rfcomm_session_p s, int dlci);
134 static int ng_btsocket_rfcomm_receive_uih
135 	(ng_btsocket_rfcomm_session_p s, int dlci, int pf, struct mbuf *m0);
136 static int ng_btsocket_rfcomm_receive_mcc
137 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
138 static int ng_btsocket_rfcomm_receive_test
139 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
140 static int ng_btsocket_rfcomm_receive_fc
141 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
142 static int ng_btsocket_rfcomm_receive_msc
143 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
144 static int ng_btsocket_rfcomm_receive_rpn
145 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
146 static int ng_btsocket_rfcomm_receive_rls
147 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
148 static int ng_btsocket_rfcomm_receive_pn
149 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
150 static void ng_btsocket_rfcomm_set_pn
151 	(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, u_int8_t flow_control,
152 	 u_int8_t credits, u_int16_t mtu);
153 
154 static int ng_btsocket_rfcomm_send_command
155 	(ng_btsocket_rfcomm_session_p s, u_int8_t type, u_int8_t dlci);
156 static int ng_btsocket_rfcomm_send_uih
157 	(ng_btsocket_rfcomm_session_p s, u_int8_t address, u_int8_t pf,
158 	 u_int8_t credits, struct mbuf *data);
159 static int ng_btsocket_rfcomm_send_msc
160 	(ng_btsocket_rfcomm_pcb_p pcb);
161 static int ng_btsocket_rfcomm_send_pn
162 	(ng_btsocket_rfcomm_pcb_p pcb);
163 static int ng_btsocket_rfcomm_send_credits
164 	(ng_btsocket_rfcomm_pcb_p pcb);
165 
166 static int ng_btsocket_rfcomm_pcb_send
167 	(ng_btsocket_rfcomm_pcb_p pcb, int limit);
168 static int ng_btsocket_rfcomm_pcb_kill
169 	(ng_btsocket_rfcomm_pcb_p pcb, int error);
170 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_by_channel
171 	(bdaddr_p src, int channel);
172 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_by_dlci
173 	(ng_btsocket_rfcomm_session_p s, int dlci);
174 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_listener
175 	(bdaddr_p src, int channel);
176 
177 static void ng_btsocket_rfcomm_timeout
178 	(ng_btsocket_rfcomm_pcb_p pcb);
179 static void ng_btsocket_rfcomm_untimeout
180 	(ng_btsocket_rfcomm_pcb_p pcb);
181 static void ng_btsocket_rfcomm_process_timeout
182 	(void *xpcb);
183 
184 static struct mbuf * ng_btsocket_rfcomm_prepare_packet
185 	(struct sockbuf *sb, int length);
186 
187 /* Globals */
188 extern int					ifqmaxlen;
189 static u_int32_t				ng_btsocket_rfcomm_debug_level;
190 static u_int32_t				ng_btsocket_rfcomm_timo;
191 struct task					ng_btsocket_rfcomm_task;
192 static LIST_HEAD(, ng_btsocket_rfcomm_session)	ng_btsocket_rfcomm_sessions;
193 static struct mtx				ng_btsocket_rfcomm_sessions_mtx;
194 static LIST_HEAD(, ng_btsocket_rfcomm_pcb)	ng_btsocket_rfcomm_sockets;
195 static struct mtx				ng_btsocket_rfcomm_sockets_mtx;
196 
197 /* Sysctl tree */
198 SYSCTL_DECL(_net_bluetooth_rfcomm_sockets);
199 SYSCTL_NODE(_net_bluetooth_rfcomm_sockets, OID_AUTO, stream, CTLFLAG_RW,
200 	0, "Bluetooth STREAM RFCOMM sockets family");
201 SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, debug_level,
202 	CTLFLAG_RW,
203 	&ng_btsocket_rfcomm_debug_level, NG_BTSOCKET_INFO_LEVEL,
204 	"Bluetooth STREAM RFCOMM sockets debug level");
205 SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, timeout,
206 	CTLFLAG_RW,
207 	&ng_btsocket_rfcomm_timo, 60,
208 	"Bluetooth STREAM RFCOMM sockets timeout");
209 
210 /*****************************************************************************
211  *****************************************************************************
212  **                              RFCOMM CRC
213  *****************************************************************************
214  *****************************************************************************/
215 
216 static u_int8_t	ng_btsocket_rfcomm_crc_table[256] = {
217 	0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
218 	0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
219 	0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
220 	0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
221 
222 	0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
223 	0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
224 	0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
225 	0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
226 
227 	0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
228 	0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
229 	0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
230 	0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
231 
232 	0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
233 	0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
234 	0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
235 	0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
236 
237 	0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
238 	0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
239 	0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
240 	0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
241 
242 	0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
243 	0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
244 	0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
245 	0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
246 
247 	0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
248 	0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
249 	0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
250 	0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
251 
252 	0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
253 	0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
254 	0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
255 	0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
256 };
257 
258 /* CRC */
259 static u_int8_t
260 ng_btsocket_rfcomm_crc(u_int8_t *data, int length)
261 {
262 	u_int8_t	crc = 0xff;
263 
264 	while (length --)
265 		crc = ng_btsocket_rfcomm_crc_table[crc ^ *data++];
266 
267 	return (crc);
268 } /* ng_btsocket_rfcomm_crc */
269 
270 /* FCS on 2 bytes */
271 static u_int8_t
272 ng_btsocket_rfcomm_fcs2(u_int8_t *data)
273 {
274 	return (0xff - ng_btsocket_rfcomm_crc(data, 2));
275 } /* ng_btsocket_rfcomm_fcs2 */
276 
277 /* FCS on 3 bytes */
278 static u_int8_t
279 ng_btsocket_rfcomm_fcs3(u_int8_t *data)
280 {
281 	return (0xff - ng_btsocket_rfcomm_crc(data, 3));
282 } /* ng_btsocket_rfcomm_fcs3 */
283 
284 /*
285  * Check FCS
286  *
287  * From Bluetooth spec
288  *
289  * "... In 07.10, the frame check sequence (FCS) is calculated on different
290  * sets of fields for different frame types. These are the fields that the
291  * FCS are calculated on:
292  *
293  * For SABM, DISC, UA, DM frames: on Address, Control and length field.
294  * For UIH frames: on Address and Control field.
295  *
296  * (This is stated here for clarification, and to set the standard for RFCOMM;
297  * the fields included in FCS calculation have actually changed in version
298  * 7.0.0 of TS 07.10, but RFCOMM will not change the FCS calculation scheme
299  * from the one above.) ..."
300  */
301 
302 static int
303 ng_btsocket_rfcomm_check_fcs(u_int8_t *data, int type, u_int8_t fcs)
304 {
305 	if (type != RFCOMM_FRAME_UIH)
306 		return (ng_btsocket_rfcomm_fcs3(data) != fcs);
307 
308 	return (ng_btsocket_rfcomm_fcs2(data) != fcs);
309 } /* ng_btsocket_rfcomm_check_fcs */
310 
311 /*****************************************************************************
312  *****************************************************************************
313  **                              Socket interface
314  *****************************************************************************
315  *****************************************************************************/
316 
317 /*
318  * Initialize everything
319  */
320 
321 void
322 ng_btsocket_rfcomm_init(void)
323 {
324 	ng_btsocket_rfcomm_debug_level = NG_BTSOCKET_WARN_LEVEL;
325 	ng_btsocket_rfcomm_timo = 60;
326 
327 	/* RFCOMM task */
328 	TASK_INIT(&ng_btsocket_rfcomm_task, 0,
329 		ng_btsocket_rfcomm_sessions_task, NULL);
330 
331 	/* RFCOMM sessions list */
332 	LIST_INIT(&ng_btsocket_rfcomm_sessions);
333 	mtx_init(&ng_btsocket_rfcomm_sessions_mtx,
334 		"btsocks_rfcomm_sessions_mtx", NULL, MTX_DEF);
335 
336 	/* RFCOMM sockets list */
337 	LIST_INIT(&ng_btsocket_rfcomm_sockets);
338 	mtx_init(&ng_btsocket_rfcomm_sockets_mtx,
339 		"btsocks_rfcomm_sockets_mtx", NULL, MTX_DEF);
340 } /* ng_btsocket_rfcomm_init */
341 
342 /*
343  * Abort connection on socket
344  */
345 
346 void
347 ng_btsocket_rfcomm_abort(struct socket *so)
348 {
349 
350 	so->so_error = ECONNABORTED;
351 	(void)ng_btsocket_rfcomm_disconnect(so);
352 } /* ng_btsocket_rfcomm_abort */
353 
354 void
355 ng_btsocket_rfcomm_close(struct socket *so)
356 {
357 
358 	(void)ng_btsocket_rfcomm_disconnect(so);
359 } /* ng_btsocket_rfcomm_close */
360 
361 /*
362  * Accept connection on socket. Nothing to do here, socket must be connected
363  * and ready, so just return peer address and be done with it.
364  */
365 
366 int
367 ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam)
368 {
369 	return (ng_btsocket_rfcomm_peeraddr(so, nam));
370 } /* ng_btsocket_rfcomm_accept */
371 
372 /*
373  * Create and attach new socket
374  */
375 
376 int
377 ng_btsocket_rfcomm_attach(struct socket *so, int proto, struct thread *td)
378 {
379 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
380 	int				error;
381 
382 	/* Check socket and protocol */
383 	if (so->so_type != SOCK_STREAM)
384 		return (ESOCKTNOSUPPORT);
385 
386 #if 0 /* XXX sonewconn() calls "pru_attach" with proto == 0 */
387 	if (proto != 0)
388 		if (proto != BLUETOOTH_PROTO_RFCOMM)
389 			return (EPROTONOSUPPORT);
390 #endif /* XXX */
391 
392 	if (pcb != NULL)
393 		return (EISCONN);
394 
395 	/* Reserve send and receive space if it is not reserved yet */
396 	if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
397 		error = soreserve(so, NG_BTSOCKET_RFCOMM_SENDSPACE,
398 					NG_BTSOCKET_RFCOMM_RECVSPACE);
399 		if (error != 0)
400 			return (error);
401 	}
402 
403 	/* Allocate the PCB */
404         MALLOC(pcb, ng_btsocket_rfcomm_pcb_p, sizeof(*pcb),
405 		M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO);
406         if (pcb == NULL)
407                 return (ENOMEM);
408 
409 	/* Link the PCB and the socket */
410 	so->so_pcb = (caddr_t) pcb;
411 	pcb->so = so;
412 
413 	/* Initialize PCB */
414 	pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED;
415 	pcb->flags = NG_BTSOCKET_RFCOMM_DLC_CFC;
416 
417 	pcb->lmodem =
418 	pcb->rmodem = (RFCOMM_MODEM_RTC | RFCOMM_MODEM_RTR | RFCOMM_MODEM_DV);
419 
420 	pcb->mtu = RFCOMM_DEFAULT_MTU;
421 	pcb->tx_cred = 0;
422 	pcb->rx_cred = RFCOMM_DEFAULT_CREDITS;
423 
424 	mtx_init(&pcb->pcb_mtx, "btsocks_rfcomm_pcb_mtx", NULL, MTX_DEF);
425 	callout_handle_init(&pcb->timo);
426 
427 	/* Add the PCB to the list */
428 	mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
429 	LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sockets, pcb, next);
430 	mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
431 
432         return (0);
433 } /* ng_btsocket_rfcomm_attach */
434 
435 /*
436  * Bind socket
437  */
438 
439 int
440 ng_btsocket_rfcomm_bind(struct socket *so, struct sockaddr *nam,
441 		struct thread *td)
442 {
443 	ng_btsocket_rfcomm_pcb_t	*pcb = so2rfcomm_pcb(so);
444 	struct sockaddr_rfcomm		*sa = (struct sockaddr_rfcomm *) nam;
445 
446 	if (pcb == NULL)
447 		return (EINVAL);
448 
449 	/* Verify address */
450 	if (sa == NULL)
451 		return (EINVAL);
452 	if (sa->rfcomm_family != AF_BLUETOOTH)
453 		return (EAFNOSUPPORT);
454 	if (sa->rfcomm_len != sizeof(*sa))
455 		return (EINVAL);
456 	if (sa->rfcomm_channel > 30)
457 		return (EINVAL);
458 	if (sa->rfcomm_channel != 0 &&
459 	    ng_btsocket_rfcomm_pcb_by_channel(&sa->rfcomm_bdaddr, sa->rfcomm_channel) != NULL)
460 		return (EADDRINUSE);
461 
462 	bcopy(&sa->rfcomm_bdaddr, &pcb->src, sizeof(pcb->src));
463 	pcb->channel = sa->rfcomm_channel;
464 
465 	return (0);
466 } /* ng_btsocket_rfcomm_bind */
467 
468 /*
469  * Connect socket
470  */
471 
472 int
473 ng_btsocket_rfcomm_connect(struct socket *so, struct sockaddr *nam,
474 		struct thread *td)
475 {
476 	ng_btsocket_rfcomm_pcb_t	*pcb = so2rfcomm_pcb(so);
477 	struct sockaddr_rfcomm		*sa = (struct sockaddr_rfcomm *) nam;
478 	ng_btsocket_rfcomm_session_t	*s = NULL;
479 	struct socket			*l2so = NULL;
480 	int				 dlci, error = 0;
481 
482 	if (pcb == NULL)
483 		return (EINVAL);
484 
485 	/* Verify address */
486 	if (sa == NULL)
487 		return (EINVAL);
488 	if (sa->rfcomm_family != AF_BLUETOOTH)
489 		return (EAFNOSUPPORT);
490 	if (sa->rfcomm_len != sizeof(*sa))
491 		return (EINVAL);
492 	if (sa->rfcomm_channel > 30)
493 		return (EINVAL);
494 	if (sa->rfcomm_channel == 0 ||
495 	    bcmp(&sa->rfcomm_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
496 		return (EDESTADDRREQ);
497 
498 	/*
499 	 * XXX FIXME - This is FUBAR. socreate() will call soalloc(1), i.e.
500 	 * soalloc() is allowed to sleep in MALLOC. This creates "could sleep"
501 	 * WITNESS warnings. To work around this problem we will create L2CAP
502 	 * socket first and then check if we actually need it. Note that we
503 	 * will not check for errors in socreate() because if we failed to
504 	 * create L2CAP socket at this point we still might have already open
505 	 * session.
506 	 */
507 
508 	error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET,
509 			BLUETOOTH_PROTO_L2CAP, td->td_ucred, td);
510 
511 	/*
512 	 * Look for session between "pcb->src" and "sa->rfcomm_bdaddr" (dst)
513 	 */
514 
515 	mtx_lock(&ng_btsocket_rfcomm_sessions_mtx);
516 
517 	s = ng_btsocket_rfcomm_session_by_addr(&pcb->src, &sa->rfcomm_bdaddr);
518 	if (s == NULL) {
519 		/*
520 		 * We need to create new RFCOMM session. Check if we have L2CAP
521 		 * socket. If l2so == NULL then error has the error code from
522 		 * socreate()
523 		 */
524 
525 		if (l2so == NULL) {
526 			mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
527 			return (error);
528 		}
529 
530 		error = ng_btsocket_rfcomm_session_create(&s, l2so,
531 				&pcb->src, &sa->rfcomm_bdaddr, td);
532 		if (error != 0) {
533 			mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
534 			soclose(l2so);
535 
536 			return (error);
537 		}
538 	} else if (l2so != NULL)
539 		soclose(l2so); /* we don't need new L2CAP socket */
540 
541 	/*
542 	 * Check if we already have the same DLCI the the same session
543 	 */
544 
545 	mtx_lock(&s->session_mtx);
546 	mtx_lock(&pcb->pcb_mtx);
547 
548 	dlci = RFCOMM_MKDLCI(!INITIATOR(s), sa->rfcomm_channel);
549 
550 	if (ng_btsocket_rfcomm_pcb_by_dlci(s, dlci) != NULL) {
551 		mtx_unlock(&pcb->pcb_mtx);
552 		mtx_unlock(&s->session_mtx);
553 		mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
554 
555 		return (EBUSY);
556 	}
557 
558 	/*
559 	 * Check session state and if its not acceptable then refuse connection
560 	 */
561 
562 	switch (s->state) {
563 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING:
564 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
565 	case NG_BTSOCKET_RFCOMM_SESSION_OPEN:
566 		/*
567 		 * Update destination address and channel and attach
568 		 * DLC to the session
569 		 */
570 
571 		bcopy(&sa->rfcomm_bdaddr, &pcb->dst, sizeof(pcb->dst));
572 		pcb->channel = sa->rfcomm_channel;
573 		pcb->dlci = dlci;
574 
575 		LIST_INSERT_HEAD(&s->dlcs, pcb, session_next);
576 		pcb->session = s;
577 
578 		ng_btsocket_rfcomm_timeout(pcb);
579 		soisconnecting(pcb->so);
580 
581 		if (s->state == NG_BTSOCKET_RFCOMM_SESSION_OPEN) {
582 			pcb->mtu = s->mtu;
583 			bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src,
584 				sizeof(pcb->src));
585 
586 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING;
587 
588 			error = ng_btsocket_rfcomm_send_pn(pcb);
589 			if (error == 0)
590 				error = ng_btsocket_rfcomm_task_wakeup();
591 		} else
592 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT;
593 		break;
594 
595 	default:
596 		error = ECONNRESET;
597 		break;
598 	}
599 
600 	mtx_unlock(&pcb->pcb_mtx);
601 	mtx_unlock(&s->session_mtx);
602 	mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
603 
604 	return (error);
605 } /* ng_btsocket_rfcomm_connect */
606 
607 /*
608  * Process ioctl's calls on socket.
609  * XXX FIXME this should provide interface to the RFCOMM multiplexor channel
610  */
611 
612 int
613 ng_btsocket_rfcomm_control(struct socket *so, u_long cmd, caddr_t data,
614 		struct ifnet *ifp, struct thread *td)
615 {
616 	return (EINVAL);
617 } /* ng_btsocket_rfcomm_control */
618 
619 /*
620  * Process getsockopt/setsockopt system calls
621  */
622 
623 int
624 ng_btsocket_rfcomm_ctloutput(struct socket *so, struct sockopt *sopt)
625 {
626 	ng_btsocket_rfcomm_pcb_p		pcb = so2rfcomm_pcb(so);
627 	struct ng_btsocket_rfcomm_fc_info	fcinfo;
628 	int					error = 0;
629 
630 	if (pcb == NULL)
631 		return (EINVAL);
632 	if (sopt->sopt_level != SOL_RFCOMM)
633 		return (0);
634 
635 	mtx_lock(&pcb->pcb_mtx);
636 
637 	switch (sopt->sopt_dir) {
638 	case SOPT_GET:
639 		switch (sopt->sopt_name) {
640 		case SO_RFCOMM_MTU:
641 			error = sooptcopyout(sopt, &pcb->mtu, sizeof(pcb->mtu));
642 			break;
643 
644 		case SO_RFCOMM_FC_INFO:
645 			fcinfo.lmodem = pcb->lmodem;
646 			fcinfo.rmodem = pcb->rmodem;
647 			fcinfo.tx_cred = pcb->tx_cred;
648 			fcinfo.rx_cred = pcb->rx_cred;
649 			fcinfo.cfc = (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)?
650 				1 : 0;
651 			fcinfo.reserved = 0;
652 
653 			error = sooptcopyout(sopt, &fcinfo, sizeof(fcinfo));
654 			break;
655 
656 		default:
657 			error = ENOPROTOOPT;
658 			break;
659 		}
660 		break;
661 
662 	case SOPT_SET:
663 		switch (sopt->sopt_name) {
664 		default:
665 			error = ENOPROTOOPT;
666 			break;
667 		}
668 		break;
669 
670 	default:
671 		error = EINVAL;
672 		break;
673 	}
674 
675 	mtx_unlock(&pcb->pcb_mtx);
676 
677 	return (error);
678 } /* ng_btsocket_rfcomm_ctloutput */
679 
680 /*
681  * Detach and destroy socket
682  */
683 
684 void
685 ng_btsocket_rfcomm_detach(struct socket *so)
686 {
687 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
688 
689 	KASSERT(pcb != NULL, ("ng_btsocket_rfcomm_detach: pcb == NULL"));
690 
691 	mtx_lock(&pcb->pcb_mtx);
692 
693 	switch (pcb->state) {
694 	case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT:
695 	case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING:
696 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTING:
697 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTED:
698 		/* XXX What to do with pending request? */
699 		if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
700 			ng_btsocket_rfcomm_untimeout(pcb);
701 
702 		if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT)
703 			pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_DETACHED;
704 		else
705 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING;
706 
707 		ng_btsocket_rfcomm_task_wakeup();
708 		break;
709 
710 	case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING:
711 		ng_btsocket_rfcomm_task_wakeup();
712 		break;
713 	}
714 
715 	while (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CLOSED)
716 		msleep(&pcb->state, &pcb->pcb_mtx, PZERO, "rf_det", 0);
717 
718 	if (pcb->session != NULL)
719 		panic("%s: pcb->session != NULL\n", __func__);
720 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
721 		panic("%s: timeout on closed DLC, flags=%#x\n",
722 			__func__, pcb->flags);
723 
724 	mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
725 	LIST_REMOVE(pcb, next);
726 	mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
727 
728 	mtx_unlock(&pcb->pcb_mtx);
729 
730 	mtx_destroy(&pcb->pcb_mtx);
731 	bzero(pcb, sizeof(*pcb));
732 	FREE(pcb, M_NETGRAPH_BTSOCKET_RFCOMM);
733 
734 	soisdisconnected(so);
735 	so->so_pcb = NULL;
736 } /* ng_btsocket_rfcomm_detach */
737 
738 /*
739  * Disconnect socket
740  */
741 
742 int
743 ng_btsocket_rfcomm_disconnect(struct socket *so)
744 {
745 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
746 
747 	if (pcb == NULL)
748 		return (EINVAL);
749 
750 	mtx_lock(&pcb->pcb_mtx);
751 
752 	if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING) {
753 		mtx_unlock(&pcb->pcb_mtx);
754 		return (EINPROGRESS);
755 	}
756 
757 	/* XXX What to do with pending request? */
758 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
759 		ng_btsocket_rfcomm_untimeout(pcb);
760 
761 	switch (pcb->state) {
762 	case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: /* XXX can we get here? */
763 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: /* XXX can we get here? */
764 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTED:
765 
766 		/*
767 		 * Just change DLC state and enqueue RFCOMM task. It will
768 		 * queue and send DISC on the DLC.
769 		 */
770 
771 		pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING;
772 		soisdisconnecting(so);
773 
774 		ng_btsocket_rfcomm_task_wakeup();
775 		break;
776 
777 /*
778  * 	case NG_BTSOCKET_RFCOMM_DLC_CLOSED:
779  *	case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT:
780  *	case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING:
781  */
782 	default:
783 		panic("%s: Invalid DLC state=%d, flags=%#x\n",
784 			__func__, pcb->state, pcb->flags);
785 		break;
786 	}
787 
788 	mtx_unlock(&pcb->pcb_mtx);
789 
790 	return (0);
791 } /* ng_btsocket_rfcomm_disconnect */
792 
793 /*
794  * Listen on socket. First call to listen() will create listening RFCOMM session
795  */
796 
797 int
798 ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td)
799 {
800 	ng_btsocket_rfcomm_pcb_p	 pcb = so2rfcomm_pcb(so);
801 	ng_btsocket_rfcomm_session_p	 s = NULL;
802 	struct socket			*l2so = NULL;
803 	int				 error;
804 	int				 socreate_error;
805 
806 	if (pcb == NULL)
807 		return (EINVAL);
808 	if (pcb->channel < 1 || pcb->channel > 30)
809 		return (EDESTADDRREQ);
810 
811 	/*
812 	 * XXX FIXME - This is FUBAR. socreate() will call soalloc(1), i.e.
813 	 * soalloc() is allowed to sleep in MALLOC. This creates "could sleep"
814 	 * WITNESS warnings. To work around this problem we will create L2CAP
815 	 * socket first and then check if we actually need it. Note that we
816 	 * will not check for errors in socreate() because if we failed to
817 	 * create L2CAP socket at this point we still might have already open
818 	 * session.
819 	 */
820 
821 	socreate_error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET,
822 			BLUETOOTH_PROTO_L2CAP, td->td_ucred, td);
823 
824 	/*
825 	 * Transition the socket and session into the LISTENING state.  Check
826 	 * for collisions first, as there can only be one.
827 	 */
828 	mtx_lock(&ng_btsocket_rfcomm_sessions_mtx);
829 	SOCK_LOCK(so);
830 	error = solisten_proto_check(so);
831 	if (error != 0)
832 		goto out;
833 
834 	LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next)
835 		if (s->state == NG_BTSOCKET_RFCOMM_SESSION_LISTENING)
836 			break;
837 
838 	if (s == NULL) {
839 		/*
840 		 * We need to create default RFCOMM session. Check if we have
841 		 * L2CAP socket. If l2so == NULL then error has the error code
842 		 * from socreate()
843 		 */
844 		if (l2so == NULL) {
845 			error = socreate_error;
846 			goto out;
847 		}
848 
849 		/*
850 		 * Create default listen RFCOMM session. The default RFCOMM
851 		 * session will listen on ANY address.
852 		 *
853 		 * XXX FIXME Note that currently there is no way to adjust MTU
854 		 * for the default session.
855 		 */
856 		error = ng_btsocket_rfcomm_session_create(&s, l2so,
857 					NG_HCI_BDADDR_ANY, NULL, td);
858 		if (error != 0)
859 			goto out;
860 		l2so = NULL;
861 	}
862 	solisten_proto(so, backlog);
863 out:
864 	SOCK_UNLOCK(so);
865 	mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
866 	/*
867 	 * If we still have an l2so reference here, it's unneeded, so release
868 	 * it.
869 	 */
870 	if (l2so != NULL)
871 		soclose(l2so);
872 	return (error);
873 } /* ng_btsocket_listen */
874 
875 /*
876  * Get peer address
877  */
878 
879 int
880 ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam)
881 {
882 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
883 	struct sockaddr_rfcomm		sa;
884 
885 	if (pcb == NULL)
886 		return (EINVAL);
887 
888 	bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
889 	sa.rfcomm_channel = pcb->channel;
890 	sa.rfcomm_len = sizeof(sa);
891 	sa.rfcomm_family = AF_BLUETOOTH;
892 
893 	*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
894 
895 	return ((*nam == NULL)? ENOMEM : 0);
896 } /* ng_btsocket_rfcomm_peeraddr */
897 
898 /*
899  * Send data to socket
900  */
901 
902 int
903 ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m,
904 		struct sockaddr *nam, struct mbuf *control, struct thread *td)
905 {
906 	ng_btsocket_rfcomm_pcb_t	*pcb = so2rfcomm_pcb(so);
907 	int				 error = 0;
908 
909 	/* Check socket and input */
910 	if (pcb == NULL || m == NULL || control != NULL) {
911 		error = EINVAL;
912 		goto drop;
913 	}
914 
915 	mtx_lock(&pcb->pcb_mtx);
916 
917 	/* Make sure DLC is connected */
918 	if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) {
919 		mtx_unlock(&pcb->pcb_mtx);
920 		error = ENOTCONN;
921 		goto drop;
922 	}
923 
924 	/* Put the packet on the socket's send queue and wakeup RFCOMM task */
925 	sbappend(&pcb->so->so_snd, m);
926 	m = NULL;
927 
928 	if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) {
929 		pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_SENDING;
930 		error = ng_btsocket_rfcomm_task_wakeup();
931 	}
932 
933 	mtx_unlock(&pcb->pcb_mtx);
934 drop:
935 	NG_FREE_M(m); /* checks for != NULL */
936 	NG_FREE_M(control);
937 
938 	return (error);
939 } /* ng_btsocket_rfcomm_send */
940 
941 /*
942  * Get socket address
943  */
944 
945 int
946 ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam)
947 {
948 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
949 	struct sockaddr_rfcomm		sa;
950 
951 	if (pcb == NULL)
952 		return (EINVAL);
953 
954 	bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
955 	sa.rfcomm_channel = pcb->channel;
956 	sa.rfcomm_len = sizeof(sa);
957 	sa.rfcomm_family = AF_BLUETOOTH;
958 
959 	*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
960 
961 	return ((*nam == NULL)? ENOMEM : 0);
962 } /* ng_btsocket_rfcomm_sockaddr */
963 
964 /*
965  * Upcall function for L2CAP sockets. Enqueue RFCOMM task.
966  */
967 
968 static void
969 ng_btsocket_rfcomm_upcall(struct socket *so, void *arg, int waitflag)
970 {
971 	int	error;
972 
973 	if (so == NULL)
974 		panic("%s: so == NULL\n", __func__);
975 
976 	if ((error = ng_btsocket_rfcomm_task_wakeup()) != 0)
977 		NG_BTSOCKET_RFCOMM_ALERT(
978 "%s: Could not enqueue RFCOMM task, error=%d\n", __func__, error);
979 } /* ng_btsocket_rfcomm_upcall */
980 
981 /*
982  * RFCOMM task. Will handle all RFCOMM sessions in one pass.
983  * XXX FIXME does not scale very well
984  */
985 
986 static void
987 ng_btsocket_rfcomm_sessions_task(void *ctx, int pending)
988 {
989 	ng_btsocket_rfcomm_session_p	s = NULL, s_next = NULL;
990 
991 	mtx_lock(&ng_btsocket_rfcomm_sessions_mtx);
992 
993 	for (s = LIST_FIRST(&ng_btsocket_rfcomm_sessions); s != NULL; ) {
994 		mtx_lock(&s->session_mtx);
995 		s_next = LIST_NEXT(s, next);
996 
997 		ng_btsocket_rfcomm_session_task(s);
998 
999 		if (s->state == NG_BTSOCKET_RFCOMM_SESSION_CLOSED) {
1000 			/* Unlink and clean the session */
1001 			LIST_REMOVE(s, next);
1002 
1003 			NG_BT_MBUFQ_DRAIN(&s->outq);
1004 			if (!LIST_EMPTY(&s->dlcs))
1005 				panic("%s: DLC list is not empty\n", __func__);
1006 
1007 			/* Close L2CAP socket */
1008 			s->l2so->so_upcallarg = NULL;
1009 			s->l2so->so_upcall = NULL;
1010 			SOCKBUF_LOCK(&s->l2so->so_rcv);
1011 			s->l2so->so_rcv.sb_flags &= ~SB_UPCALL;
1012 			SOCKBUF_UNLOCK(&s->l2so->so_rcv);
1013 			SOCKBUF_LOCK(&s->l2so->so_snd);
1014 			s->l2so->so_snd.sb_flags &= ~SB_UPCALL;
1015 			SOCKBUF_UNLOCK(&s->l2so->so_snd);
1016 			soclose(s->l2so);
1017 
1018 			mtx_unlock(&s->session_mtx);
1019 
1020 			mtx_destroy(&s->session_mtx);
1021 			bzero(s, sizeof(*s));
1022 			FREE(s, M_NETGRAPH_BTSOCKET_RFCOMM);
1023 		} else
1024 			mtx_unlock(&s->session_mtx);
1025 
1026 		s = s_next;
1027 	}
1028 
1029 	mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
1030 } /* ng_btsocket_rfcomm_sessions_task */
1031 
1032 /*
1033  * Process RFCOMM session. Will handle all RFCOMM sockets in one pass.
1034  */
1035 
1036 static void
1037 ng_btsocket_rfcomm_session_task(ng_btsocket_rfcomm_session_p s)
1038 {
1039 	mtx_assert(&s->session_mtx, MA_OWNED);
1040 
1041 	if (s->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) {
1042 		NG_BTSOCKET_RFCOMM_INFO(
1043 "%s: L2CAP connection has been terminated, so=%p, so_state=%#x, so_count=%d, " \
1044 "state=%d, flags=%#x\n", __func__, s->l2so, s->l2so->so_state,
1045 			s->l2so->so_count, s->state, s->flags);
1046 
1047 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1048 		ng_btsocket_rfcomm_session_clean(s);
1049 	}
1050 
1051 	/* Now process upcall */
1052 	switch (s->state) {
1053 	/* Try to accept new L2CAP connection(s) */
1054 	case NG_BTSOCKET_RFCOMM_SESSION_LISTENING:
1055 		while (ng_btsocket_rfcomm_session_accept(s) == 0)
1056 			;
1057 		break;
1058 
1059 	/* Process the results of the L2CAP connect */
1060 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING:
1061 		ng_btsocket_rfcomm_session_process_pcb(s);
1062 
1063 		if (ng_btsocket_rfcomm_session_connect(s) != 0) {
1064 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1065 			ng_btsocket_rfcomm_session_clean(s);
1066 		}
1067 		break;
1068 
1069 	/* Try to receive/send more data */
1070 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
1071 	case NG_BTSOCKET_RFCOMM_SESSION_OPEN:
1072 	case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING:
1073 		ng_btsocket_rfcomm_session_process_pcb(s);
1074 
1075 		if (ng_btsocket_rfcomm_session_receive(s) != 0) {
1076 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1077 			ng_btsocket_rfcomm_session_clean(s);
1078 		} else if (ng_btsocket_rfcomm_session_send(s) != 0) {
1079 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1080 			ng_btsocket_rfcomm_session_clean(s);
1081 		}
1082 		break;
1083 
1084 	case NG_BTSOCKET_RFCOMM_SESSION_CLOSED:
1085 		break;
1086 
1087 	default:
1088 		panic("%s: Invalid session state=%d, flags=%#x\n",
1089 			__func__, s->state, s->flags);
1090 		break;
1091 	}
1092 } /* ng_btsocket_rfcomm_session_task */
1093 
1094 /*
1095  * Process RFCOMM connection indicator. Caller must hold s->session_mtx
1096  */
1097 
1098 static ng_btsocket_rfcomm_pcb_p
1099 ng_btsocket_rfcomm_connect_ind(ng_btsocket_rfcomm_session_p s, int channel)
1100 {
1101 	ng_btsocket_rfcomm_pcb_p	 pcb = NULL, pcb1 = NULL;
1102 	ng_btsocket_l2cap_pcb_p		 l2pcb = NULL;
1103 	struct socket			*so1 = NULL;
1104 
1105 	mtx_assert(&s->session_mtx, MA_OWNED);
1106 
1107 	/*
1108 	 * Try to find RFCOMM socket that listens on given source address
1109 	 * and channel. This will return the best possible match.
1110 	 */
1111 
1112 	l2pcb = so2l2cap_pcb(s->l2so);
1113 	pcb = ng_btsocket_rfcomm_pcb_listener(&l2pcb->src, channel);
1114 	if (pcb == NULL)
1115 		return (NULL);
1116 
1117 	/*
1118 	 * Check the pending connections queue and if we have space then
1119 	 * create new socket and set proper source and destination address,
1120 	 * and channel.
1121 	 */
1122 
1123 	mtx_lock(&pcb->pcb_mtx);
1124 
1125 	if (pcb->so->so_qlen <= pcb->so->so_qlimit)
1126 		so1 = sonewconn(pcb->so, 0);
1127 
1128 	mtx_unlock(&pcb->pcb_mtx);
1129 
1130 	if (so1 == NULL)
1131 		return (NULL);
1132 
1133 	/*
1134 	 * If we got here than we have created new socket. So complete the
1135 	 * connection. Set source and destination address from the session.
1136 	 */
1137 
1138 	pcb1 = so2rfcomm_pcb(so1);
1139 	if (pcb1 == NULL)
1140 		panic("%s: pcb1 == NULL\n", __func__);
1141 
1142 	mtx_lock(&pcb1->pcb_mtx);
1143 
1144 	bcopy(&l2pcb->src, &pcb1->src, sizeof(pcb1->src));
1145 	bcopy(&l2pcb->dst, &pcb1->dst, sizeof(pcb1->dst));
1146 	pcb1->channel = channel;
1147 
1148 	/* Link new DLC to the session. We already hold s->session_mtx */
1149 	LIST_INSERT_HEAD(&s->dlcs, pcb1, session_next);
1150 	pcb1->session = s;
1151 
1152 	mtx_unlock(&pcb1->pcb_mtx);
1153 
1154 	return (pcb1);
1155 } /* ng_btsocket_rfcomm_connect_ind */
1156 
1157 /*
1158  * Process RFCOMM connect confirmation. Caller must hold s->session_mtx.
1159  */
1160 
1161 static void
1162 ng_btsocket_rfcomm_connect_cfm(ng_btsocket_rfcomm_session_p s)
1163 {
1164 	ng_btsocket_rfcomm_pcb_p	 pcb = NULL, pcb_next = NULL;
1165 	struct socket			*so = NULL;
1166 	int				 error;
1167 
1168 	mtx_assert(&s->session_mtx, MA_OWNED);
1169 
1170 	/*
1171 	 * Wake up all waiting sockets and send PN request for each of them.
1172 	 * Note that timeout already been set in ng_btsocket_rfcomm_connect()
1173 	 *
1174 	 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill
1175 	 * will unlink DLC from the session
1176 	 */
1177 
1178 	for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) {
1179 		mtx_lock(&pcb->pcb_mtx);
1180 		pcb_next = LIST_NEXT(pcb, session_next);
1181 
1182 		if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) {
1183 			pcb->mtu = s->mtu;
1184 			bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src,
1185 				sizeof(pcb->src));
1186 
1187 			error = ng_btsocket_rfcomm_send_pn(pcb);
1188 			if (error == 0)
1189 				pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING;
1190 			else if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
1191 				so = pcb->so;
1192 			else
1193 				so = NULL;
1194 		}
1195 
1196 		mtx_unlock(&pcb->pcb_mtx);
1197 		pcb = pcb_next;
1198 
1199 		if (so != NULL)
1200 			ng_btsocket_rfcomm_detach(so);
1201 	}
1202 } /* ng_btsocket_rfcomm_connect_cfm */
1203 
1204 /*****************************************************************************
1205  *****************************************************************************
1206  **                              RFCOMM sessions
1207  *****************************************************************************
1208  *****************************************************************************/
1209 
1210 /*
1211  * Create new RFCOMM session. That function WILL NOT take ownership over l2so.
1212  * Caller MUST free l2so if function failed.
1213  */
1214 
1215 static int
1216 ng_btsocket_rfcomm_session_create(ng_btsocket_rfcomm_session_p *sp,
1217 		struct socket *l2so, bdaddr_p src, bdaddr_p dst,
1218 		struct thread *td)
1219 {
1220 	ng_btsocket_rfcomm_session_p	s = NULL;
1221 	struct sockaddr_l2cap		l2sa;
1222 	struct sockopt			l2sopt;
1223 	int				mtu, error;
1224 
1225 	mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED);
1226 
1227 	/* Allocate the RFCOMM session */
1228         MALLOC(s, ng_btsocket_rfcomm_session_p, sizeof(*s),
1229 		M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO);
1230         if (s == NULL)
1231                 return (ENOMEM);
1232 
1233 	/* Set defaults */
1234 	s->mtu = RFCOMM_DEFAULT_MTU;
1235 	s->flags = 0;
1236 	s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1237 	NG_BT_MBUFQ_INIT(&s->outq, ifqmaxlen);
1238 
1239 	/*
1240 	 * XXX Mark session mutex as DUPOK to prevent "duplicated lock of
1241 	 * the same type" message. When accepting new L2CAP connection
1242 	 * ng_btsocket_rfcomm_session_accept() holds both session mutexes
1243 	 * for "old" (accepting) session and "new" (created) session.
1244 	 */
1245 
1246 	mtx_init(&s->session_mtx, "btsocks_rfcomm_session_mtx", NULL,
1247 		MTX_DEF|MTX_DUPOK);
1248 
1249 	LIST_INIT(&s->dlcs);
1250 
1251 	/* Prepare L2CAP socket */
1252 	l2so->so_upcallarg = NULL;
1253 	l2so->so_upcall = ng_btsocket_rfcomm_upcall;
1254 	SOCKBUF_LOCK(&l2so->so_rcv);
1255 	l2so->so_rcv.sb_flags |= SB_UPCALL;
1256 	SOCKBUF_UNLOCK(&l2so->so_rcv);
1257 	SOCKBUF_LOCK(&l2so->so_snd);
1258 	l2so->so_snd.sb_flags |= SB_UPCALL;
1259 	SOCKBUF_UNLOCK(&l2so->so_snd);
1260 	l2so->so_state |= SS_NBIO;
1261 	s->l2so = l2so;
1262 
1263 	mtx_lock(&s->session_mtx);
1264 
1265 	/*
1266 	 * "src" == NULL and "dst" == NULL means just create session.
1267 	 * caller must do the rest
1268 	 */
1269 
1270 	if (src == NULL && dst == NULL)
1271 		goto done;
1272 
1273 	/*
1274 	 * Set incoming MTU on L2CAP socket. It is RFCOMM session default MTU
1275 	 * plus 5 bytes: RFCOMM frame header, one extra byte for length and one
1276 	 * extra byte for credits.
1277 	 */
1278 
1279 	mtu = s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1;
1280 
1281 	l2sopt.sopt_dir = SOPT_SET;
1282 	l2sopt.sopt_level = SOL_L2CAP;
1283 	l2sopt.sopt_name = SO_L2CAP_IMTU;
1284 	l2sopt.sopt_val = (void *) &mtu;
1285 	l2sopt.sopt_valsize = sizeof(mtu);
1286 	l2sopt.sopt_td = NULL;
1287 
1288 	error = sosetopt(s->l2so, &l2sopt);
1289 	if (error != 0)
1290 		goto bad;
1291 
1292 	/* Bind socket to "src" address */
1293 	l2sa.l2cap_len = sizeof(l2sa);
1294 	l2sa.l2cap_family = AF_BLUETOOTH;
1295 	l2sa.l2cap_psm = (dst == NULL)? htole16(NG_L2CAP_PSM_RFCOMM) : 0;
1296 	bcopy(src, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr));
1297 
1298 	error = sobind(s->l2so, (struct sockaddr *) &l2sa, td);
1299 	if (error != 0)
1300 		goto bad;
1301 
1302 	/* If "dst" is not NULL then initiate connect(), otherwise listen() */
1303 	if (dst == NULL) {
1304 		s->flags = 0;
1305 		s->state = NG_BTSOCKET_RFCOMM_SESSION_LISTENING;
1306 
1307 		error = solisten(s->l2so, 10, td);
1308 		if (error != 0)
1309 			goto bad;
1310 	} else {
1311 		s->flags = NG_BTSOCKET_RFCOMM_SESSION_INITIATOR;
1312 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTING;
1313 
1314 		l2sa.l2cap_len = sizeof(l2sa);
1315 		l2sa.l2cap_family = AF_BLUETOOTH;
1316 		l2sa.l2cap_psm = htole16(NG_L2CAP_PSM_RFCOMM);
1317 	        bcopy(dst, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr));
1318 
1319 		error = soconnect(s->l2so, (struct sockaddr *) &l2sa, td);
1320 		if (error != 0)
1321 			goto bad;
1322 	}
1323 
1324 done:
1325 	LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sessions, s, next);
1326 	*sp = s;
1327 
1328 	mtx_unlock(&s->session_mtx);
1329 
1330 	return (0);
1331 
1332 bad:
1333 	mtx_unlock(&s->session_mtx);
1334 
1335 	/* Return L2CAP socket back to its original state */
1336 	l2so->so_upcallarg = NULL;
1337 	l2so->so_upcall = NULL;
1338 	SOCKBUF_LOCK(&l2so->so_rcv);
1339 	l2so->so_rcv.sb_flags &= ~SB_UPCALL;
1340 	SOCKBUF_UNLOCK(&l2so->so_rcv);
1341 	SOCKBUF_LOCK(&l2so->so_snd);
1342 	l2so->so_snd.sb_flags &= ~SB_UPCALL;
1343 	SOCKBUF_UNLOCK(&l2so->so_snd);
1344 	l2so->so_state &= ~SS_NBIO;
1345 
1346 	mtx_destroy(&s->session_mtx);
1347 	bzero(s, sizeof(*s));
1348 	FREE(s, M_NETGRAPH_BTSOCKET_RFCOMM);
1349 
1350 	return (error);
1351 } /* ng_btsocket_rfcomm_session_create */
1352 
1353 /*
1354  * Process accept() on RFCOMM session
1355  * XXX FIXME locking for "l2so"?
1356  */
1357 
1358 static int
1359 ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0)
1360 {
1361 	struct socket			*l2so = NULL;
1362 	struct sockaddr_l2cap		*l2sa = NULL;
1363 	ng_btsocket_l2cap_pcb_t		*l2pcb = NULL;
1364 	ng_btsocket_rfcomm_session_p	 s = NULL;
1365 	int				 error = 0;
1366 
1367 	mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED);
1368 	mtx_assert(&s0->session_mtx, MA_OWNED);
1369 
1370 	/* Check if there is a complete L2CAP connection in the queue */
1371 	if ((error = s0->l2so->so_error) != 0) {
1372 		NG_BTSOCKET_RFCOMM_ERR(
1373 "%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error);
1374 		s0->l2so->so_error = 0;
1375 
1376 		return (error);
1377 	}
1378 
1379 	ACCEPT_LOCK();
1380 	if (TAILQ_EMPTY(&s0->l2so->so_comp)) {
1381 		ACCEPT_UNLOCK();
1382 		if (s0->l2so->so_rcv.sb_state & SBS_CANTRCVMORE)
1383 			return (ECONNABORTED);
1384 		return (EWOULDBLOCK);
1385 	}
1386 
1387 	/* Accept incoming L2CAP connection */
1388 	l2so = TAILQ_FIRST(&s0->l2so->so_comp);
1389 	if (l2so == NULL)
1390 		panic("%s: l2so == NULL\n", __func__);
1391 
1392 	TAILQ_REMOVE(&s0->l2so->so_comp, l2so, so_list);
1393 	s0->l2so->so_qlen --;
1394 	l2so->so_qstate &= ~SQ_COMP;
1395 	l2so->so_head = NULL;
1396 	SOCK_LOCK(l2so);
1397 	soref(l2so);
1398 	l2so->so_state |= SS_NBIO;
1399 	SOCK_UNLOCK(l2so);
1400 	ACCEPT_UNLOCK();
1401 
1402 	error = soaccept(l2so, (struct sockaddr **) &l2sa);
1403 	if (error != 0) {
1404 		NG_BTSOCKET_RFCOMM_ERR(
1405 "%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error);
1406 		soclose(l2so);
1407 
1408 		return (error);
1409 	}
1410 
1411 	/*
1412 	 * Check if there is already active RFCOMM session between two devices.
1413 	 * If so then close L2CAP connection. We only support one RFCOMM session
1414 	 * between each pair of devices. Note that here we assume session in any
1415 	 * state. The session even could be in the middle of disconnecting.
1416 	 */
1417 
1418 	l2pcb = so2l2cap_pcb(l2so);
1419 	s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst);
1420 	if (s == NULL) {
1421 		/* Create a new RFCOMM session */
1422 		error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL,
1423 				curthread /* XXX */);
1424 		if (error == 0) {
1425 			mtx_lock(&s->session_mtx);
1426 
1427 			s->flags = 0;
1428 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED;
1429 
1430 			/*
1431 			 * Adjust MTU on incomming connection. Reserve 5 bytes:
1432 			 * RFCOMM frame header, one extra byte for length and
1433 			 * one extra byte for credits.
1434 			 */
1435 
1436 			s->mtu = min(l2pcb->imtu, l2pcb->omtu) -
1437 					sizeof(struct rfcomm_frame_hdr) - 1 - 1;
1438 
1439 			mtx_unlock(&s->session_mtx);
1440 		} else {
1441 			NG_BTSOCKET_RFCOMM_ALERT(
1442 "%s: Failed to create new RFCOMM session, error=%d\n", __func__, error);
1443 
1444 			soclose(l2so);
1445 		}
1446 	} else {
1447 		NG_BTSOCKET_RFCOMM_WARN(
1448 "%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \
1449 "dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n",	__func__,
1450 			l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3],
1451 			l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0],
1452 			l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3],
1453 			l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0],
1454 			s->state, s->flags);
1455 
1456 		error = EBUSY;
1457 		soclose(l2so);
1458 	}
1459 
1460 	return (error);
1461 } /* ng_btsocket_rfcomm_session_accept */
1462 
1463 /*
1464  * Process connect() on RFCOMM session
1465  * XXX FIXME locking for "l2so"?
1466  */
1467 
1468 static int
1469 ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s)
1470 {
1471 	ng_btsocket_l2cap_pcb_p	l2pcb = so2l2cap_pcb(s->l2so);
1472 	int			error;
1473 
1474 	mtx_assert(&s->session_mtx, MA_OWNED);
1475 
1476 	/* First check if connection has failed */
1477 	if ((error = s->l2so->so_error) != 0) {
1478 		s->l2so->so_error = 0;
1479 
1480 		NG_BTSOCKET_RFCOMM_ERR(
1481 "%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n",
1482 			__func__, error, s->state, s->flags);
1483 
1484 		return (error);
1485 	}
1486 
1487 	/* Is connection still in progress? */
1488 	if (s->l2so->so_state & SS_ISCONNECTING)
1489 		return (0);
1490 
1491 	/*
1492 	 * If we got here then we are connected. Send SABM on DLCI 0 to
1493 	 * open multiplexor channel.
1494 	 */
1495 
1496 	if (error == 0) {
1497 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED;
1498 
1499 		/*
1500 		 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM
1501 		 * frame header, one extra byte for length and one extra byte
1502 		 * for credits.
1503 		 */
1504 
1505 		s->mtu = min(l2pcb->imtu, l2pcb->omtu) -
1506 				sizeof(struct rfcomm_frame_hdr) - 1 - 1;
1507 
1508 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0);
1509 		if (error == 0)
1510 			error = ng_btsocket_rfcomm_task_wakeup();
1511 	}
1512 
1513 	return (error);
1514 }/* ng_btsocket_rfcomm_session_connect */
1515 
1516 /*
1517  * Receive data on RFCOMM session
1518  * XXX FIXME locking for "l2so"?
1519  */
1520 
1521 static int
1522 ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s)
1523 {
1524 	struct mbuf	*m = NULL;
1525 	struct uio	 uio;
1526 	int		 more, flags, error;
1527 
1528 	mtx_assert(&s->session_mtx, MA_OWNED);
1529 
1530 	/* Can we read from the L2CAP socket? */
1531 	if (!soreadable(s->l2so))
1532 		return (0);
1533 
1534 	/* First check for error on L2CAP socket */
1535 	if ((error = s->l2so->so_error) != 0) {
1536 		s->l2so->so_error = 0;
1537 
1538 		NG_BTSOCKET_RFCOMM_ERR(
1539 "%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n",
1540 			__func__, error, s->state, s->flags);
1541 
1542 		return (error);
1543 	}
1544 
1545 	/*
1546 	 * Read all packets from the L2CAP socket.
1547 	 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as
1548 	 * indication that there is more packets on the socket's buffer.
1549 	 * Also what should we use in uio.uio_resid?
1550 	 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1?
1551 	 */
1552 
1553 	for (more = 1; more; ) {
1554 		/* Try to get next packet from socket */
1555 		bzero(&uio, sizeof(uio));
1556 /*		uio.uio_td = NULL; */
1557 		uio.uio_resid = 1000000000;
1558 		flags = MSG_DONTWAIT;
1559 
1560 		m = NULL;
1561 		error = soreceive(s->l2so, NULL, &uio, &m,
1562 		    (struct mbuf **) NULL, &flags);
1563 		if (error != 0) {
1564 			if (error == EWOULDBLOCK)
1565 				return (0); /* XXX can happen? */
1566 
1567 			NG_BTSOCKET_RFCOMM_ERR(
1568 "%s: Could not receive data from L2CAP socket, error=%d\n", __func__, error);
1569 
1570 			return (error);
1571 		}
1572 
1573 		more = (m->m_nextpkt != NULL);
1574 		m->m_nextpkt = NULL;
1575 
1576 		ng_btsocket_rfcomm_receive_frame(s, m);
1577 	}
1578 
1579 	return (0);
1580 } /* ng_btsocket_rfcomm_session_receive */
1581 
1582 /*
1583  * Send data on RFCOMM session
1584  * XXX FIXME locking for "l2so"?
1585  */
1586 
1587 static int
1588 ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s)
1589 {
1590 	struct mbuf	*m = NULL;
1591 	int		 error;
1592 
1593 	mtx_assert(&s->session_mtx, MA_OWNED);
1594 
1595 	/* Send as much as we can from the session queue */
1596 	while (sowriteable(s->l2so)) {
1597 		/* Check if socket still OK */
1598 		if ((error = s->l2so->so_error) != 0) {
1599 			s->l2so->so_error = 0;
1600 
1601 			NG_BTSOCKET_RFCOMM_ERR(
1602 "%s: Detected error=%d on L2CAP socket, state=%d, flags=%#x\n",
1603 				__func__, error, s->state, s->flags);
1604 
1605 			return (error);
1606 		}
1607 
1608 		NG_BT_MBUFQ_DEQUEUE(&s->outq, m);
1609 		if (m == NULL)
1610 			return (0); /* we are done */
1611 
1612 		/* Call send function on the L2CAP socket */
1613 		error = sosend(s->l2so, NULL, NULL, m, NULL, 0,
1614 		    curthread /* XXX */);
1615 		if (error != 0) {
1616 			NG_BTSOCKET_RFCOMM_ERR(
1617 "%s: Could not send data to L2CAP socket, error=%d\n", __func__, error);
1618 
1619 			return (error);
1620 		}
1621 	}
1622 
1623 	return (0);
1624 } /* ng_btsocket_rfcomm_session_send */
1625 
1626 /*
1627  * Close and disconnect all DLCs for the given session. Caller must hold
1628  * s->sesson_mtx. Will wakeup session.
1629  */
1630 
1631 static void
1632 ng_btsocket_rfcomm_session_clean(ng_btsocket_rfcomm_session_p s)
1633 {
1634 	ng_btsocket_rfcomm_pcb_p	 pcb = NULL, pcb_next = NULL;
1635 	struct socket			*so = NULL;
1636 	int				 error;
1637 
1638 	mtx_assert(&s->session_mtx, MA_OWNED);
1639 
1640 	/*
1641 	 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill
1642 	 * will unlink DLC from the session
1643 	 */
1644 
1645 	for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) {
1646 		mtx_lock(&pcb->pcb_mtx);
1647 		pcb_next = LIST_NEXT(pcb, session_next);
1648 
1649 		NG_BTSOCKET_RFCOMM_INFO(
1650 "%s: Disconnecting dlci=%d, state=%d, flags=%#x\n",
1651 			__func__, pcb->dlci, pcb->state, pcb->flags);
1652 
1653 		if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED)
1654 			error = ECONNRESET;
1655 		else
1656 			error = ECONNREFUSED;
1657 
1658 		if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
1659 			so = pcb->so;
1660 		else
1661 			so = NULL;
1662 
1663 		mtx_unlock(&pcb->pcb_mtx);
1664 		pcb = pcb_next;
1665 
1666 		if (so != NULL)
1667 			ng_btsocket_rfcomm_detach(so);
1668 	}
1669 } /* ng_btsocket_rfcomm_session_clean */
1670 
1671 /*
1672  * Process all DLCs on the session. Caller MUST hold s->session_mtx.
1673  */
1674 
1675 static void
1676 ng_btsocket_rfcomm_session_process_pcb(ng_btsocket_rfcomm_session_p s)
1677 {
1678 	ng_btsocket_rfcomm_pcb_p	 pcb = NULL, pcb_next = NULL;
1679 	struct socket			*so = NULL;
1680 	int				 error;
1681 
1682 	mtx_assert(&s->session_mtx, MA_OWNED);
1683 
1684 	/*
1685 	 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill
1686 	 * will unlink DLC from the session
1687 	 */
1688 
1689 	for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) {
1690 		so = NULL;
1691 
1692 		mtx_lock(&pcb->pcb_mtx);
1693 		pcb_next = LIST_NEXT(pcb, session_next);
1694 
1695 		switch (pcb->state) {
1696 
1697 		/*
1698 		 * If DLC in W4_CONNECT state then we should check for both
1699 		 * timeout and detach.
1700 		 */
1701 
1702 		case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT:
1703 			if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_DETACHED) {
1704 				if (ng_btsocket_rfcomm_pcb_kill(pcb, 0))
1705 					so = pcb->so;
1706 			} else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT)
1707 				if (ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT))
1708 					so = pcb->so;
1709 			break;
1710 
1711 		/*
1712 		 * If DLC in CONFIGURING or CONNECTING state then we only
1713 		 * should check for timeout. If detach() was called then
1714 		 * DLC will be moved into DISCONNECTING state.
1715 		 */
1716 
1717 		case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING:
1718 		case NG_BTSOCKET_RFCOMM_DLC_CONNECTING:
1719 			if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT)
1720 				if (ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT))
1721 					so = pcb->so;
1722 			break;
1723 
1724 		/*
1725 		 * If DLC in CONNECTED state then we need to send data (if any)
1726 		 * from the socket's send queue. Note that we will send data
1727 		 * from either all sockets or none. This may overload session's
1728 		 * outgoing queue (but we do not check for that).
1729 		 *
1730  		 * XXX FIXME need scheduler for RFCOMM sockets
1731 		 */
1732 
1733 		case NG_BTSOCKET_RFCOMM_DLC_CONNECTED:
1734 			error = ng_btsocket_rfcomm_pcb_send(pcb, ALOT);
1735 			if (error != 0)
1736 				if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
1737 					so = pcb->so;
1738 			break;
1739 
1740 		/*
1741 		 * If DLC in DISCONNECTING state then we must send DISC frame.
1742 		 * Note that if DLC has timeout set then we do not need to
1743 		 * resend DISC frame.
1744 		 *
1745 		 * XXX FIXME need to drain all data from the socket's queue
1746 		 * if LINGER option was set
1747 		 */
1748 
1749 		case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING:
1750 			if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) {
1751 				error = ng_btsocket_rfcomm_send_command(
1752 						pcb->session, RFCOMM_FRAME_DISC,
1753 						pcb->dlci);
1754 				if (error == 0)
1755 					ng_btsocket_rfcomm_timeout(pcb);
1756 				else if (ng_btsocket_rfcomm_pcb_kill(pcb,error))
1757 					so = pcb->so;
1758 			} else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT)
1759 				if (ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT))
1760 					so = pcb->so;
1761 			break;
1762 
1763 /*		case NG_BTSOCKET_RFCOMM_DLC_CLOSED: */
1764 		default:
1765 			panic("%s: Invalid DLC state=%d, flags=%#x\n",
1766 				__func__, pcb->state, pcb->flags);
1767 			break;
1768 		}
1769 
1770 		mtx_unlock(&pcb->pcb_mtx);
1771 		pcb = pcb_next;
1772 
1773 		if (so != NULL)
1774 			ng_btsocket_rfcomm_detach(so);
1775 	}
1776 } /* ng_btsocket_rfcomm_session_process_pcb */
1777 
1778 /*
1779  * Find RFCOMM session between "src" and "dst".
1780  * Caller MUST hold ng_btsocket_rfcomm_sessions_mtx.
1781  */
1782 
1783 static ng_btsocket_rfcomm_session_p
1784 ng_btsocket_rfcomm_session_by_addr(bdaddr_p src, bdaddr_p dst)
1785 {
1786 	ng_btsocket_rfcomm_session_p	s = NULL;
1787 	ng_btsocket_l2cap_pcb_p		l2pcb = NULL;
1788 	int				any_src;
1789 
1790 	mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED);
1791 
1792 	any_src = (bcmp(src, NG_HCI_BDADDR_ANY, sizeof(*src)) == 0);
1793 
1794 	LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) {
1795 		l2pcb = so2l2cap_pcb(s->l2so);
1796 
1797 		if ((any_src || bcmp(&l2pcb->src, src, sizeof(*src)) == 0) &&
1798 		    bcmp(&l2pcb->dst, dst, sizeof(*dst)) == 0)
1799 			break;
1800 	}
1801 
1802 	return (s);
1803 } /* ng_btsocket_rfcomm_session_by_addr */
1804 
1805 /*****************************************************************************
1806  *****************************************************************************
1807  **                                  RFCOMM
1808  *****************************************************************************
1809  *****************************************************************************/
1810 
1811 /*
1812  * Process incoming RFCOMM frame. Caller must hold s->session_mtx.
1813  * XXX FIXME check frame length
1814  */
1815 
1816 static int
1817 ng_btsocket_rfcomm_receive_frame(ng_btsocket_rfcomm_session_p s,
1818 		struct mbuf *m0)
1819 {
1820 	struct rfcomm_frame_hdr	*hdr = NULL;
1821 	struct mbuf		*m = NULL;
1822 	u_int16_t		 length;
1823 	u_int8_t		 dlci, type;
1824 	int			 error = 0;
1825 
1826 	mtx_assert(&s->session_mtx, MA_OWNED);
1827 
1828 	/* Pullup as much as we can into first mbuf (for direct access) */
1829 	length = min(m0->m_pkthdr.len, MHLEN);
1830 	if (m0->m_len < length) {
1831 		if ((m0 = m_pullup(m0, length)) == NULL) {
1832 			NG_BTSOCKET_RFCOMM_ALERT(
1833 "%s: m_pullup(%d) failed\n", __func__, length);
1834 
1835 			return (ENOBUFS);
1836 		}
1837 	}
1838 
1839 	hdr = mtod(m0, struct rfcomm_frame_hdr *);
1840 	dlci = RFCOMM_DLCI(hdr->address);
1841 	type = RFCOMM_TYPE(hdr->control);
1842 
1843 	/* Test EA bit in length. If not set then we have 2 bytes of length */
1844 	if (!RFCOMM_EA(hdr->length)) {
1845 		bcopy(&hdr->length, &length, sizeof(length));
1846 		length = le16toh(length) >> 1;
1847 		m_adj(m0, sizeof(*hdr) + 1);
1848 	} else {
1849 		length = hdr->length >> 1;
1850 		m_adj(m0, sizeof(*hdr));
1851 	}
1852 
1853 	NG_BTSOCKET_RFCOMM_INFO(
1854 "%s: Got frame type=%#x, dlci=%d, length=%d, cr=%d, pf=%d, len=%d\n",
1855 		__func__, type, dlci, length, RFCOMM_CR(hdr->address),
1856 		RFCOMM_PF(hdr->control), m0->m_pkthdr.len);
1857 
1858 	/*
1859 	 * Get FCS (the last byte in the frame)
1860 	 * XXX this will not work if mbuf chain ends with empty mbuf.
1861 	 * XXX let's hope it never happens :)
1862 	 */
1863 
1864 	for (m = m0; m->m_next != NULL; m = m->m_next)
1865 		;
1866 	if (m->m_len <= 0)
1867 		panic("%s: Empty mbuf at the end of the chain, len=%d\n",
1868 			__func__, m->m_len);
1869 
1870 	/*
1871 	 * Check FCS. We only need to calculate FCS on first 2 or 3 bytes
1872 	 * and already m_pullup'ed mbuf chain, so it should be safe.
1873 	 */
1874 
1875 	if (ng_btsocket_rfcomm_check_fcs((u_int8_t *) hdr, type, m->m_data[m->m_len - 1])) {
1876 		NG_BTSOCKET_RFCOMM_ERR(
1877 "%s: Invalid RFCOMM packet. Bad checksum\n", __func__);
1878 		NG_FREE_M(m0);
1879 
1880 		return (EINVAL);
1881 	}
1882 
1883 	m_adj(m0, -1); /* Trim FCS byte */
1884 
1885 	/*
1886 	 * Process RFCOMM frame.
1887 	 *
1888 	 * From TS 07.10 spec
1889 	 *
1890 	 * "... In the case where a SABM or DISC command with the P bit set
1891 	 * to 0 is received then the received frame shall be discarded..."
1892  	 *
1893 	 * "... If a unsolicited DM response is received then the frame shall
1894 	 * be processed irrespective of the P/F setting... "
1895 	 *
1896 	 * "... The station may transmit response frames with the F bit set
1897 	 * to 0 at any opportunity on an asynchronous basis. However, in the
1898 	 * case where a UA response is received with the F bit set to 0 then
1899 	 * the received frame shall be discarded..."
1900 	 *
1901 	 * From Bluetooth spec
1902 	 *
1903 	 * "... When credit based flow control is being used, the meaning of
1904 	 * the P/F bit in the control field of the RFCOMM header is redefined
1905 	 * for UIH frames..."
1906 	 */
1907 
1908 	switch (type) {
1909 	case RFCOMM_FRAME_SABM:
1910 		if (RFCOMM_PF(hdr->control))
1911 			error = ng_btsocket_rfcomm_receive_sabm(s, dlci);
1912 		break;
1913 
1914 	case RFCOMM_FRAME_DISC:
1915 		if (RFCOMM_PF(hdr->control))
1916 			error = ng_btsocket_rfcomm_receive_disc(s, dlci);
1917 		break;
1918 
1919 	case RFCOMM_FRAME_UA:
1920 		if (RFCOMM_PF(hdr->control))
1921 			error = ng_btsocket_rfcomm_receive_ua(s, dlci);
1922 		break;
1923 
1924 	case RFCOMM_FRAME_DM:
1925 		error = ng_btsocket_rfcomm_receive_dm(s, dlci);
1926 		break;
1927 
1928 	case RFCOMM_FRAME_UIH:
1929 		if (dlci == 0)
1930 			error = ng_btsocket_rfcomm_receive_mcc(s, m0);
1931 		else
1932 			error = ng_btsocket_rfcomm_receive_uih(s, dlci,
1933 					RFCOMM_PF(hdr->control), m0);
1934 
1935 		return (error);
1936 		/* NOT REACHED */
1937 
1938 	default:
1939 		NG_BTSOCKET_RFCOMM_ERR(
1940 "%s: Invalid RFCOMM packet. Unknown type=%#x\n", __func__, type);
1941 		error = EINVAL;
1942 		break;
1943 	}
1944 
1945 	NG_FREE_M(m0);
1946 
1947 	return (error);
1948 } /* ng_btsocket_rfcomm_receive_frame */
1949 
1950 /*
1951  * Process RFCOMM SABM frame
1952  */
1953 
1954 static int
1955 ng_btsocket_rfcomm_receive_sabm(ng_btsocket_rfcomm_session_p s, int dlci)
1956 {
1957 	ng_btsocket_rfcomm_pcb_p	 pcb = NULL;
1958 	struct socket			*so = NULL;
1959 	int				 error = 0;
1960 
1961 	mtx_assert(&s->session_mtx, MA_OWNED);
1962 
1963 	NG_BTSOCKET_RFCOMM_INFO(
1964 "%s: Got SABM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n",
1965 		__func__, s->state, s->flags, s->mtu, dlci);
1966 
1967 	/* DLCI == 0 means open multiplexor channel */
1968 	if (dlci == 0) {
1969 		switch (s->state) {
1970 		case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
1971 		case NG_BTSOCKET_RFCOMM_SESSION_OPEN:
1972 			error = ng_btsocket_rfcomm_send_command(s,
1973 					RFCOMM_FRAME_UA, dlci);
1974 			if (error == 0) {
1975 				s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN;
1976 				ng_btsocket_rfcomm_connect_cfm(s);
1977 			} else {
1978 				s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1979 				ng_btsocket_rfcomm_session_clean(s);
1980 			}
1981 			break;
1982 
1983 		default:
1984 			NG_BTSOCKET_RFCOMM_WARN(
1985 "%s: Got SABM for session in invalid state state=%d, flags=%#x\n",
1986 				__func__, s->state, s->flags);
1987 			error = EINVAL;
1988 			break;
1989 		}
1990 
1991 		return (error);
1992 	}
1993 
1994 	/* Make sure multiplexor channel is open */
1995 	if (s->state != NG_BTSOCKET_RFCOMM_SESSION_OPEN) {
1996 		NG_BTSOCKET_RFCOMM_ERR(
1997 "%s: Got SABM for dlci=%d with mulitplexor channel closed, state=%d, " \
1998 "flags=%#x\n",		__func__, dlci, s->state, s->flags);
1999 
2000 		return (EINVAL);
2001 	}
2002 
2003 	/*
2004 	 * Check if we have this DLCI. This might happen when remote
2005 	 * peer uses PN command before actual open (SABM) happens.
2006 	 */
2007 
2008 	pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci);
2009 	if (pcb != NULL) {
2010 		mtx_lock(&pcb->pcb_mtx);
2011 
2012 		if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING) {
2013 			NG_BTSOCKET_RFCOMM_ERR(
2014 "%s: Got SABM for dlci=%d in invalid state=%d, flags=%#x\n",
2015 				__func__, dlci, pcb->state, pcb->flags);
2016 			mtx_unlock(&pcb->pcb_mtx);
2017 
2018 			return (ENOENT);
2019 		}
2020 
2021 		ng_btsocket_rfcomm_untimeout(pcb);
2022 
2023 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci);
2024 		if (error == 0)
2025 			error = ng_btsocket_rfcomm_send_msc(pcb);
2026 
2027 		if (error == 0) {
2028 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED;
2029 			soisconnected(pcb->so);
2030 		} else if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
2031 			so = pcb->so;
2032 
2033 		mtx_unlock(&pcb->pcb_mtx);
2034 
2035 		if (so != NULL)
2036 			ng_btsocket_rfcomm_detach(so);
2037 
2038 		return (error);
2039 	}
2040 
2041 	/*
2042 	 * We do not have requested DLCI, so it must be an incoming connection
2043 	 * with default parameters. Try to accept it.
2044 	 */
2045 
2046 	pcb = ng_btsocket_rfcomm_connect_ind(s, RFCOMM_SRVCHANNEL(dlci));
2047 	if (pcb != NULL) {
2048 		mtx_lock(&pcb->pcb_mtx);
2049 
2050 		pcb->dlci = dlci;
2051 
2052 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci);
2053 		if (error == 0)
2054 			error = ng_btsocket_rfcomm_send_msc(pcb);
2055 
2056 		if (error == 0) {
2057 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED;
2058 			soisconnected(pcb->so);
2059 		} else if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
2060 			so = pcb->so;
2061 
2062 		mtx_unlock(&pcb->pcb_mtx);
2063 
2064 		if (so != NULL)
2065 			ng_btsocket_rfcomm_detach(so);
2066 	} else
2067 		/* Nobody is listen()ing on the requested DLCI */
2068 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci);
2069 
2070 	return (error);
2071 } /* ng_btsocket_rfcomm_receive_sabm */
2072 
2073 /*
2074  * Process RFCOMM DISC frame
2075  */
2076 
2077 static int
2078 ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci)
2079 {
2080 	ng_btsocket_rfcomm_pcb_p	pcb = NULL;
2081 	int				error = 0;
2082 
2083 	mtx_assert(&s->session_mtx, MA_OWNED);
2084 
2085 	NG_BTSOCKET_RFCOMM_INFO(
2086 "%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n",
2087 		__func__, s->state, s->flags, s->mtu, dlci);
2088 
2089 	/* DLCI == 0 means close multiplexor channel */
2090 	if (dlci == 0) {
2091 		/* XXX FIXME assume that remote side will close the socket */
2092 		error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0);
2093 		if (error == 0) {
2094 			if (s->state == NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING)
2095 				s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */
2096 			else
2097 				s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING;
2098 		} else
2099 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */
2100 
2101 		ng_btsocket_rfcomm_session_clean(s);
2102 	} else {
2103 		pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci);
2104 		if (pcb != NULL) {
2105 			struct socket	*so = NULL;
2106 			int		 err;
2107 
2108 			mtx_lock(&pcb->pcb_mtx);
2109 
2110 			NG_BTSOCKET_RFCOMM_INFO(
2111 "%s: Got DISC for dlci=%d, state=%d, flags=%#x\n",
2112 				__func__, dlci, pcb->state, pcb->flags);
2113 
2114 			error = ng_btsocket_rfcomm_send_command(s,
2115 					RFCOMM_FRAME_UA, dlci);
2116 
2117 			if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED)
2118 				err = 0;
2119 			else
2120 				err = ECONNREFUSED;
2121 
2122 			if (ng_btsocket_rfcomm_pcb_kill(pcb, err))
2123 				so = pcb->so;
2124 
2125 			mtx_unlock(&pcb->pcb_mtx);
2126 
2127 			if (so != NULL)
2128 				ng_btsocket_rfcomm_detach(so);
2129 		} else {
2130 			NG_BTSOCKET_RFCOMM_WARN(
2131 "%s: Got DISC for non-existing dlci=%d\n", __func__, dlci);
2132 
2133 			error = ng_btsocket_rfcomm_send_command(s,
2134 					RFCOMM_FRAME_DM, dlci);
2135 		}
2136 	}
2137 
2138 	return (error);
2139 } /* ng_btsocket_rfcomm_receive_disc */
2140 
2141 /*
2142  * Process RFCOMM UA frame
2143  */
2144 
2145 static int
2146 ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci)
2147 {
2148 	ng_btsocket_rfcomm_pcb_p	pcb = NULL;
2149 	int				error = 0;
2150 
2151 	mtx_assert(&s->session_mtx, MA_OWNED);
2152 
2153 	NG_BTSOCKET_RFCOMM_INFO(
2154 "%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n",
2155 		__func__, s->state, s->flags, s->mtu, dlci);
2156 
2157 	/* dlci == 0 means multiplexor channel */
2158 	if (dlci == 0) {
2159 		switch (s->state) {
2160 		case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
2161 			s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN;
2162 			ng_btsocket_rfcomm_connect_cfm(s);
2163 			break;
2164 
2165 		case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING:
2166 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
2167 			ng_btsocket_rfcomm_session_clean(s);
2168 			break;
2169 
2170 		default:
2171 			NG_BTSOCKET_RFCOMM_WARN(
2172 "%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n",
2173 				__func__, s->state, INITIATOR(s), s->flags,
2174 				s->mtu);
2175 			error = ENOENT;
2176 			break;
2177 		}
2178 
2179 		return (error);
2180 	}
2181 
2182 	/* Check if we have this DLCI */
2183 	pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci);
2184 	if (pcb != NULL) {
2185 		struct socket	*so = NULL;
2186 
2187 		mtx_lock(&pcb->pcb_mtx);
2188 
2189 		NG_BTSOCKET_RFCOMM_INFO(
2190 "%s: Got UA for dlci=%d, state=%d, flags=%#x\n",
2191 			__func__, dlci, pcb->state, pcb->flags);
2192 
2193 		switch (pcb->state) {
2194 		case NG_BTSOCKET_RFCOMM_DLC_CONNECTING:
2195 			ng_btsocket_rfcomm_untimeout(pcb);
2196 
2197 			error = ng_btsocket_rfcomm_send_msc(pcb);
2198 			if (error == 0) {
2199 				pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED;
2200 				soisconnected(pcb->so);
2201 			}
2202 			break;
2203 
2204 		case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING:
2205 			if (ng_btsocket_rfcomm_pcb_kill(pcb, 0))
2206 				so = pcb->so;
2207 			break;
2208 
2209 		default:
2210 			NG_BTSOCKET_RFCOMM_WARN(
2211 "%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n",
2212 				__func__, dlci, pcb->state, pcb->flags);
2213 			error = ENOENT;
2214 			break;
2215 		}
2216 
2217 		mtx_unlock(&pcb->pcb_mtx);
2218 
2219 		if (so != NULL)
2220 			ng_btsocket_rfcomm_detach(so);
2221 	} else {
2222 		NG_BTSOCKET_RFCOMM_WARN(
2223 "%s: Got UA for non-existing dlci=%d\n", __func__, dlci);
2224 
2225 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci);
2226 	}
2227 
2228 	return (error);
2229 } /* ng_btsocket_rfcomm_receive_ua */
2230 
2231 /*
2232  * Process RFCOMM DM frame
2233  */
2234 
2235 static int
2236 ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci)
2237 {
2238 	ng_btsocket_rfcomm_pcb_p	pcb = NULL;
2239 	int				error;
2240 
2241 	mtx_assert(&s->session_mtx, MA_OWNED);
2242 
2243 	NG_BTSOCKET_RFCOMM_INFO(
2244 "%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n",
2245 		__func__, s->state, s->flags, s->mtu, dlci);
2246 
2247 	/* DLCI == 0 means multiplexor channel */
2248 	if (dlci == 0) {
2249 		/* Disconnect all dlc's on the session */
2250 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
2251 		ng_btsocket_rfcomm_session_clean(s);
2252 	} else {
2253 		pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci);
2254 		if (pcb != NULL) {
2255 			struct socket	*so = NULL;
2256 
2257 			mtx_lock(&pcb->pcb_mtx);
2258 
2259 			NG_BTSOCKET_RFCOMM_INFO(
2260 "%s: Got DM for dlci=%d, state=%d, flags=%#x\n",
2261 				__func__, dlci, pcb->state, pcb->flags);
2262 
2263 			if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED)
2264 				error = ECONNRESET;
2265 			else
2266 				error = ECONNREFUSED;
2267 
2268 			if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
2269 				so = pcb->so;
2270 
2271 			mtx_unlock(&pcb->pcb_mtx);
2272 
2273 			if (so != NULL)
2274 				ng_btsocket_rfcomm_detach(so);
2275 		} else
2276 			NG_BTSOCKET_RFCOMM_WARN(
2277 "%s: Got DM for non-existing dlci=%d\n", __func__, dlci);
2278 	}
2279 
2280 	return (0);
2281 } /* ng_btsocket_rfcomm_receive_dm */
2282 
2283 /*
2284  * Process RFCOMM UIH frame (data)
2285  */
2286 
2287 static int
2288 ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci,
2289 		int pf, struct mbuf *m0)
2290 {
2291 	ng_btsocket_rfcomm_pcb_p	pcb = NULL;
2292 	int				error = 0;
2293 
2294 	mtx_assert(&s->session_mtx, MA_OWNED);
2295 
2296 	NG_BTSOCKET_RFCOMM_INFO(
2297 "%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n",
2298 		__func__, s->state, s->flags, s->mtu, dlci, pf,
2299 		m0->m_pkthdr.len);
2300 
2301 	/* XXX should we do it here? Check for session flow control */
2302 	if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) {
2303 		NG_BTSOCKET_RFCOMM_WARN(
2304 "%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n",
2305 			__func__, s->state, s->flags);
2306 		goto drop;
2307 	}
2308 
2309 	/* Check if we have this dlci */
2310 	pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci);
2311 	if (pcb == NULL) {
2312 		NG_BTSOCKET_RFCOMM_WARN(
2313 "%s: Got UIH for non-existing dlci=%d\n", __func__, dlci);
2314 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci);
2315 		goto drop;
2316 	}
2317 
2318 	mtx_lock(&pcb->pcb_mtx);
2319 
2320 	/* Check dlci state */
2321 	if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) {
2322 		NG_BTSOCKET_RFCOMM_WARN(
2323 "%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n",
2324 			__func__, dlci, pcb->state, pcb->flags);
2325 		error = EINVAL;
2326 		goto drop1;
2327 	}
2328 
2329 	/* Check dlci flow control */
2330 	if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) ||
2331 	     (pcb->lmodem & RFCOMM_MODEM_FC)) {
2332 		NG_BTSOCKET_RFCOMM_ERR(
2333 "%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \
2334 "flags=%#x, rx_cred=%d, lmodem=%#x\n",
2335 			__func__, dlci, pcb->state, pcb->flags,
2336 			pcb->rx_cred, pcb->lmodem);
2337 		goto drop1;
2338 	}
2339 
2340 	/* Did we get any credits? */
2341 	if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) {
2342 		NG_BTSOCKET_RFCOMM_INFO(
2343 "%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \
2344 "rx_cred=%d, tx_cred=%d\n",
2345 			__func__, *mtod(m0, u_int8_t *), dlci, pcb->state,
2346 			pcb->flags, pcb->rx_cred, pcb->tx_cred);
2347 
2348 		pcb->tx_cred += *mtod(m0, u_int8_t *);
2349 		m_adj(m0, 1);
2350 
2351 		/* Send more from the DLC. XXX check for errors? */
2352 		ng_btsocket_rfcomm_pcb_send(pcb, ALOT);
2353 	}
2354 
2355 	/* OK the of the rest of the mbuf is the data */
2356 	if (m0->m_pkthdr.len > 0) {
2357 		/* If we are using credit flow control decrease rx_cred here */
2358 		if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) {
2359 			/* Give remote peer more credits (if needed) */
2360 			if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2)
2361 				ng_btsocket_rfcomm_send_credits(pcb);
2362 			else
2363 				NG_BTSOCKET_RFCOMM_INFO(
2364 "%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \
2365 "rx_cred=%d, tx_cred=%d\n",		__func__, dlci, pcb->state, pcb->flags,
2366 					pcb->rx_cred, pcb->tx_cred);
2367 		}
2368 
2369 		/* Check packet against mtu on dlci */
2370 		if (m0->m_pkthdr.len > pcb->mtu) {
2371 			NG_BTSOCKET_RFCOMM_ERR(
2372 "%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n",
2373 				__func__, dlci, pcb->state, pcb->flags,
2374 				pcb->mtu, m0->m_pkthdr.len);
2375 
2376 			error = EMSGSIZE;
2377 		} else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) {
2378 
2379 			/*
2380 			 * This is really bad. Receive queue on socket does
2381 			 * not have enough space for the packet. We do not
2382 			 * have any other choice but drop the packet.
2383 			 */
2384 
2385 			NG_BTSOCKET_RFCOMM_ERR(
2386 "%s: Not enough space in socket receive queue. Dropping UIH for dlci=%d, " \
2387 "state=%d, flags=%#x, len=%d, space=%ld\n",
2388 				__func__, dlci, pcb->state, pcb->flags,
2389 				m0->m_pkthdr.len, sbspace(&pcb->so->so_rcv));
2390 
2391 			error = ENOBUFS;
2392 		} else {
2393 			/* Append packet to the socket receive queue */
2394 			sbappend(&pcb->so->so_rcv, m0);
2395 			m0 = NULL;
2396 
2397 			sorwakeup(pcb->so);
2398 		}
2399 	}
2400 drop1:
2401 	mtx_unlock(&pcb->pcb_mtx);
2402 drop:
2403 	NG_FREE_M(m0); /* checks for != NULL */
2404 
2405 	return (error);
2406 } /* ng_btsocket_rfcomm_receive_uih */
2407 
2408 /*
2409  * Process RFCOMM MCC command (Multiplexor)
2410  *
2411  * From TS 07.10 spec
2412  *
2413  * "5.4.3.1 Information Data
2414  *
2415  *  ...The frames (UIH) sent by the initiating station have the C/R bit set
2416  *  to 1 and those sent by the responding station have the C/R bit set to 0..."
2417  *
2418  * "5.4.6.2 Operating procedures
2419  *
2420  *  Messages always exist in pairs; a command message and a corresponding
2421  *  response message. If the C/R bit is set to 1 the message is a command,
2422  *  if it is set to 0 the message is a response...
2423  *
2424  *  ...
2425  *
2426  *  NOTE: Notice that when UIH frames are used to convey information on DLCI 0
2427  *  there are at least two different fields that contain a C/R bit, and the
2428  *  bits are set of different form. The C/R bit in the Type field shall be set
2429  *  as it is stated above, while the C/R bit in the Address field (see subclause
2430  *  5.2.1.2) shall be set as it is described in subclause 5.4.3.1."
2431  */
2432 
2433 static int
2434 ng_btsocket_rfcomm_receive_mcc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2435 {
2436 	struct rfcomm_mcc_hdr	*hdr = NULL;
2437 	u_int8_t		 cr, type, length;
2438 
2439 	mtx_assert(&s->session_mtx, MA_OWNED);
2440 
2441 	/*
2442 	 * We can access data directly in the first mbuf, because we have
2443 	 * m_pullup()'ed mbuf chain in ng_btsocket_rfcomm_receive_frame().
2444 	 * All MCC commands should fit into single mbuf (except probably TEST).
2445 	 */
2446 
2447 	hdr = mtod(m0, struct rfcomm_mcc_hdr *);
2448 	cr = RFCOMM_CR(hdr->type);
2449 	type = RFCOMM_MCC_TYPE(hdr->type);
2450 	length = RFCOMM_MCC_LENGTH(hdr->length);
2451 
2452 	/* Check MCC frame length */
2453 	if (sizeof(*hdr) + length != m0->m_pkthdr.len) {
2454 		NG_BTSOCKET_RFCOMM_ERR(
2455 "%s: Invalid MCC frame length=%d, len=%d\n",
2456 			__func__, length, m0->m_pkthdr.len);
2457 		NG_FREE_M(m0);
2458 
2459 		return (EMSGSIZE);
2460 	}
2461 
2462 	switch (type) {
2463 	case RFCOMM_MCC_TEST:
2464 		return (ng_btsocket_rfcomm_receive_test(s, m0));
2465 		/* NOT REACHED */
2466 
2467 	case RFCOMM_MCC_FCON:
2468 	case RFCOMM_MCC_FCOFF:
2469 		return (ng_btsocket_rfcomm_receive_fc(s, m0));
2470 		/* NOT REACHED */
2471 
2472 	case RFCOMM_MCC_MSC:
2473 		return (ng_btsocket_rfcomm_receive_msc(s, m0));
2474 		/* NOT REACHED */
2475 
2476 	case RFCOMM_MCC_RPN:
2477 		return (ng_btsocket_rfcomm_receive_rpn(s, m0));
2478 		/* NOT REACHED */
2479 
2480 	case RFCOMM_MCC_RLS:
2481 		return (ng_btsocket_rfcomm_receive_rls(s, m0));
2482 		/* NOT REACHED */
2483 
2484 	case RFCOMM_MCC_PN:
2485 		return (ng_btsocket_rfcomm_receive_pn(s, m0));
2486 		/* NOT REACHED */
2487 
2488 	case RFCOMM_MCC_NSC:
2489 		NG_BTSOCKET_RFCOMM_ERR(
2490 "%s: Got MCC NSC, type=%#x, cr=%d, length=%d, session state=%d, flags=%#x, " \
2491 "mtu=%d, len=%d\n",	__func__, RFCOMM_MCC_TYPE(*((u_int8_t *)(hdr + 1))), cr,
2492 			 length, s->state, s->flags, s->mtu, m0->m_pkthdr.len);
2493 		NG_FREE_M(m0);
2494 		break;
2495 
2496 	default:
2497 		NG_BTSOCKET_RFCOMM_ERR(
2498 "%s: Got unknown MCC, type=%#x, cr=%d, length=%d, session state=%d, " \
2499 "flags=%#x, mtu=%d, len=%d\n",
2500 			__func__, type, cr, length, s->state, s->flags,
2501 			s->mtu, m0->m_pkthdr.len);
2502 
2503 		/* Reuse mbuf to send NSC */
2504 		hdr = mtod(m0, struct rfcomm_mcc_hdr *);
2505 		m0->m_pkthdr.len = m0->m_len = sizeof(*hdr);
2506 
2507 		/* Create MCC NSC header */
2508 		hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_NSC);
2509 		hdr->length = RFCOMM_MKLEN8(1);
2510 
2511 		/* Put back MCC command type we did not like */
2512 		m0->m_data[m0->m_len] = RFCOMM_MKMCC_TYPE(cr, type);
2513 		m0->m_pkthdr.len ++;
2514 		m0->m_len ++;
2515 
2516 		/* Send UIH frame */
2517 		return (ng_btsocket_rfcomm_send_uih(s,
2518 				RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0));
2519 		/* NOT REACHED */
2520 	}
2521 
2522 	return (0);
2523 } /* ng_btsocket_rfcomm_receive_mcc */
2524 
2525 /*
2526  * Receive RFCOMM TEST MCC command
2527  */
2528 
2529 static int
2530 ng_btsocket_rfcomm_receive_test(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2531 {
2532 	struct rfcomm_mcc_hdr	*hdr = mtod(m0, struct rfcomm_mcc_hdr *);
2533 	int			 error = 0;
2534 
2535 	mtx_assert(&s->session_mtx, MA_OWNED);
2536 
2537 	NG_BTSOCKET_RFCOMM_INFO(
2538 "%s: Got MCC TEST, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \
2539 "len=%d\n",	__func__, RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length),
2540 		s->state, s->flags, s->mtu, m0->m_pkthdr.len);
2541 
2542 	if (RFCOMM_CR(hdr->type)) {
2543 		hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_TEST);
2544 		error = ng_btsocket_rfcomm_send_uih(s,
2545 				RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0);
2546 	} else
2547 		NG_FREE_M(m0); /* XXX ignore response */
2548 
2549 	return (error);
2550 } /* ng_btsocket_rfcomm_receive_test */
2551 
2552 /*
2553  * Receive RFCOMM FCON/FCOFF MCC command
2554  */
2555 
2556 static int
2557 ng_btsocket_rfcomm_receive_fc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2558 {
2559 	struct rfcomm_mcc_hdr	*hdr = mtod(m0, struct rfcomm_mcc_hdr *);
2560 	u_int8_t		 type = RFCOMM_MCC_TYPE(hdr->type);
2561 	int			 error = 0;
2562 
2563 	mtx_assert(&s->session_mtx, MA_OWNED);
2564 
2565 	/*
2566 	 * Turn ON/OFF aggregate flow on the entire session. When remote peer
2567 	 * asserted flow control no transmission shall occur except on dlci 0
2568 	 * (control channel).
2569 	 */
2570 
2571 	NG_BTSOCKET_RFCOMM_INFO(
2572 "%s: Got MCC FC%s, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \
2573 "len=%d\n",	__func__, (type == RFCOMM_MCC_FCON)? "ON" : "OFF",
2574 		RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length),
2575 		s->state, s->flags, s->mtu, m0->m_pkthdr.len);
2576 
2577 	if (RFCOMM_CR(hdr->type)) {
2578 		if (type == RFCOMM_MCC_FCON)
2579 			s->flags &= ~NG_BTSOCKET_RFCOMM_SESSION_RFC;
2580 		else
2581 			s->flags |= NG_BTSOCKET_RFCOMM_SESSION_RFC;
2582 
2583 		hdr->type = RFCOMM_MKMCC_TYPE(0, type);
2584 		error = ng_btsocket_rfcomm_send_uih(s,
2585 				RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0);
2586 	} else
2587 		NG_FREE_M(m0); /* XXX ignore response */
2588 
2589 	return (error);
2590 } /* ng_btsocket_rfcomm_receive_fc  */
2591 
2592 /*
2593  * Receive RFCOMM MSC MCC command
2594  */
2595 
2596 static int
2597 ng_btsocket_rfcomm_receive_msc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2598 {
2599 	struct rfcomm_mcc_hdr		*hdr = mtod(m0, struct rfcomm_mcc_hdr*);
2600 	struct rfcomm_mcc_msc		*msc = (struct rfcomm_mcc_msc *)(hdr+1);
2601 	ng_btsocket_rfcomm_pcb_t	*pcb = NULL;
2602 	int				 error = 0;
2603 
2604 	mtx_assert(&s->session_mtx, MA_OWNED);
2605 
2606 	NG_BTSOCKET_RFCOMM_INFO(
2607 "%s: Got MCC MSC, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \
2608 "mtu=%d, len=%d\n",
2609 		__func__,  RFCOMM_DLCI(msc->address), RFCOMM_CR(hdr->type),
2610 		RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags,
2611 		s->mtu, m0->m_pkthdr.len);
2612 
2613 	if (RFCOMM_CR(hdr->type)) {
2614 		pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, RFCOMM_DLCI(msc->address));
2615 		if (pcb == NULL) {
2616 			NG_BTSOCKET_RFCOMM_WARN(
2617 "%s: Got MSC command for non-existing dlci=%d\n",
2618 				__func__, RFCOMM_DLCI(msc->address));
2619 			NG_FREE_M(m0);
2620 
2621 			return (ENOENT);
2622 		}
2623 
2624 		mtx_lock(&pcb->pcb_mtx);
2625 
2626 		if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING &&
2627 		    pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) {
2628 			NG_BTSOCKET_RFCOMM_WARN(
2629 "%s: Got MSC on dlci=%d in invalid state=%d\n",
2630 				__func__, RFCOMM_DLCI(msc->address),
2631 				pcb->state);
2632 
2633 			mtx_unlock(&pcb->pcb_mtx);
2634 			NG_FREE_M(m0);
2635 
2636 			return (EINVAL);
2637 		}
2638 
2639 		pcb->rmodem = msc->modem; /* Update remote port signals */
2640 
2641 		hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_MSC);
2642 		error = ng_btsocket_rfcomm_send_uih(s,
2643 				RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0);
2644 
2645 #if 0 /* YYY */
2646 		/* Send more data from DLC. XXX check for errors? */
2647 		if (!(pcb->rmodem & RFCOMM_MODEM_FC) &&
2648 		    !(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC))
2649 			ng_btsocket_rfcomm_pcb_send(pcb, ALOT);
2650 #endif /* YYY */
2651 
2652 		mtx_unlock(&pcb->pcb_mtx);
2653 	} else
2654 		NG_FREE_M(m0); /* XXX ignore response */
2655 
2656 	return (error);
2657 } /* ng_btsocket_rfcomm_receive_msc */
2658 
2659 /*
2660  * Receive RFCOMM RPN MCC command
2661  * XXX FIXME do we need htole16/le16toh for RPN param_mask?
2662  */
2663 
2664 static int
2665 ng_btsocket_rfcomm_receive_rpn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2666 {
2667 	struct rfcomm_mcc_hdr	*hdr = mtod(m0, struct rfcomm_mcc_hdr *);
2668 	struct rfcomm_mcc_rpn	*rpn = (struct rfcomm_mcc_rpn *)(hdr + 1);
2669 	int			 error = 0;
2670 	u_int16_t		 param_mask;
2671 	u_int8_t		 bit_rate, data_bits, stop_bits, parity,
2672 				 flow_control, xon_char, xoff_char;
2673 
2674 	mtx_assert(&s->session_mtx, MA_OWNED);
2675 
2676 	NG_BTSOCKET_RFCOMM_INFO(
2677 "%s: Got MCC RPN, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \
2678 "mtu=%d, len=%d\n",
2679 		__func__, RFCOMM_DLCI(rpn->dlci), RFCOMM_CR(hdr->type),
2680 		RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags,
2681 		s->mtu, m0->m_pkthdr.len);
2682 
2683 	if (RFCOMM_CR(hdr->type)) {
2684 		param_mask = RFCOMM_RPN_PM_ALL;
2685 
2686 		if (RFCOMM_MCC_LENGTH(hdr->length) == 1) {
2687 			/* Request - return default setting */
2688 			bit_rate = RFCOMM_RPN_BR_115200;
2689 			data_bits = RFCOMM_RPN_DATA_8;
2690 			stop_bits = RFCOMM_RPN_STOP_1;
2691 			parity = RFCOMM_RPN_PARITY_NONE;
2692 			flow_control = RFCOMM_RPN_FLOW_NONE;
2693 			xon_char = RFCOMM_RPN_XON_CHAR;
2694 			xoff_char = RFCOMM_RPN_XOFF_CHAR;
2695                 } else {
2696 			/*
2697 			 * Ignore/accept bit_rate, 8 bits, 1 stop bit, no
2698 			 * parity, no flow control lines, default XON/XOFF
2699 			 * chars.
2700 			 */
2701 
2702 			bit_rate = rpn->bit_rate;
2703 			rpn->param_mask = le16toh(rpn->param_mask); /* XXX */
2704 
2705 			data_bits = RFCOMM_RPN_DATA_BITS(rpn->line_settings);
2706 			if (rpn->param_mask & RFCOMM_RPN_PM_DATA &&
2707 			    data_bits != RFCOMM_RPN_DATA_8) {
2708 				data_bits = RFCOMM_RPN_DATA_8;
2709 				param_mask ^= RFCOMM_RPN_PM_DATA;
2710 			}
2711 
2712 			stop_bits = RFCOMM_RPN_STOP_BITS(rpn->line_settings);
2713 			if (rpn->param_mask & RFCOMM_RPN_PM_STOP &&
2714 			    stop_bits != RFCOMM_RPN_STOP_1) {
2715 				stop_bits = RFCOMM_RPN_STOP_1;
2716 				param_mask ^= RFCOMM_RPN_PM_STOP;
2717 			}
2718 
2719 			parity = RFCOMM_RPN_PARITY(rpn->line_settings);
2720 			if (rpn->param_mask & RFCOMM_RPN_PM_PARITY &&
2721 			    parity != RFCOMM_RPN_PARITY_NONE) {
2722 				parity = RFCOMM_RPN_PARITY_NONE;
2723 				param_mask ^= RFCOMM_RPN_PM_PARITY;
2724 			}
2725 
2726 			flow_control = rpn->flow_control;
2727 			if (rpn->param_mask & RFCOMM_RPN_PM_FLOW &&
2728 			    flow_control != RFCOMM_RPN_FLOW_NONE) {
2729 				flow_control = RFCOMM_RPN_FLOW_NONE;
2730 				param_mask ^= RFCOMM_RPN_PM_FLOW;
2731 			}
2732 
2733 			xon_char = rpn->xon_char;
2734 			if (rpn->param_mask & RFCOMM_RPN_PM_XON &&
2735 			    xon_char != RFCOMM_RPN_XON_CHAR) {
2736 				xon_char = RFCOMM_RPN_XON_CHAR;
2737 				param_mask ^= RFCOMM_RPN_PM_XON;
2738 			}
2739 
2740 			xoff_char = rpn->xoff_char;
2741 			if (rpn->param_mask & RFCOMM_RPN_PM_XOFF &&
2742 			    xoff_char != RFCOMM_RPN_XOFF_CHAR) {
2743 				xoff_char = RFCOMM_RPN_XOFF_CHAR;
2744 				param_mask ^= RFCOMM_RPN_PM_XOFF;
2745 			}
2746 		}
2747 
2748 		rpn->bit_rate = bit_rate;
2749 		rpn->line_settings = RFCOMM_MKRPN_LINE_SETTINGS(data_bits,
2750 						stop_bits, parity);
2751 		rpn->flow_control = flow_control;
2752 		rpn->xon_char = xon_char;
2753 		rpn->xoff_char = xoff_char;
2754 		rpn->param_mask = htole16(param_mask); /* XXX */
2755 
2756 		m0->m_pkthdr.len = m0->m_len = sizeof(*hdr) + sizeof(*rpn);
2757 
2758 		hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RPN);
2759 		error = ng_btsocket_rfcomm_send_uih(s,
2760 				RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0);
2761 	} else
2762 		NG_FREE_M(m0); /* XXX ignore response */
2763 
2764 	return (error);
2765 } /* ng_btsocket_rfcomm_receive_rpn */
2766 
2767 /*
2768  * Receive RFCOMM RLS MCC command
2769  */
2770 
2771 static int
2772 ng_btsocket_rfcomm_receive_rls(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2773 {
2774 	struct rfcomm_mcc_hdr	*hdr = mtod(m0, struct rfcomm_mcc_hdr *);
2775 	struct rfcomm_mcc_rls	*rls = (struct rfcomm_mcc_rls *)(hdr + 1);
2776 	int			 error = 0;
2777 
2778 	mtx_assert(&s->session_mtx, MA_OWNED);
2779 
2780 	/*
2781 	 * XXX FIXME Do we have to do anything else here? Remote peer tries to
2782 	 * tell us something about DLCI. Just report what we have received and
2783 	 * return back received values as required by TS 07.10 spec.
2784 	 */
2785 
2786 	NG_BTSOCKET_RFCOMM_INFO(
2787 "%s: Got MCC RLS, dlci=%d, status=%#x, cr=%d, length=%d, session state=%d, " \
2788 "flags=%#x, mtu=%d, len=%d\n",
2789 		__func__, RFCOMM_DLCI(rls->address), rls->status,
2790 		RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length),
2791 		s->state, s->flags, s->mtu, m0->m_pkthdr.len);
2792 
2793 	if (RFCOMM_CR(hdr->type)) {
2794 		if (rls->status & 0x1)
2795 			NG_BTSOCKET_RFCOMM_ERR(
2796 "%s: Got RLS dlci=%d, error=%#x\n", __func__, RFCOMM_DLCI(rls->address),
2797 				rls->status >> 1);
2798 
2799 		hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RLS);
2800 		error = ng_btsocket_rfcomm_send_uih(s,
2801 				RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0);
2802 	} else
2803 		NG_FREE_M(m0); /* XXX ignore responses */
2804 
2805 	return (error);
2806 } /* ng_btsocket_rfcomm_receive_rls */
2807 
2808 /*
2809  * Receive RFCOMM PN MCC command
2810  */
2811 
2812 static int
2813 ng_btsocket_rfcomm_receive_pn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0)
2814 {
2815 	struct rfcomm_mcc_hdr		*hdr = mtod(m0, struct rfcomm_mcc_hdr*);
2816 	struct rfcomm_mcc_pn		*pn = (struct rfcomm_mcc_pn *)(hdr+1);
2817 	ng_btsocket_rfcomm_pcb_t	*pcb = NULL;
2818 	int				 error = 0;
2819 
2820 	mtx_assert(&s->session_mtx, MA_OWNED);
2821 
2822 	NG_BTSOCKET_RFCOMM_INFO(
2823 "%s: Got MCC PN, dlci=%d, cr=%d, length=%d, flow_control=%#x, priority=%d, " \
2824 "ack_timer=%d, mtu=%d, max_retrans=%d, credits=%d, session state=%d, " \
2825 "flags=%#x, session mtu=%d, len=%d\n",
2826 		__func__, pn->dlci, RFCOMM_CR(hdr->type),
2827 		RFCOMM_MCC_LENGTH(hdr->length), pn->flow_control, pn->priority,
2828 		pn->ack_timer, le16toh(pn->mtu), pn->max_retrans, pn->credits,
2829 		s->state, s->flags, s->mtu, m0->m_pkthdr.len);
2830 
2831 	if (pn->dlci == 0) {
2832 		NG_BTSOCKET_RFCOMM_ERR("%s: Zero dlci in MCC PN\n", __func__);
2833 		NG_FREE_M(m0);
2834 
2835 		return (EINVAL);
2836 	}
2837 
2838 	/* Check if we have this dlci */
2839 	pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, pn->dlci);
2840 	if (pcb != NULL) {
2841 		mtx_lock(&pcb->pcb_mtx);
2842 
2843 		if (RFCOMM_CR(hdr->type)) {
2844 			/* PN Request */
2845 			ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control,
2846 				pn->credits, pn->mtu);
2847 
2848 			if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) {
2849 				pn->flow_control = 0xe0;
2850 				pn->credits = RFCOMM_DEFAULT_CREDITS;
2851 			} else {
2852 				pn->flow_control = 0;
2853 				pn->credits = 0;
2854 			}
2855 
2856 			hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN);
2857 			error = ng_btsocket_rfcomm_send_uih(s,
2858 					RFCOMM_MKADDRESS(INITIATOR(s), 0),
2859 					0, 0, m0);
2860 		} else {
2861 			/* PN Response - proceed with SABM. Timeout still set */
2862 			if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONFIGURING) {
2863 				ng_btsocket_rfcomm_set_pn(pcb, 0,
2864 					pn->flow_control, pn->credits, pn->mtu);
2865 
2866 				pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING;
2867 				error = ng_btsocket_rfcomm_send_command(s,
2868 						RFCOMM_FRAME_SABM, pn->dlci);
2869 			} else
2870 				NG_BTSOCKET_RFCOMM_WARN(
2871 "%s: Got PN response for dlci=%d in invalid state=%d\n",
2872 					__func__, pn->dlci, pcb->state);
2873 
2874 			NG_FREE_M(m0);
2875 		}
2876 
2877 		mtx_unlock(&pcb->pcb_mtx);
2878 	} else if (RFCOMM_CR(hdr->type)) {
2879 		/* PN request to non-existing dlci - incomming connection */
2880 		pcb = ng_btsocket_rfcomm_connect_ind(s,
2881 				RFCOMM_SRVCHANNEL(pn->dlci));
2882 		if (pcb != NULL) {
2883 			struct socket	*so = NULL;
2884 
2885 			mtx_lock(&pcb->pcb_mtx);
2886 
2887 			pcb->dlci = pn->dlci;
2888 
2889 			ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control,
2890 				pn->credits, pn->mtu);
2891 
2892 			if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) {
2893 				pn->flow_control = 0xe0;
2894 				pn->credits = RFCOMM_DEFAULT_CREDITS;
2895 			} else {
2896 				pn->flow_control = 0;
2897 				pn->credits = 0;
2898 			}
2899 
2900 			hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN);
2901 			error = ng_btsocket_rfcomm_send_uih(s,
2902 					RFCOMM_MKADDRESS(INITIATOR(s), 0),
2903 					0, 0, m0);
2904 
2905 			if (error == 0) {
2906 				ng_btsocket_rfcomm_timeout(pcb);
2907 				pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING;
2908 				soisconnecting(pcb->so);
2909 			} else if (ng_btsocket_rfcomm_pcb_kill(pcb, error))
2910 				so = pcb->so;
2911 
2912 			mtx_unlock(&pcb->pcb_mtx);
2913 
2914 			if (so != NULL)
2915 				ng_btsocket_rfcomm_detach(so);
2916 		} else {
2917 			/* Nobody is listen()ing on this channel */
2918 			error = ng_btsocket_rfcomm_send_command(s,
2919 					RFCOMM_FRAME_DM, pn->dlci);
2920 			NG_FREE_M(m0);
2921 		}
2922 	} else
2923 		NG_FREE_M(m0); /* XXX ignore response to non-existing dlci */
2924 
2925 	return (error);
2926 } /* ng_btsocket_rfcomm_receive_pn */
2927 
2928 /*
2929  * Set PN parameters for dlci. Caller must hold pcb->pcb_mtx.
2930  *
2931  * From Bluetooth spec.
2932  *
2933  * "... The CL1 - CL4 field is completely redefined. (In TS07.10 this defines
2934  *  the convergence layer to use, which is not applicable to RFCOMM. In RFCOMM,
2935  *  in Bluetooth versions up to 1.0B, this field was forced to 0).
2936  *
2937  *  In the PN request sent prior to a DLC establishment, this field must contain
2938  *  the value 15 (0xF), indicating support of credit based flow control in the
2939  *  sender. See Table 5.3 below. If the PN response contains any other value
2940  *  than 14 (0xE) in this field, it is inferred that the peer RFCOMM entity is
2941  *  not supporting the credit based flow control feature. (This is only possible
2942  *  if the peer RFCOMM implementation is only conforming to Bluetooth version
2943  *  1.0B.) If a PN request is sent on an already open DLC, then this field must
2944  *  contain the value zero; it is not possible to set initial credits  more
2945  *  than once per DLC activation. A responding implementation must set this
2946  *  field in the PN response to 14 (0xE), if (and only if) the value in the PN
2947  *  request was 15..."
2948  */
2949 
2950 static void
2951 ng_btsocket_rfcomm_set_pn(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr,
2952 		u_int8_t flow_control, u_int8_t credits, u_int16_t mtu)
2953 {
2954 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
2955 
2956 	pcb->mtu = le16toh(mtu);
2957 
2958 	if (cr) {
2959 		if (flow_control == 0xf0) {
2960 			pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC;
2961 			pcb->tx_cred = credits;
2962 		} else {
2963 			pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC;
2964 			pcb->tx_cred = 0;
2965 		}
2966 	} else {
2967 		if (flow_control == 0xe0) {
2968 			pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC;
2969 			pcb->tx_cred = credits;
2970 		} else {
2971 			pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC;
2972 			pcb->tx_cred = 0;
2973 		}
2974 	}
2975 
2976 	NG_BTSOCKET_RFCOMM_INFO(
2977 "%s: cr=%d, dlci=%d, state=%d, flags=%#x, mtu=%d, rx_cred=%d, tx_cred=%d\n",
2978 		__func__, cr, pcb->dlci, pcb->state, pcb->flags, pcb->mtu,
2979 		pcb->rx_cred, pcb->tx_cred);
2980 } /* ng_btsocket_rfcomm_set_pn */
2981 
2982 /*
2983  * Send RFCOMM SABM/DISC/UA/DM frames. Caller must hold s->session_mtx
2984  */
2985 
2986 static int
2987 ng_btsocket_rfcomm_send_command(ng_btsocket_rfcomm_session_p s,
2988 		u_int8_t type, u_int8_t dlci)
2989 {
2990 	struct rfcomm_cmd_hdr	*hdr = NULL;
2991 	struct mbuf		*m = NULL;
2992 	int			 cr;
2993 
2994 	mtx_assert(&s->session_mtx, MA_OWNED);
2995 
2996 	NG_BTSOCKET_RFCOMM_INFO(
2997 "%s: Sending command type %#x, session state=%d, flags=%#x, mtu=%d, dlci=%d\n",
2998 		__func__, type, s->state, s->flags, s->mtu, dlci);
2999 
3000 	switch (type) {
3001 	case RFCOMM_FRAME_SABM:
3002 	case RFCOMM_FRAME_DISC:
3003 		cr = INITIATOR(s);
3004 		break;
3005 
3006 	case RFCOMM_FRAME_UA:
3007 	case RFCOMM_FRAME_DM:
3008 		cr = !INITIATOR(s);
3009 		break;
3010 
3011 	default:
3012 		panic("%s: Invalid frame type=%#x\n", __func__, type);
3013 		return (EINVAL);
3014 		/* NOT REACHED */
3015 	}
3016 
3017 	MGETHDR(m, M_DONTWAIT, MT_DATA);
3018 	if (m == NULL)
3019 		return (ENOBUFS);
3020 
3021 	m->m_pkthdr.len = m->m_len = sizeof(*hdr);
3022 
3023 	hdr = mtod(m, struct rfcomm_cmd_hdr *);
3024 	hdr->address = RFCOMM_MKADDRESS(cr, dlci);
3025 	hdr->control = RFCOMM_MKCONTROL(type, 1);
3026 	hdr->length = RFCOMM_MKLEN8(0);
3027 	hdr->fcs = ng_btsocket_rfcomm_fcs3((u_int8_t *) hdr);
3028 
3029 	NG_BT_MBUFQ_ENQUEUE(&s->outq, m);
3030 
3031 	return (0);
3032 } /* ng_btsocket_rfcomm_send_command */
3033 
3034 /*
3035  * Send RFCOMM UIH frame. Caller must hold s->session_mtx
3036  */
3037 
3038 static int
3039 ng_btsocket_rfcomm_send_uih(ng_btsocket_rfcomm_session_p s, u_int8_t address,
3040 		u_int8_t pf, u_int8_t credits, struct mbuf *data)
3041 {
3042 	struct rfcomm_frame_hdr	*hdr = NULL;
3043 	struct mbuf		*m = NULL, *mcrc = NULL;
3044 	u_int16_t		 length;
3045 
3046 	mtx_assert(&s->session_mtx, MA_OWNED);
3047 
3048 	MGETHDR(m, M_DONTWAIT, MT_DATA);
3049 	if (m == NULL) {
3050 		NG_FREE_M(data);
3051 		return (ENOBUFS);
3052 	}
3053 	m->m_pkthdr.len = m->m_len = sizeof(*hdr);
3054 
3055 	MGET(mcrc, M_DONTWAIT, MT_DATA);
3056 	if (mcrc == NULL) {
3057 		NG_FREE_M(data);
3058 		return (ENOBUFS);
3059 	}
3060 	mcrc->m_len = 1;
3061 
3062 	/* Fill UIH frame header */
3063 	hdr = mtod(m, struct rfcomm_frame_hdr *);
3064 	hdr->address = address;
3065 	hdr->control = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, pf);
3066 
3067 	/* Calculate FCS */
3068 	mcrc->m_data[0] = ng_btsocket_rfcomm_fcs2((u_int8_t *) hdr);
3069 
3070 	/* Put length back */
3071 	length = (data != NULL)? data->m_pkthdr.len : 0;
3072 	if (length > 127) {
3073 		u_int16_t	l = htole16(RFCOMM_MKLEN16(length));
3074 
3075 		bcopy(&l, &hdr->length, sizeof(l));
3076 		m->m_pkthdr.len ++;
3077 		m->m_len ++;
3078 	} else
3079 		hdr->length = RFCOMM_MKLEN8(length);
3080 
3081 	if (pf) {
3082 		m->m_data[m->m_len] = credits;
3083 		m->m_pkthdr.len ++;
3084 		m->m_len ++;
3085 	}
3086 
3087 	/* Add payload */
3088 	if (data != NULL) {
3089 		m_cat(m, data);
3090 		m->m_pkthdr.len += length;
3091 	}
3092 
3093 	/* Put FCS back */
3094 	m_cat(m, mcrc);
3095 	m->m_pkthdr.len ++;
3096 
3097 	NG_BTSOCKET_RFCOMM_INFO(
3098 "%s: Sending UIH state=%d, flags=%#x, address=%d, length=%d, pf=%d, " \
3099 "credits=%d, len=%d\n",
3100 		__func__, s->state, s->flags, address, length, pf, credits,
3101 		m->m_pkthdr.len);
3102 
3103 	NG_BT_MBUFQ_ENQUEUE(&s->outq, m);
3104 
3105 	return (0);
3106 } /* ng_btsocket_rfcomm_send_uih */
3107 
3108 /*
3109  * Send MSC request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx
3110  */
3111 
3112 static int
3113 ng_btsocket_rfcomm_send_msc(ng_btsocket_rfcomm_pcb_p pcb)
3114 {
3115 	struct mbuf		*m = NULL;
3116 	struct rfcomm_mcc_hdr	*hdr = NULL;
3117 	struct rfcomm_mcc_msc	*msc = NULL;
3118 
3119 	mtx_assert(&pcb->session->session_mtx, MA_OWNED);
3120 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3121 
3122 	MGETHDR(m, M_DONTWAIT, MT_DATA);
3123 	if (m == NULL)
3124 		return (ENOBUFS);
3125 
3126 	m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*msc);
3127 
3128 	hdr = mtod(m, struct rfcomm_mcc_hdr *);
3129 	msc = (struct rfcomm_mcc_msc *)(hdr + 1);
3130 
3131 	hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_MSC);
3132 	hdr->length = RFCOMM_MKLEN8(sizeof(*msc));
3133 
3134 	msc->address = RFCOMM_MKADDRESS(1, pcb->dlci);
3135 	msc->modem = pcb->lmodem;
3136 
3137 	NG_BTSOCKET_RFCOMM_INFO(
3138 "%s: Sending MSC dlci=%d, state=%d, flags=%#x, address=%d, modem=%#x\n",
3139 		__func__, pcb->dlci, pcb->state, pcb->flags, msc->address,
3140 		msc->modem);
3141 
3142 	return (ng_btsocket_rfcomm_send_uih(pcb->session,
3143 			RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m));
3144 } /* ng_btsocket_rfcomm_send_msc */
3145 
3146 /*
3147  * Send PN request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx
3148  */
3149 
3150 static int
3151 ng_btsocket_rfcomm_send_pn(ng_btsocket_rfcomm_pcb_p pcb)
3152 {
3153 	struct mbuf		*m = NULL;
3154 	struct rfcomm_mcc_hdr	*hdr = NULL;
3155 	struct rfcomm_mcc_pn	*pn = NULL;
3156 
3157 	mtx_assert(&pcb->session->session_mtx, MA_OWNED);
3158 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3159 
3160 	MGETHDR(m, M_DONTWAIT, MT_DATA);
3161 	if (m == NULL)
3162 		return (ENOBUFS);
3163 
3164 	m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*pn);
3165 
3166 	hdr = mtod(m, struct rfcomm_mcc_hdr *);
3167 	pn = (struct rfcomm_mcc_pn *)(hdr + 1);
3168 
3169 	hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_PN);
3170 	hdr->length = RFCOMM_MKLEN8(sizeof(*pn));
3171 
3172 	pn->dlci = pcb->dlci;
3173 
3174 	/*
3175 	 * Set default DLCI priority as described in GSM 07.10
3176 	 * (ETSI TS 101 369) clause 5.6 page 42
3177 	 */
3178 
3179 	pn->priority = (pcb->dlci < 56)? (((pcb->dlci >> 3) << 3) + 7) : 61;
3180 	pn->ack_timer = 0;
3181 	pn->mtu = htole16(pcb->mtu);
3182 	pn->max_retrans = 0;
3183 
3184 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) {
3185 		pn->flow_control = 0xf0;
3186 		pn->credits = pcb->rx_cred;
3187 	} else {
3188 		pn->flow_control = 0;
3189 		pn->credits = 0;
3190 	}
3191 
3192 	NG_BTSOCKET_RFCOMM_INFO(
3193 "%s: Sending PN dlci=%d, state=%d, flags=%#x, mtu=%d, flow_control=%#x, " \
3194 "credits=%d\n",	__func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu,
3195 		pn->flow_control, pn->credits);
3196 
3197 	return (ng_btsocket_rfcomm_send_uih(pcb->session,
3198 			RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m));
3199 } /* ng_btsocket_rfcomm_send_pn */
3200 
3201 /*
3202  * Calculate and send credits based on available space in receive buffer
3203  */
3204 
3205 static int
3206 ng_btsocket_rfcomm_send_credits(ng_btsocket_rfcomm_pcb_p pcb)
3207 {
3208 	int		error = 0;
3209 	u_int8_t	credits;
3210 
3211 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3212 	mtx_assert(&pcb->session->session_mtx, MA_OWNED);
3213 
3214 	NG_BTSOCKET_RFCOMM_INFO(
3215 "%s: Sending more credits, dlci=%d, state=%d, flags=%#x, mtu=%d, " \
3216 "space=%ld, tx_cred=%d, rx_cred=%d\n",
3217 		__func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu,
3218 		sbspace(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred);
3219 
3220 	credits = sbspace(&pcb->so->so_rcv) / pcb->mtu;
3221 	if (credits > 0) {
3222 		if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS)
3223 			credits = RFCOMM_MAX_CREDITS - pcb->rx_cred;
3224 
3225 		error = ng_btsocket_rfcomm_send_uih(
3226 				pcb->session,
3227 				RFCOMM_MKADDRESS(INITIATOR(pcb->session),
3228 					pcb->dlci), 1, credits, NULL);
3229 		if (error == 0) {
3230 			pcb->rx_cred += credits;
3231 
3232 			NG_BTSOCKET_RFCOMM_INFO(
3233 "%s: Gave remote side %d more credits, dlci=%d, state=%d, flags=%#x, " \
3234 "rx_cred=%d, tx_cred=%d\n",	__func__, credits, pcb->dlci, pcb->state,
3235 				pcb->flags, pcb->rx_cred, pcb->tx_cred);
3236 		} else
3237 			NG_BTSOCKET_RFCOMM_ERR(
3238 "%s: Could not send credits, error=%d, dlci=%d, state=%d, flags=%#x, " \
3239 "mtu=%d, space=%ld, tx_cred=%d, rx_cred=%d\n",
3240 				__func__, error, pcb->dlci, pcb->state,
3241 				pcb->flags, pcb->mtu, sbspace(&pcb->so->so_rcv),
3242 				pcb->tx_cred, pcb->rx_cred);
3243 	}
3244 
3245 	return (error);
3246 } /* ng_btsocket_rfcomm_send_credits */
3247 
3248 /*****************************************************************************
3249  *****************************************************************************
3250  **                              RFCOMM DLCs
3251  *****************************************************************************
3252  *****************************************************************************/
3253 
3254 /*
3255  * Send data from socket send buffer
3256  * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx
3257  */
3258 
3259 static int
3260 ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit)
3261 {
3262 	struct mbuf	*m = NULL;
3263 	int		 sent, length, error;
3264 
3265 	mtx_assert(&pcb->session->session_mtx, MA_OWNED);
3266 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3267 
3268 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)
3269 		limit = min(limit, pcb->tx_cred);
3270 	else if (!(pcb->rmodem & RFCOMM_MODEM_FC))
3271 		limit = min(limit, RFCOMM_MAX_CREDITS); /* XXX ??? */
3272 	else
3273 		limit = 0;
3274 
3275 	if (limit == 0) {
3276 		NG_BTSOCKET_RFCOMM_INFO(
3277 "%s: Could not send - remote flow control asserted, dlci=%d, flags=%#x, " \
3278 "rmodem=%#x, tx_cred=%d\n",
3279 			__func__, pcb->dlci, pcb->flags, pcb->rmodem,
3280 			pcb->tx_cred);
3281 
3282 		return (0);
3283 	}
3284 
3285 	for (error = 0, sent = 0; sent < limit; sent ++) {
3286 		length = min(pcb->mtu, pcb->so->so_snd.sb_cc);
3287 		if (length == 0)
3288 			break;
3289 
3290 		/* Get the chunk from the socket's send buffer */
3291 		m = ng_btsocket_rfcomm_prepare_packet(&pcb->so->so_snd, length);
3292 		if (m == NULL) {
3293 			error = ENOBUFS;
3294 			break;
3295 		}
3296 
3297 		sbdrop(&pcb->so->so_snd, length);
3298 
3299 		error = ng_btsocket_rfcomm_send_uih(pcb->session,
3300 				RFCOMM_MKADDRESS(INITIATOR(pcb->session),
3301 					pcb->dlci), 0, 0, m);
3302 		if (error != 0)
3303 			break;
3304 	}
3305 
3306 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)
3307 		pcb->tx_cred -= sent;
3308 
3309 	if (error == 0 && sent > 0) {
3310 		pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_SENDING;
3311 		sowwakeup(pcb->so);
3312 	}
3313 
3314 	return (error);
3315 } /* ng_btsocket_rfcomm_pcb_send */
3316 
3317 /*
3318  * Unlink and disconnect DLC. If ng_btsocket_rfcomm_pcb_kill() returns
3319  * non zero value than socket has no reference and has to be detached.
3320  * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx
3321  */
3322 
3323 static int
3324 ng_btsocket_rfcomm_pcb_kill(ng_btsocket_rfcomm_pcb_p pcb, int error)
3325 {
3326 	ng_btsocket_rfcomm_session_p	s = pcb->session;
3327 
3328 	NG_BTSOCKET_RFCOMM_INFO(
3329 "%s: Killing DLC, so=%p, dlci=%d, state=%d, flags=%#x, error=%d\n",
3330 		__func__, pcb->so, pcb->dlci, pcb->state, pcb->flags, error);
3331 
3332 	if (pcb->session == NULL)
3333 		panic("%s: DLC without session, pcb=%p, state=%d, flags=%#x\n",
3334 			__func__, pcb, pcb->state, pcb->flags);
3335 
3336 	mtx_assert(&pcb->session->session_mtx, MA_OWNED);
3337 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3338 
3339 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
3340 		ng_btsocket_rfcomm_untimeout(pcb);
3341 
3342 	/* Detach DLC from the session. Does not matter which state DLC in */
3343 	LIST_REMOVE(pcb, session_next);
3344 	pcb->session = NULL;
3345 
3346 	/* Change DLC state and wakeup all sleepers */
3347 	pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED;
3348 	pcb->so->so_error = error;
3349 	soisdisconnected(pcb->so);
3350 	wakeup(&pcb->state);
3351 
3352 	/* Check if we have any DLCs left on the session */
3353 	if (LIST_EMPTY(&s->dlcs) && INITIATOR(s)) {
3354 		NG_BTSOCKET_RFCOMM_INFO(
3355 "%s: Disconnecting session, state=%d, flags=%#x, mtu=%d\n",
3356 			__func__, s->state, s->flags, s->mtu);
3357 
3358 		switch (s->state) {
3359 		case NG_BTSOCKET_RFCOMM_SESSION_CLOSED:
3360 		case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING:
3361 			/*
3362 			 * Do not have to do anything here. We can get here
3363 			 * when L2CAP connection was terminated or we have
3364 			 * received DISC on multiplexor channel
3365 			 */
3366 			break;
3367 
3368 		case NG_BTSOCKET_RFCOMM_SESSION_OPEN:
3369 			/* Send DISC on multiplexor channel */
3370 			error = ng_btsocket_rfcomm_send_command(s,
3371 					RFCOMM_FRAME_DISC, 0);
3372 			if (error == 0) {
3373 				s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING;
3374 				break;
3375 			}
3376 			/* FALL THROUGH */
3377 
3378 		case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING:
3379 		case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
3380 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
3381 			break;
3382 
3383 /*		case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: */
3384 		default:
3385 			panic("%s: Invalid session state=%d, flags=%#x\n",
3386 				__func__, s->state, s->flags);
3387 			break;
3388 		}
3389 
3390 		ng_btsocket_rfcomm_task_wakeup();
3391 	}
3392 
3393 	return (pcb->so->so_state & SS_NOFDREF);
3394 } /* ng_btsocket_rfcomm_pcb_kill */
3395 
3396 /*
3397  * Look for RFCOMM socket with given channel and source address
3398  */
3399 
3400 static ng_btsocket_rfcomm_pcb_p
3401 ng_btsocket_rfcomm_pcb_by_channel(bdaddr_p src, int channel)
3402 {
3403 	ng_btsocket_rfcomm_pcb_p	pcb = NULL;
3404 
3405 	mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
3406 
3407 	LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next)
3408 		if (pcb->channel == channel &&
3409 		    bcmp(&pcb->src, src, sizeof(*src)) == 0)
3410 			break;
3411 
3412 	mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
3413 
3414 	return (pcb);
3415 } /* ng_btsocket_rfcomm_pcb_by_channel */
3416 
3417 /*
3418  * Look for given dlci for given RFCOMM session. Caller must hold s->session_mtx
3419  */
3420 
3421 static ng_btsocket_rfcomm_pcb_p
3422 ng_btsocket_rfcomm_pcb_by_dlci(ng_btsocket_rfcomm_session_p s, int dlci)
3423 {
3424 	ng_btsocket_rfcomm_pcb_p	pcb = NULL;
3425 
3426 	mtx_assert(&s->session_mtx, MA_OWNED);
3427 
3428 	LIST_FOREACH(pcb, &s->dlcs, session_next)
3429 		if (pcb->dlci == dlci)
3430 			break;
3431 
3432 	return (pcb);
3433 } /* ng_btsocket_rfcomm_pcb_by_dlci */
3434 
3435 /*
3436  * Look for socket that listens on given src address and given channel
3437  */
3438 
3439 static ng_btsocket_rfcomm_pcb_p
3440 ng_btsocket_rfcomm_pcb_listener(bdaddr_p src, int channel)
3441 {
3442 	ng_btsocket_rfcomm_pcb_p	pcb = NULL, pcb1 = NULL;
3443 
3444 	mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
3445 
3446 	LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) {
3447 		if (pcb->channel != channel ||
3448 		    !(pcb->so->so_options & SO_ACCEPTCONN))
3449 			continue;
3450 
3451 		if (bcmp(&pcb->src, src, sizeof(*src)) == 0)
3452 			break;
3453 
3454 		if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
3455 			pcb1 = pcb;
3456 	}
3457 
3458 	mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
3459 
3460 	return ((pcb != NULL)? pcb : pcb1);
3461 } /* ng_btsocket_rfcomm_pcb_listener */
3462 
3463 /*****************************************************************************
3464  *****************************************************************************
3465  **                              Misc. functions
3466  *****************************************************************************
3467  *****************************************************************************/
3468 
3469 /*
3470  *  Set timeout. Caller MUST hold pcb_mtx
3471  */
3472 
3473 static void
3474 ng_btsocket_rfcomm_timeout(ng_btsocket_rfcomm_pcb_p pcb)
3475 {
3476 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3477 
3478 	if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) {
3479 		pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMO;
3480 		pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT;
3481 		pcb->timo = timeout(ng_btsocket_rfcomm_process_timeout, pcb,
3482 					ng_btsocket_rfcomm_timo * hz);
3483 	} else
3484 		panic("%s: Duplicated socket timeout?!\n", __func__);
3485 } /* ng_btsocket_rfcomm_timeout */
3486 
3487 /*
3488  *  Unset pcb timeout. Caller MUST hold pcb_mtx
3489  */
3490 
3491 static void
3492 ng_btsocket_rfcomm_untimeout(ng_btsocket_rfcomm_pcb_p pcb)
3493 {
3494 	mtx_assert(&pcb->pcb_mtx, MA_OWNED);
3495 
3496 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) {
3497 		untimeout(ng_btsocket_rfcomm_process_timeout, pcb, pcb->timo);
3498 		pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO;
3499 		pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT;
3500 	} else
3501 		panic("%s: No socket timeout?!\n", __func__);
3502 } /* ng_btsocket_rfcomm_timeout */
3503 
3504 /*
3505  * Process pcb timeout
3506  */
3507 
3508 static void
3509 ng_btsocket_rfcomm_process_timeout(void *xpcb)
3510 {
3511 	ng_btsocket_rfcomm_pcb_p	pcb = (ng_btsocket_rfcomm_pcb_p) xpcb;
3512 
3513 	mtx_lock(&pcb->pcb_mtx);
3514 
3515 	NG_BTSOCKET_RFCOMM_INFO(
3516 "%s: Timeout, so=%p, dlci=%d, state=%d, flags=%#x\n",
3517 		__func__, pcb->so, pcb->dlci, pcb->state, pcb->flags);
3518 
3519 	pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO;
3520 	pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT;
3521 
3522 	switch (pcb->state) {
3523 	case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING:
3524 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTING:
3525 		pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING;
3526 		break;
3527 
3528 	case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT:
3529 	case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING:
3530 		break;
3531 
3532 	default:
3533 		panic(
3534 "%s: DLC timeout in invalid state, dlci=%d, state=%d, flags=%#x\n",
3535 			__func__, pcb->dlci, pcb->state, pcb->flags);
3536 		break;
3537 	}
3538 
3539 	ng_btsocket_rfcomm_task_wakeup();
3540 
3541 	mtx_unlock(&pcb->pcb_mtx);
3542 } /* ng_btsocket_rfcomm_process_timeout */
3543 
3544 /*
3545  * Get up to length bytes from the socket buffer
3546  */
3547 
3548 static struct mbuf *
3549 ng_btsocket_rfcomm_prepare_packet(struct sockbuf *sb, int length)
3550 {
3551 	struct mbuf	*top = NULL, *m = NULL, *n = NULL, *nextpkt = NULL;
3552 	int		 mlen, noff, len;
3553 
3554 	MGETHDR(top, M_DONTWAIT, MT_DATA);
3555 	if (top == NULL)
3556 		return (NULL);
3557 
3558 	top->m_pkthdr.len = length;
3559 	top->m_len = 0;
3560 	mlen = MHLEN;
3561 
3562 	m = top;
3563 	n = sb->sb_mb;
3564 	nextpkt = n->m_nextpkt;
3565 	noff = 0;
3566 
3567 	while (length > 0 && n != NULL) {
3568 		len = min(mlen - m->m_len, n->m_len - noff);
3569 		if (len > length)
3570 			len = length;
3571 
3572 		bcopy(mtod(n, caddr_t)+noff, mtod(m, caddr_t)+m->m_len, len);
3573 		m->m_len += len;
3574 		noff += len;
3575 		length -= len;
3576 
3577 		if (length > 0 && m->m_len == mlen) {
3578 			MGET(m->m_next, M_DONTWAIT, MT_DATA);
3579 			if (m->m_next == NULL) {
3580 				NG_FREE_M(top);
3581 				return (NULL);
3582 			}
3583 
3584 			m = m->m_next;
3585 			m->m_len = 0;
3586 			mlen = MLEN;
3587 		}
3588 
3589 		if (noff == n->m_len) {
3590 			noff = 0;
3591 			n = n->m_next;
3592 
3593 			if (n == NULL)
3594 				n = nextpkt;
3595 
3596 			nextpkt = (n != NULL)? n->m_nextpkt : NULL;
3597 		}
3598 	}
3599 
3600 	if (length < 0)
3601 		panic("%s: length=%d\n", __func__, length);
3602 	if (length > 0 && n == NULL)
3603 		panic("%s: bogus length=%d, n=%p\n", __func__, length, n);
3604 
3605 	return (top);
3606 } /* ng_btsocket_rfcomm_prepare_packet */
3607 
3608