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