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