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