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