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