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