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