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