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