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