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