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