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/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/mutex.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/queue.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/sysctl.h>
53 #include <sys/taskqueue.h>
54 #include <sys/uio.h>
55 #include "ng_message.h"
56 #include "netgraph.h"
57 #include "bluetooth/include/ng_bluetooth.h"
58 #include "bluetooth/include/ng_hci.h"
59 #include "bluetooth/include/ng_l2cap.h"
60 #include "bluetooth/include/ng_btsocket.h"
61 #include "bluetooth/include/ng_btsocket_l2cap.h"
62 #include "bluetooth/include/ng_btsocket_rfcomm.h"
63 
64 /* MALLOC define */
65 #ifdef NG_SEPARATE_MALLOC
66 MALLOC_DEFINE(M_NETGRAPH_BTSOCKET_RFCOMM, "netgraph_btsocks_rfcomm",
67 		"Netgraph Bluetooth RFCOMM sockets");
68 #else
69 #define M_NETGRAPH_BTSOCKET_RFCOMM M_NETGRAPH
70 #endif /* NG_SEPARATE_MALLOC */
71 
72 /* Debug */
73 #define NG_BTSOCKET_RFCOMM_INFO \
74 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_INFO_LEVEL) \
75 		printf
76 
77 #define NG_BTSOCKET_RFCOMM_WARN \
78 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_WARN_LEVEL) \
79 		printf
80 
81 #define NG_BTSOCKET_RFCOMM_ERR \
82 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_ERR_LEVEL) \
83 		printf
84 
85 #define NG_BTSOCKET_RFCOMM_ALERT \
86 	if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_ALERT_LEVEL) \
87 		printf
88 
89 #define	ALOT	0x7fff
90 
91 /* Local prototypes */
92 static void ng_btsocket_rfcomm_upcall
93 	(struct socket *so, void *arg, int waitflag);
94 static void ng_btsocket_rfcomm_sessions_task
95 	(void *ctx, int pending);
96 static void ng_btsocket_rfcomm_session_task
97 	(ng_btsocket_rfcomm_session_p s);
98 #define ng_btsocket_rfcomm_task_wakeup() \
99 	taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_rfcomm_task)
100 
101 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_connect_ind
102 	(ng_btsocket_rfcomm_session_p s, int channel);
103 static void ng_btsocket_rfcomm_connect_cfm
104 	(ng_btsocket_rfcomm_session_p s);
105 
106 static int ng_btsocket_rfcomm_session_create
107 	(ng_btsocket_rfcomm_session_p *sp, struct socket *l2so,
108 	 bdaddr_p src, bdaddr_p dst, struct thread *td);
109 static int ng_btsocket_rfcomm_session_accept
110 	(ng_btsocket_rfcomm_session_p s0);
111 static int ng_btsocket_rfcomm_session_connect
112 	(ng_btsocket_rfcomm_session_p s);
113 static int ng_btsocket_rfcomm_session_receive
114 	(ng_btsocket_rfcomm_session_p s);
115 static int ng_btsocket_rfcomm_session_send
116 	(ng_btsocket_rfcomm_session_p s);
117 static void ng_btsocket_rfcomm_session_clean
118 	(ng_btsocket_rfcomm_session_p s);
119 static void ng_btsocket_rfcomm_session_process_pcb
120 	(ng_btsocket_rfcomm_session_p s);
121 static ng_btsocket_rfcomm_session_p ng_btsocket_rfcomm_session_by_addr
122 	(bdaddr_p src, bdaddr_p dst);
123 
124 static int ng_btsocket_rfcomm_receive_frame
125 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
126 static int ng_btsocket_rfcomm_receive_sabm
127 	(ng_btsocket_rfcomm_session_p s, int dlci);
128 static int ng_btsocket_rfcomm_receive_disc
129 	(ng_btsocket_rfcomm_session_p s, int dlci);
130 static int ng_btsocket_rfcomm_receive_ua
131 	(ng_btsocket_rfcomm_session_p s, int dlci);
132 static int ng_btsocket_rfcomm_receive_dm
133 	(ng_btsocket_rfcomm_session_p s, int dlci);
134 static int ng_btsocket_rfcomm_receive_uih
135 	(ng_btsocket_rfcomm_session_p s, int dlci, int pf, struct mbuf *m0);
136 static int ng_btsocket_rfcomm_receive_mcc
137 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
138 static int ng_btsocket_rfcomm_receive_test
139 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
140 static int ng_btsocket_rfcomm_receive_fc
141 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
142 static int ng_btsocket_rfcomm_receive_msc
143 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
144 static int ng_btsocket_rfcomm_receive_rpn
145 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
146 static int ng_btsocket_rfcomm_receive_rls
147 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
148 static int ng_btsocket_rfcomm_receive_pn
149 	(ng_btsocket_rfcomm_session_p s, struct mbuf *m0);
150 static void ng_btsocket_rfcomm_set_pn
151 	(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, u_int8_t flow_control,
152 	 u_int8_t credits, u_int16_t mtu);
153 
154 static int ng_btsocket_rfcomm_send_command
155 	(ng_btsocket_rfcomm_session_p s, u_int8_t type, u_int8_t dlci);
156 static int ng_btsocket_rfcomm_send_uih
157 	(ng_btsocket_rfcomm_session_p s, u_int8_t address, u_int8_t pf,
158 	 u_int8_t credits, struct mbuf *data);
159 static int ng_btsocket_rfcomm_send_msc
160 	(ng_btsocket_rfcomm_pcb_p pcb);
161 static int ng_btsocket_rfcomm_send_pn
162 	(ng_btsocket_rfcomm_pcb_p pcb);
163 static int ng_btsocket_rfcomm_send_credits
164 	(ng_btsocket_rfcomm_pcb_p pcb);
165 
166 static int ng_btsocket_rfcomm_pcb_send
167 	(ng_btsocket_rfcomm_pcb_p pcb, int limit);
168 static void ng_btsocket_rfcomm_pcb_kill
169 	(ng_btsocket_rfcomm_pcb_p pcb, int error);
170 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_by_dlci
171 	(ng_btsocket_rfcomm_session_p s, int dlci);
172 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_listener
173 	(bdaddr_p src, int channel);
174 
175 static void ng_btsocket_rfcomm_timeout
176 	(ng_btsocket_rfcomm_pcb_p pcb);
177 static void ng_btsocket_rfcomm_untimeout
178 	(ng_btsocket_rfcomm_pcb_p pcb);
179 static void ng_btsocket_rfcomm_process_timeout
180 	(void *xpcb);
181 
182 static struct mbuf * ng_btsocket_rfcomm_prepare_packet
183 	(struct sockbuf *sb, int length);
184 
185 /* Globals */
186 extern int					ifqmaxlen;
187 static u_int32_t				ng_btsocket_rfcomm_debug_level;
188 static u_int32_t				ng_btsocket_rfcomm_timo;
189 struct task					ng_btsocket_rfcomm_task;
190 static LIST_HEAD(, ng_btsocket_rfcomm_session)	ng_btsocket_rfcomm_sessions;
191 static struct mtx				ng_btsocket_rfcomm_sessions_mtx;
192 static LIST_HEAD(, ng_btsocket_rfcomm_pcb)	ng_btsocket_rfcomm_sockets;
193 static struct mtx				ng_btsocket_rfcomm_sockets_mtx;
194 
195 /* Sysctl tree */
196 SYSCTL_DECL(_net_bluetooth_rfcomm_sockets);
197 SYSCTL_NODE(_net_bluetooth_rfcomm_sockets, OID_AUTO, stream, CTLFLAG_RW,
198 	0, "Bluetooth STREAM RFCOMM sockets family");
199 SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, debug_level,
200 	CTLFLAG_RW,
201 	&ng_btsocket_rfcomm_debug_level, NG_BTSOCKET_INFO_LEVEL,
202 	"Bluetooth STREAM RFCOMM sockets debug level");
203 SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, timeout,
204 	CTLFLAG_RW,
205 	&ng_btsocket_rfcomm_timo, 60,
206 	"Bluetooth STREAM RFCOMM sockets timeout");
207 
208 /*****************************************************************************
209  *****************************************************************************
210  **                              RFCOMM CRC
211  *****************************************************************************
212  *****************************************************************************/
213 
214 static u_int8_t	ng_btsocket_rfcomm_crc_table[256] = {
215 	0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
216 	0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
217 	0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
218 	0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
219 
220 	0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
221 	0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
222 	0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
223 	0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
224 
225 	0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
226 	0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
227 	0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
228 	0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
229 
230 	0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
231 	0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
232 	0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
233 	0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
234 
235 	0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
236 	0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
237 	0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
238 	0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
239 
240 	0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
241 	0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
242 	0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
243 	0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
244 
245 	0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
246 	0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
247 	0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
248 	0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
249 
250 	0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
251 	0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
252 	0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
253 	0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
254 };
255 
256 /* CRC */
257 static u_int8_t
258 ng_btsocket_rfcomm_crc(u_int8_t *data, int length)
259 {
260 	u_int8_t	crc = 0xff;
261 
262 	while (length --)
263 		crc = ng_btsocket_rfcomm_crc_table[crc ^ *data++];
264 
265 	return (crc);
266 } /* ng_btsocket_rfcomm_crc */
267 
268 /* FCS on 2 bytes */
269 static u_int8_t
270 ng_btsocket_rfcomm_fcs2(u_int8_t *data)
271 {
272 	return (0xff - ng_btsocket_rfcomm_crc(data, 2));
273 } /* ng_btsocket_rfcomm_fcs2 */
274 
275 /* FCS on 3 bytes */
276 static u_int8_t
277 ng_btsocket_rfcomm_fcs3(u_int8_t *data)
278 {
279 	return (0xff - ng_btsocket_rfcomm_crc(data, 3));
280 } /* ng_btsocket_rfcomm_fcs3 */
281 
282 /*
283  * Check FCS
284  *
285  * From Bluetooth spec
286  *
287  * "... In 07.10, the frame check sequence (FCS) is calculated on different
288  * sets of fields for different frame types. These are the fields that the
289  * FCS are calculated on:
290  *
291  * For SABM, DISC, UA, DM frames: on Address, Control and length field.
292  * For UIH frames: on Address and Control field.
293  *
294  * (This is stated here for clarification, and to set the standard for RFCOMM;
295  * the fields included in FCS calculation have actually changed in version
296  * 7.0.0 of TS 07.10, but RFCOMM will not change the FCS calculation scheme
297  * from the one above.) ..."
298  */
299 
300 static int
301 ng_btsocket_rfcomm_check_fcs(u_int8_t *data, int type, u_int8_t fcs)
302 {
303 	if (type != RFCOMM_FRAME_UIH)
304 		return (ng_btsocket_rfcomm_fcs3(data) != fcs);
305 
306 	return (ng_btsocket_rfcomm_fcs2(data) != fcs);
307 } /* ng_btsocket_rfcomm_check_fcs */
308 
309 /*****************************************************************************
310  *****************************************************************************
311  **                              Socket interface
312  *****************************************************************************
313  *****************************************************************************/
314 
315 /*
316  * Initialize everything
317  */
318 
319 void
320 ng_btsocket_rfcomm_init(void)
321 {
322 	ng_btsocket_rfcomm_debug_level = NG_BTSOCKET_WARN_LEVEL;
323 	ng_btsocket_rfcomm_timo = 60;
324 
325 	/* RFCOMM task */
326 	TASK_INIT(&ng_btsocket_rfcomm_task, 0,
327 		ng_btsocket_rfcomm_sessions_task, NULL);
328 
329 	/* RFCOMM sessions list */
330 	LIST_INIT(&ng_btsocket_rfcomm_sessions);
331 	mtx_init(&ng_btsocket_rfcomm_sessions_mtx,
332 		"btsocks_rfcomm_sessions_mtx", NULL, MTX_DEF);
333 
334 	/* RFCOMM sockets list */
335 	LIST_INIT(&ng_btsocket_rfcomm_sockets);
336 	mtx_init(&ng_btsocket_rfcomm_sockets_mtx,
337 		"btsocks_rfcomm_sockets_mtx", NULL, MTX_DEF);
338 } /* ng_btsocket_rfcomm_init */
339 
340 /*
341  * Abort connection on socket
342  */
343 
344 void
345 ng_btsocket_rfcomm_abort(struct socket *so)
346 {
347 
348 	so->so_error = ECONNABORTED;
349 	(void)ng_btsocket_rfcomm_disconnect(so);
350 } /* ng_btsocket_rfcomm_abort */
351 
352 void
353 ng_btsocket_rfcomm_close(struct socket *so)
354 {
355 
356 	(void)ng_btsocket_rfcomm_disconnect(so);
357 } /* ng_btsocket_rfcomm_close */
358 
359 /*
360  * Accept connection on socket. Nothing to do here, socket must be connected
361  * and ready, so just return peer address and be done with it.
362  */
363 
364 int
365 ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam)
366 {
367 	return (ng_btsocket_rfcomm_peeraddr(so, nam));
368 } /* ng_btsocket_rfcomm_accept */
369 
370 /*
371  * Create and attach new socket
372  */
373 
374 int
375 ng_btsocket_rfcomm_attach(struct socket *so, int proto, struct thread *td)
376 {
377 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
378 	int				error;
379 
380 	/* Check socket and protocol */
381 	if (so->so_type != SOCK_STREAM)
382 		return (ESOCKTNOSUPPORT);
383 
384 #if 0 /* XXX sonewconn() calls "pru_attach" with proto == 0 */
385 	if (proto != 0)
386 		if (proto != BLUETOOTH_PROTO_RFCOMM)
387 			return (EPROTONOSUPPORT);
388 #endif /* XXX */
389 
390 	if (pcb != NULL)
391 		return (EISCONN);
392 
393 	/* Reserve send and receive space if it is not reserved yet */
394 	if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
395 		error = soreserve(so, NG_BTSOCKET_RFCOMM_SENDSPACE,
396 					NG_BTSOCKET_RFCOMM_RECVSPACE);
397 		if (error != 0)
398 			return (error);
399 	}
400 
401 	/* Allocate the PCB */
402         pcb = kmalloc(sizeof(*pcb), M_NETGRAPH_BTSOCKET_RFCOMM,
403 		      M_WAITOK | M_NULLOK | M_ZERO);
404         if (pcb == NULL)
405                 return (ENOMEM);
406 
407 	/* Link the PCB and the socket */
408 	so->so_pcb = (caddr_t) pcb;
409 	pcb->so = so;
410 
411 	/* Initialize PCB */
412 	pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED;
413 	pcb->flags = NG_BTSOCKET_RFCOMM_DLC_CFC;
414 
415 	pcb->lmodem =
416 	pcb->rmodem = (RFCOMM_MODEM_RTC | RFCOMM_MODEM_RTR | RFCOMM_MODEM_DV);
417 
418 	pcb->mtu = RFCOMM_DEFAULT_MTU;
419 	pcb->tx_cred = 0;
420 	pcb->rx_cred = RFCOMM_DEFAULT_CREDITS;
421 
422 	mtx_init(&pcb->pcb_mtx, "btsocks_rfcomm_pcb_mtx", NULL, MTX_DEF);
423 	callout_handle_init(&pcb->timo);
424 
425 	/* Add the PCB to the list */
426 	mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
427 	LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sockets, pcb, next);
428 	mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
429 
430         return (0);
431 } /* ng_btsocket_rfcomm_attach */
432 
433 /*
434  * Bind socket
435  */
436 
437 int
438 ng_btsocket_rfcomm_bind(struct socket *so, struct sockaddr *nam,
439 		struct thread *td)
440 {
441 	ng_btsocket_rfcomm_pcb_t	*pcb = so2rfcomm_pcb(so), *pcb1;
442 	struct sockaddr_rfcomm		*sa = (struct sockaddr_rfcomm *) nam;
443 
444 	if (pcb == NULL)
445 		return (EINVAL);
446 
447 	/* Verify address */
448 	if (sa == NULL)
449 		return (EINVAL);
450 	if (sa->rfcomm_family != AF_BLUETOOTH)
451 		return (EAFNOSUPPORT);
452 	if (sa->rfcomm_len != sizeof(*sa))
453 		return (EINVAL);
454 	if (sa->rfcomm_channel > 30)
455 		return (EINVAL);
456 
457 	mtx_lock(&pcb->pcb_mtx);
458 
459 	if (sa->rfcomm_channel != 0) {
460 		mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
461 
462 		LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) {
463 			if (pcb1->channel == sa->rfcomm_channel &&
464 			    bcmp(&pcb1->src, &sa->rfcomm_bdaddr,
465 					sizeof(pcb1->src)) == 0) {
466 				mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
467 				mtx_unlock(&pcb->pcb_mtx);
468 
469 				return (EADDRINUSE);
470 			}
471 		}
472 
473 		mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
474 	}
475 
476 	bcopy(&sa->rfcomm_bdaddr, &pcb->src, sizeof(pcb->src));
477 	pcb->channel = sa->rfcomm_channel;
478 
479 	mtx_unlock(&pcb->pcb_mtx);
480 
481 	return (0);
482 } /* ng_btsocket_rfcomm_bind */
483 
484 /*
485  * Connect socket
486  */
487 
488 int
489 ng_btsocket_rfcomm_connect(struct socket *so, struct sockaddr *nam,
490 		struct thread *td)
491 {
492 	ng_btsocket_rfcomm_pcb_t	*pcb = so2rfcomm_pcb(so);
493 	struct sockaddr_rfcomm		*sa = (struct sockaddr_rfcomm *) nam;
494 	ng_btsocket_rfcomm_session_t	*s = NULL;
495 	struct socket			*l2so = NULL;
496 	int				 dlci, error = 0;
497 
498 	if (pcb == NULL)
499 		return (EINVAL);
500 
501 	/* Verify address */
502 	if (sa == NULL)
503 		return (EINVAL);
504 	if (sa->rfcomm_family != AF_BLUETOOTH)
505 		return (EAFNOSUPPORT);
506 	if (sa->rfcomm_len != sizeof(*sa))
507 		return (EINVAL);
508 	if (sa->rfcomm_channel > 30)
509 		return (EINVAL);
510 	if (sa->rfcomm_channel == 0 ||
511 	    bcmp(&sa->rfcomm_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
512 		return (EDESTADDRREQ);
513 
514 	/*
515 	 * XXX FIXME - This is FUBAR. socreate() will call soalloc(1), i.e.
516 	 * soalloc() is allowed to sleep in MALLOC. This creates "could sleep"
517 	 * WITNESS warnings. To work around this problem we will create L2CAP
518 	 * socket first and then check if we actually need it. Note that we
519 	 * will not check for errors in socreate() because if we failed to
520 	 * create L2CAP socket at this point we still might have already open
521 	 * session.
522 	 */
523 
524 	error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET,
525 			BLUETOOTH_PROTO_L2CAP, td->td_ucred, td);
526 
527 	/*
528 	 * Look for session between "pcb->src" and "sa->rfcomm_bdaddr" (dst)
529 	 */
530 
531 	mtx_lock(&ng_btsocket_rfcomm_sessions_mtx);
532 
533 	s = ng_btsocket_rfcomm_session_by_addr(&pcb->src, &sa->rfcomm_bdaddr);
534 	if (s == NULL) {
535 		/*
536 		 * We need to create new RFCOMM session. Check if we have L2CAP
537 		 * socket. If l2so == NULL then error has the error code from
538 		 * socreate()
539 		 */
540 
541 		if (l2so == NULL) {
542 			mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
543 			return (error);
544 		}
545 
546 		error = ng_btsocket_rfcomm_session_create(&s, l2so,
547 				&pcb->src, &sa->rfcomm_bdaddr, td);
548 		if (error != 0) {
549 			mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
550 			soclose(l2so);
551 
552 			return (error);
553 		}
554 	} else if (l2so != NULL)
555 		soclose(l2so); /* we don't need new L2CAP socket */
556 
557 	/*
558 	 * Check if we already have the same DLCI the the same session
559 	 */
560 
561 	mtx_lock(&s->session_mtx);
562 	mtx_lock(&pcb->pcb_mtx);
563 
564 	dlci = RFCOMM_MKDLCI(!INITIATOR(s), sa->rfcomm_channel);
565 
566 	if (ng_btsocket_rfcomm_pcb_by_dlci(s, dlci) != NULL) {
567 		mtx_unlock(&pcb->pcb_mtx);
568 		mtx_unlock(&s->session_mtx);
569 		mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
570 
571 		return (EBUSY);
572 	}
573 
574 	/*
575 	 * Check session state and if its not acceptable then refuse connection
576 	 */
577 
578 	switch (s->state) {
579 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING:
580 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
581 	case NG_BTSOCKET_RFCOMM_SESSION_OPEN:
582 		/*
583 		 * Update destination address and channel and attach
584 		 * DLC to the session
585 		 */
586 
587 		bcopy(&sa->rfcomm_bdaddr, &pcb->dst, sizeof(pcb->dst));
588 		pcb->channel = sa->rfcomm_channel;
589 		pcb->dlci = dlci;
590 
591 		LIST_INSERT_HEAD(&s->dlcs, pcb, session_next);
592 		pcb->session = s;
593 
594 		ng_btsocket_rfcomm_timeout(pcb);
595 		soisconnecting(pcb->so);
596 
597 		if (s->state == NG_BTSOCKET_RFCOMM_SESSION_OPEN) {
598 			pcb->mtu = s->mtu;
599 			bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src,
600 				sizeof(pcb->src));
601 
602 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING;
603 
604 			error = ng_btsocket_rfcomm_send_pn(pcb);
605 			if (error == 0)
606 				error = ng_btsocket_rfcomm_task_wakeup();
607 		} else
608 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT;
609 		break;
610 
611 	default:
612 		error = ECONNRESET;
613 		break;
614 	}
615 
616 	mtx_unlock(&pcb->pcb_mtx);
617 	mtx_unlock(&s->session_mtx);
618 	mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
619 
620 	return (error);
621 } /* ng_btsocket_rfcomm_connect */
622 
623 /*
624  * Process ioctl's calls on socket.
625  * XXX FIXME this should provide interface to the RFCOMM multiplexor channel
626  */
627 
628 int
629 ng_btsocket_rfcomm_control(struct socket *so, u_long cmd, caddr_t data,
630 		struct ifnet *ifp, struct thread *td)
631 {
632 	return (EINVAL);
633 } /* ng_btsocket_rfcomm_control */
634 
635 /*
636  * Process getsockopt/setsockopt system calls
637  */
638 
639 int
640 ng_btsocket_rfcomm_ctloutput(struct socket *so, struct sockopt *sopt)
641 {
642 	ng_btsocket_rfcomm_pcb_p		pcb = so2rfcomm_pcb(so);
643 	struct ng_btsocket_rfcomm_fc_info	fcinfo;
644 	int					error = 0;
645 
646 	if (pcb == NULL)
647 		return (EINVAL);
648 	if (sopt->sopt_level != SOL_RFCOMM)
649 		return (0);
650 
651 	mtx_lock(&pcb->pcb_mtx);
652 
653 	switch (sopt->sopt_dir) {
654 	case SOPT_GET:
655 		switch (sopt->sopt_name) {
656 		case SO_RFCOMM_MTU:
657 			error = sooptcopyout(sopt, &pcb->mtu, sizeof(pcb->mtu));
658 			break;
659 
660 		case SO_RFCOMM_FC_INFO:
661 			fcinfo.lmodem = pcb->lmodem;
662 			fcinfo.rmodem = pcb->rmodem;
663 			fcinfo.tx_cred = pcb->tx_cred;
664 			fcinfo.rx_cred = pcb->rx_cred;
665 			fcinfo.cfc = (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)?
666 				1 : 0;
667 			fcinfo.reserved = 0;
668 
669 			error = sooptcopyout(sopt, &fcinfo, sizeof(fcinfo));
670 			break;
671 
672 		default:
673 			error = ENOPROTOOPT;
674 			break;
675 		}
676 		break;
677 
678 	case SOPT_SET:
679 		switch (sopt->sopt_name) {
680 		default:
681 			error = ENOPROTOOPT;
682 			break;
683 		}
684 		break;
685 
686 	default:
687 		error = EINVAL;
688 		break;
689 	}
690 
691 	mtx_unlock(&pcb->pcb_mtx);
692 
693 	return (error);
694 } /* ng_btsocket_rfcomm_ctloutput */
695 
696 /*
697  * Detach and destroy socket
698  */
699 
700 void
701 ng_btsocket_rfcomm_detach(struct socket *so)
702 {
703 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
704 
705 	KASSERT(pcb != NULL, ("ng_btsocket_rfcomm_detach: pcb == NULL"));
706 
707 	mtx_lock(&pcb->pcb_mtx);
708 
709 	so->so_pcb = NULL;
710 
711 	switch (pcb->state) {
712 	case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT:
713 	case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING:
714 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTING:
715 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTED:
716 		/* XXX What to do with pending request? */
717 		if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
718 			ng_btsocket_rfcomm_untimeout(pcb);
719 
720 		if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT)
721 			pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_DETACHED;
722 		else
723 			pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING;
724 
725 		ng_btsocket_rfcomm_task_wakeup();
726 		break;
727 
728 	case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING:
729 		ng_btsocket_rfcomm_task_wakeup();
730 		break;
731 	}
732 
733 	while (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CLOSED)
734 		msleep(&pcb->state, &pcb->pcb_mtx, PZERO, "rf_det", 0);
735 
736 	if (pcb->session != NULL)
737 		panic("%s: pcb->session != NULL\n", __func__);
738 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
739 		panic("%s: timeout on closed DLC, flags=%#x\n",
740 			__func__, pcb->flags);
741 
742 	mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
743 	LIST_REMOVE(pcb, next);
744 	mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
745 
746 	mtx_unlock(&pcb->pcb_mtx);
747 
748 	mtx_destroy(&pcb->pcb_mtx);
749 	bzero(pcb, sizeof(*pcb));
750 	kfree(pcb, M_NETGRAPH_BTSOCKET_RFCOMM);
751 
752 	soisdisconnected(so);
753 	sofree(so);		/* for so_pcb = NULL */
754 } /* ng_btsocket_rfcomm_detach */
755 
756 /*
757  * Disconnect socket
758  */
759 
760 int
761 ng_btsocket_rfcomm_disconnect(struct socket *so)
762 {
763 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
764 
765 	if (pcb == NULL)
766 		return (EINVAL);
767 
768 	mtx_lock(&pcb->pcb_mtx);
769 
770 	if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING) {
771 		mtx_unlock(&pcb->pcb_mtx);
772 		return (EINPROGRESS);
773 	}
774 
775 	/* XXX What to do with pending request? */
776 	if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)
777 		ng_btsocket_rfcomm_untimeout(pcb);
778 
779 	switch (pcb->state) {
780 	case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: /* XXX can we get here? */
781 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: /* XXX can we get here? */
782 	case NG_BTSOCKET_RFCOMM_DLC_CONNECTED:
783 
784 		/*
785 		 * Just change DLC state and enqueue RFCOMM task. It will
786 		 * queue and send DISC on the DLC.
787 		 */
788 
789 		pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING;
790 		soisdisconnecting(so);
791 
792 		ng_btsocket_rfcomm_task_wakeup();
793 		break;
794 
795 	case NG_BTSOCKET_RFCOMM_DLC_CLOSED:
796 	case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT:
797 		break;
798 
799 	default:
800 		panic("%s: Invalid DLC state=%d, flags=%#x\n",
801 			__func__, pcb->state, pcb->flags);
802 		break;
803 	}
804 
805 	mtx_unlock(&pcb->pcb_mtx);
806 
807 	return (0);
808 } /* ng_btsocket_rfcomm_disconnect */
809 
810 /*
811  * Listen on socket. First call to listen() will create listening RFCOMM session
812  */
813 
814 int
815 ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td)
816 {
817 	ng_btsocket_rfcomm_pcb_p	 pcb = so2rfcomm_pcb(so), pcb1;
818 	ng_btsocket_rfcomm_session_p	 s = NULL;
819 	struct socket			*l2so = NULL;
820 	int				 error, socreate_error, usedchannels;
821 
822 	if (pcb == NULL)
823 		return (EINVAL);
824 	if (pcb->channel > 30)
825 		return (EADDRNOTAVAIL);
826 
827 	usedchannels = 0;
828 
829 	mtx_lock(&pcb->pcb_mtx);
830 
831 	if (pcb->channel == 0) {
832 		mtx_lock(&ng_btsocket_rfcomm_sockets_mtx);
833 
834 		LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next)
835 			if (pcb1->channel != 0 &&
836 			    bcmp(&pcb1->src, &pcb->src, sizeof(pcb->src)) == 0)
837 				usedchannels |= (1 << (pcb1->channel - 1));
838 
839 		for (pcb->channel = 30; pcb->channel > 0; pcb->channel --)
840 			if (!(usedchannels & (1 << (pcb->channel - 1))))
841 				break;
842 
843 		if (pcb->channel == 0) {
844 			mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
845 			mtx_unlock(&pcb->pcb_mtx);
846 
847 			return (EADDRNOTAVAIL);
848 		}
849 
850 		mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx);
851 	}
852 
853 	mtx_unlock(&pcb->pcb_mtx);
854 
855 	/*
856 	 * XXX FIXME - This is FUBAR. socreate() will call soalloc(1), i.e.
857 	 * soalloc() is allowed to sleep in MALLOC. This creates "could sleep"
858 	 * WITNESS warnings. To work around this problem we will create L2CAP
859 	 * socket first and then check if we actually need it. Note that we
860 	 * will not check for errors in socreate() because if we failed to
861 	 * create L2CAP socket at this point we still might have already open
862 	 * session.
863 	 */
864 
865 	socreate_error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET,
866 			BLUETOOTH_PROTO_L2CAP, td->td_ucred, td);
867 
868 	/*
869 	 * Transition the socket and session into the LISTENING state.  Check
870 	 * for collisions first, as there can only be one.
871 	 */
872 	mtx_lock(&ng_btsocket_rfcomm_sessions_mtx);
873 	SOCK_LOCK(so);
874 	error = solisten_proto_check(so);
875 	SOCK_UNLOCK(so);
876 	if (error != 0)
877 		goto out;
878 
879 	LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next)
880 		if (s->state == NG_BTSOCKET_RFCOMM_SESSION_LISTENING)
881 			break;
882 
883 	if (s == NULL) {
884 		/*
885 		 * We need to create default RFCOMM session. Check if we have
886 		 * L2CAP socket. If l2so == NULL then error has the error code
887 		 * from socreate()
888 		 */
889 		if (l2so == NULL) {
890 			error = socreate_error;
891 			goto out;
892 		}
893 
894 		/*
895 		 * Create default listen RFCOMM session. The default RFCOMM
896 		 * session will listen on ANY address.
897 		 *
898 		 * XXX FIXME Note that currently there is no way to adjust MTU
899 		 * for the default session.
900 		 */
901 		error = ng_btsocket_rfcomm_session_create(&s, l2so,
902 					NG_HCI_BDADDR_ANY, NULL, td);
903 		if (error != 0)
904 			goto out;
905 		l2so = NULL;
906 	}
907 	SOCK_LOCK(so);
908 	solisten_proto(so, backlog);
909 	SOCK_UNLOCK(so);
910 out:
911 	mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
912 	/*
913 	 * If we still have an l2so reference here, it's unneeded, so release
914 	 * it.
915 	 */
916 	if (l2so != NULL)
917 		soclose(l2so);
918 	return (error);
919 } /* ng_btsocket_listen */
920 
921 /*
922  * Get peer address
923  */
924 
925 int
926 ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam)
927 {
928 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
929 	struct sockaddr_rfcomm		sa;
930 
931 	if (pcb == NULL)
932 		return (EINVAL);
933 
934 	bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
935 	sa.rfcomm_channel = pcb->channel;
936 	sa.rfcomm_len = sizeof(sa);
937 	sa.rfcomm_family = AF_BLUETOOTH;
938 
939 	*nam = sodupsockaddr((struct sockaddr *) &sa, M_WAITOK | M_NULLOK);
940 
941 	return ((*nam == NULL)? ENOMEM : 0);
942 } /* ng_btsocket_rfcomm_peeraddr */
943 
944 /*
945  * Send data to socket
946  */
947 
948 int
949 ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m,
950 		struct sockaddr *nam, struct mbuf *control, struct thread *td)
951 {
952 	ng_btsocket_rfcomm_pcb_t	*pcb = so2rfcomm_pcb(so);
953 	int				 error = 0;
954 
955 	/* Check socket and input */
956 	if (pcb == NULL || m == NULL || control != NULL) {
957 		error = EINVAL;
958 		goto drop;
959 	}
960 
961 	mtx_lock(&pcb->pcb_mtx);
962 
963 	/* Make sure DLC is connected */
964 	if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) {
965 		mtx_unlock(&pcb->pcb_mtx);
966 		error = ENOTCONN;
967 		goto drop;
968 	}
969 
970 	/* Put the packet on the socket's send queue and wakeup RFCOMM task */
971 	sbappend(&pcb->so->so_snd, m);
972 	m = NULL;
973 
974 	if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) {
975 		pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_SENDING;
976 		error = ng_btsocket_rfcomm_task_wakeup();
977 	}
978 
979 	mtx_unlock(&pcb->pcb_mtx);
980 drop:
981 	NG_FREE_M(m); /* checks for != NULL */
982 	NG_FREE_M(control);
983 
984 	return (error);
985 } /* ng_btsocket_rfcomm_send */
986 
987 /*
988  * Get socket address
989  */
990 
991 int
992 ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam)
993 {
994 	ng_btsocket_rfcomm_pcb_p	pcb = so2rfcomm_pcb(so);
995 	struct sockaddr_rfcomm		sa;
996 
997 	if (pcb == NULL)
998 		return (EINVAL);
999 
1000 	bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
1001 	sa.rfcomm_channel = pcb->channel;
1002 	sa.rfcomm_len = sizeof(sa);
1003 	sa.rfcomm_family = AF_BLUETOOTH;
1004 
1005 	*nam = sodupsockaddr((struct sockaddr *) &sa, M_WAITOK | M_NULLOK);
1006 
1007 	return ((*nam == NULL)? ENOMEM : 0);
1008 } /* ng_btsocket_rfcomm_sockaddr */
1009 
1010 /*
1011  * Upcall function for L2CAP sockets. Enqueue RFCOMM task.
1012  */
1013 
1014 static void
1015 ng_btsocket_rfcomm_upcall(struct socket *so, void *arg, int waitflag)
1016 {
1017 	int	error;
1018 
1019 	if (so == NULL)
1020 		panic("%s: so == NULL\n", __func__);
1021 
1022 	if ((error = ng_btsocket_rfcomm_task_wakeup()) != 0)
1023 		NG_BTSOCKET_RFCOMM_ALERT(
1024 "%s: Could not enqueue RFCOMM task, error=%d\n", __func__, error);
1025 } /* ng_btsocket_rfcomm_upcall */
1026 
1027 /*
1028  * RFCOMM task. Will handle all RFCOMM sessions in one pass.
1029  * XXX FIXME does not scale very well
1030  */
1031 
1032 static void
1033 ng_btsocket_rfcomm_sessions_task(void *ctx, int pending)
1034 {
1035 	ng_btsocket_rfcomm_session_p	s = NULL, s_next = NULL;
1036 
1037 	mtx_lock(&ng_btsocket_rfcomm_sessions_mtx);
1038 
1039 	for (s = LIST_FIRST(&ng_btsocket_rfcomm_sessions); s != NULL; ) {
1040 		mtx_lock(&s->session_mtx);
1041 		s_next = LIST_NEXT(s, next);
1042 
1043 		ng_btsocket_rfcomm_session_task(s);
1044 
1045 		if (s->state == NG_BTSOCKET_RFCOMM_SESSION_CLOSED) {
1046 			/* Unlink and clean the session */
1047 			LIST_REMOVE(s, next);
1048 
1049 			NG_BT_MBUFQ_DRAIN(&s->outq);
1050 			if (!LIST_EMPTY(&s->dlcs))
1051 				panic("%s: DLC list is not empty\n", __func__);
1052 
1053 			/* Close L2CAP socket */
1054 			s->l2so->so_upcallarg = NULL;
1055 			s->l2so->so_upcall = NULL;
1056 			SOCKBUF_LOCK(&s->l2so->so_rcv);
1057 			s->l2so->so_rcv.sb_flags &= ~SB_UPCALL;
1058 			SOCKBUF_UNLOCK(&s->l2so->so_rcv);
1059 			SOCKBUF_LOCK(&s->l2so->so_snd);
1060 			s->l2so->so_snd.sb_flags &= ~SB_UPCALL;
1061 			SOCKBUF_UNLOCK(&s->l2so->so_snd);
1062 			soclose(s->l2so);
1063 
1064 			mtx_unlock(&s->session_mtx);
1065 
1066 			mtx_destroy(&s->session_mtx);
1067 			bzero(s, sizeof(*s));
1068 			kfree(s, M_NETGRAPH_BTSOCKET_RFCOMM);
1069 		} else
1070 			mtx_unlock(&s->session_mtx);
1071 
1072 		s = s_next;
1073 	}
1074 
1075 	mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx);
1076 } /* ng_btsocket_rfcomm_sessions_task */
1077 
1078 /*
1079  * Process RFCOMM session. Will handle all RFCOMM sockets in one pass.
1080  */
1081 
1082 static void
1083 ng_btsocket_rfcomm_session_task(ng_btsocket_rfcomm_session_p s)
1084 {
1085 	mtx_assert(&s->session_mtx, MA_OWNED);
1086 
1087 	if (s->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) {
1088 		NG_BTSOCKET_RFCOMM_INFO(
1089 "%s: L2CAP connection has been terminated, so=%p, so_state=%#x, so_count=%d, " \
1090 "state=%d, flags=%#x\n", __func__, s->l2so, s->l2so->so_state,
1091 			s->l2so->so_count, s->state, s->flags);
1092 
1093 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1094 		ng_btsocket_rfcomm_session_clean(s);
1095 	}
1096 
1097 	/* Now process upcall */
1098 	switch (s->state) {
1099 	/* Try to accept new L2CAP connection(s) */
1100 	case NG_BTSOCKET_RFCOMM_SESSION_LISTENING:
1101 		while (ng_btsocket_rfcomm_session_accept(s) == 0)
1102 			;
1103 		break;
1104 
1105 	/* Process the results of the L2CAP connect */
1106 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING:
1107 		ng_btsocket_rfcomm_session_process_pcb(s);
1108 
1109 		if (ng_btsocket_rfcomm_session_connect(s) != 0) {
1110 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1111 			ng_btsocket_rfcomm_session_clean(s);
1112 		}
1113 		break;
1114 
1115 	/* Try to receive/send more data */
1116 	case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED:
1117 	case NG_BTSOCKET_RFCOMM_SESSION_OPEN:
1118 	case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING:
1119 		ng_btsocket_rfcomm_session_process_pcb(s);
1120 
1121 		if (ng_btsocket_rfcomm_session_receive(s) != 0) {
1122 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1123 			ng_btsocket_rfcomm_session_clean(s);
1124 		} else if (ng_btsocket_rfcomm_session_send(s) != 0) {
1125 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1126 			ng_btsocket_rfcomm_session_clean(s);
1127 		}
1128 		break;
1129 
1130 	case NG_BTSOCKET_RFCOMM_SESSION_CLOSED:
1131 		break;
1132 
1133 	default:
1134 		panic("%s: Invalid session state=%d, flags=%#x\n",
1135 			__func__, s->state, s->flags);
1136 		break;
1137 	}
1138 } /* ng_btsocket_rfcomm_session_task */
1139 
1140 /*
1141  * Process RFCOMM connection indicator. Caller must hold s->session_mtx
1142  */
1143 
1144 static ng_btsocket_rfcomm_pcb_p
1145 ng_btsocket_rfcomm_connect_ind(ng_btsocket_rfcomm_session_p s, int channel)
1146 {
1147 	ng_btsocket_rfcomm_pcb_p	 pcb = NULL, pcb1 = NULL;
1148 	ng_btsocket_l2cap_pcb_p		 l2pcb = NULL;
1149 	struct socket			*so1 = NULL;
1150 
1151 	mtx_assert(&s->session_mtx, MA_OWNED);
1152 
1153 	/*
1154 	 * Try to find RFCOMM socket that listens on given source address
1155 	 * and channel. This will return the best possible match.
1156 	 */
1157 
1158 	l2pcb = so2l2cap_pcb(s->l2so);
1159 	pcb = ng_btsocket_rfcomm_pcb_listener(&l2pcb->src, channel);
1160 	if (pcb == NULL)
1161 		return (NULL);
1162 
1163 	/*
1164 	 * Check the pending connections queue and if we have space then
1165 	 * create new socket and set proper source and destination address,
1166 	 * and channel.
1167 	 */
1168 
1169 	mtx_lock(&pcb->pcb_mtx);
1170 
1171 	if (pcb->so->so_qlen <= pcb->so->so_qlimit)
1172 		so1 = sonewconn(pcb->so, 0);
1173 
1174 	mtx_unlock(&pcb->pcb_mtx);
1175 
1176 	if (so1 == NULL)
1177 		return (NULL);
1178 
1179 	/*
1180 	 * If we got here than we have created new socket. So complete the
1181 	 * connection. Set source and destination address from the session.
1182 	 */
1183 
1184 	pcb1 = so2rfcomm_pcb(so1);
1185 	if (pcb1 == NULL)
1186 		panic("%s: pcb1 == NULL\n", __func__);
1187 
1188 	mtx_lock(&pcb1->pcb_mtx);
1189 
1190 	bcopy(&l2pcb->src, &pcb1->src, sizeof(pcb1->src));
1191 	bcopy(&l2pcb->dst, &pcb1->dst, sizeof(pcb1->dst));
1192 	pcb1->channel = channel;
1193 
1194 	/* Link new DLC to the session. We already hold s->session_mtx */
1195 	LIST_INSERT_HEAD(&s->dlcs, pcb1, session_next);
1196 	pcb1->session = s;
1197 
1198 	mtx_unlock(&pcb1->pcb_mtx);
1199 
1200 	return (pcb1);
1201 } /* ng_btsocket_rfcomm_connect_ind */
1202 
1203 /*
1204  * Process RFCOMM connect confirmation. Caller must hold s->session_mtx.
1205  */
1206 
1207 static void
1208 ng_btsocket_rfcomm_connect_cfm(ng_btsocket_rfcomm_session_p s)
1209 {
1210 	ng_btsocket_rfcomm_pcb_p	pcb = NULL, pcb_next = NULL;
1211 	int				error;
1212 
1213 	mtx_assert(&s->session_mtx, MA_OWNED);
1214 
1215 	/*
1216 	 * Wake up all waiting sockets and send PN request for each of them.
1217 	 * Note that timeout already been set in ng_btsocket_rfcomm_connect()
1218 	 *
1219 	 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill
1220 	 * will unlink DLC from the session
1221 	 */
1222 
1223 	for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) {
1224 		mtx_lock(&pcb->pcb_mtx);
1225 		pcb_next = LIST_NEXT(pcb, session_next);
1226 
1227 		if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) {
1228 			pcb->mtu = s->mtu;
1229 			bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src,
1230 				sizeof(pcb->src));
1231 
1232 			error = ng_btsocket_rfcomm_send_pn(pcb);
1233 			if (error == 0)
1234 				pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING;
1235 			else
1236 				ng_btsocket_rfcomm_pcb_kill(pcb, error);
1237 		}
1238 
1239 		mtx_unlock(&pcb->pcb_mtx);
1240 		pcb = pcb_next;
1241 	}
1242 } /* ng_btsocket_rfcomm_connect_cfm */
1243 
1244 /*****************************************************************************
1245  *****************************************************************************
1246  **                              RFCOMM sessions
1247  *****************************************************************************
1248  *****************************************************************************/
1249 
1250 /*
1251  * Create new RFCOMM session. That function WILL NOT take ownership over l2so.
1252  * Caller MUST free l2so if function failed.
1253  */
1254 
1255 static int
1256 ng_btsocket_rfcomm_session_create(ng_btsocket_rfcomm_session_p *sp,
1257 		struct socket *l2so, bdaddr_p src, bdaddr_p dst,
1258 		struct thread *td)
1259 {
1260 	ng_btsocket_rfcomm_session_p	s = NULL;
1261 	struct sockaddr_l2cap		l2sa;
1262 	struct sockopt			l2sopt;
1263 	int				error;
1264 	u_int16_t			mtu;
1265 
1266 	mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED);
1267 
1268 	/* Allocate the RFCOMM session */
1269         s = kmalloc(sizeof(*s), M_NETGRAPH_BTSOCKET_RFCOMM,
1270 		    M_WAITOK | M_NULLOK | M_ZERO);
1271         if (s == NULL)
1272                 return (ENOMEM);
1273 
1274 	/* Set defaults */
1275 	s->mtu = RFCOMM_DEFAULT_MTU;
1276 	s->flags = 0;
1277 	s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED;
1278 	NG_BT_MBUFQ_INIT(&s->outq, ifqmaxlen);
1279 
1280 	/*
1281 	 * XXX Mark session mutex as DUPOK to prevent "duplicated lock of
1282 	 * the same type" message. When accepting new L2CAP connection
1283 	 * ng_btsocket_rfcomm_session_accept() holds both session mutexes
1284 	 * for "old" (accepting) session and "new" (created) session.
1285 	 */
1286 
1287 	mtx_init(&s->session_mtx, "btsocks_rfcomm_session_mtx", NULL,
1288 		MTX_DEF|MTX_DUPOK);
1289 
1290 	LIST_INIT(&s->dlcs);
1291 
1292 	/* Prepare L2CAP socket */
1293 	l2so->so_upcallarg = NULL;
1294 	l2so->so_upcall = ng_btsocket_rfcomm_upcall;
1295 	SOCKBUF_LOCK(&l2so->so_rcv);
1296 	l2so->so_rcv.sb_flags |= SB_UPCALL;
1297 	SOCKBUF_UNLOCK(&l2so->so_rcv);
1298 	SOCKBUF_LOCK(&l2so->so_snd);
1299 	l2so->so_snd.sb_flags |= SB_UPCALL;
1300 	SOCKBUF_UNLOCK(&l2so->so_snd);
1301 	sosetstate(l2so, SS_NBIO);
1302 	s->l2so = l2so;
1303 
1304 	mtx_lock(&s->session_mtx);
1305 
1306 	/*
1307 	 * "src" == NULL and "dst" == NULL means just create session.
1308 	 * caller must do the rest
1309 	 */
1310 
1311 	if (src == NULL && dst == NULL)
1312 		goto done;
1313 
1314 	/*
1315 	 * Set incoming MTU on L2CAP socket. It is RFCOMM session default MTU
1316 	 * plus 5 bytes: RFCOMM frame header, one extra byte for length and one
1317 	 * extra byte for credits.
1318 	 */
1319 
1320 	mtu = s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1;
1321 
1322 	l2sopt.sopt_dir = SOPT_SET;
1323 	l2sopt.sopt_level = SOL_L2CAP;
1324 	l2sopt.sopt_name = SO_L2CAP_IMTU;
1325 	l2sopt.sopt_val = (void *) &mtu;
1326 	l2sopt.sopt_valsize = sizeof(mtu);
1327 	l2sopt.sopt_td = NULL;
1328 
1329 	error = sosetopt(s->l2so, &l2sopt);
1330 	if (error != 0)
1331 		goto bad;
1332 
1333 	/* Bind socket to "src" address */
1334 	l2sa.l2cap_len = sizeof(l2sa);
1335 	l2sa.l2cap_family = AF_BLUETOOTH;
1336 	l2sa.l2cap_psm = (dst == NULL)? htole16(NG_L2CAP_PSM_RFCOMM) : 0;
1337 	bcopy(src, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr));
1338 
1339 	error = sobind(s->l2so, (struct sockaddr *) &l2sa, td);
1340 	if (error != 0)
1341 		goto bad;
1342 
1343 	/* If "dst" is not NULL then initiate connect(), otherwise listen() */
1344 	if (dst == NULL) {
1345 		s->flags = 0;
1346 		s->state = NG_BTSOCKET_RFCOMM_SESSION_LISTENING;
1347 
1348 		error = solisten(s->l2so, 10, td);
1349 		if (error != 0)
1350 			goto bad;
1351 	} else {
1352 		s->flags = NG_BTSOCKET_RFCOMM_SESSION_INITIATOR;
1353 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTING;
1354 
1355 		l2sa.l2cap_len = sizeof(l2sa);
1356 		l2sa.l2cap_family = AF_BLUETOOTH;
1357 		l2sa.l2cap_psm = htole16(NG_L2CAP_PSM_RFCOMM);
1358 	        bcopy(dst, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr));
1359 
1360 		error = soconnect(s->l2so, (struct sockaddr *) &l2sa, td);
1361 		if (error != 0)
1362 			goto bad;
1363 	}
1364 
1365 done:
1366 	LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sessions, s, next);
1367 	*sp = s;
1368 
1369 	mtx_unlock(&s->session_mtx);
1370 
1371 	return (0);
1372 
1373 bad:
1374 	mtx_unlock(&s->session_mtx);
1375 
1376 	/* Return L2CAP socket back to its original state */
1377 	l2so->so_upcallarg = NULL;
1378 	l2so->so_upcall = NULL;
1379 	SOCKBUF_LOCK(&l2so->so_rcv);
1380 	l2so->so_rcv.sb_flags &= ~SB_UPCALL;
1381 	SOCKBUF_UNLOCK(&l2so->so_rcv);
1382 	SOCKBUF_LOCK(&l2so->so_snd);
1383 	l2so->so_snd.sb_flags &= ~SB_UPCALL;
1384 	SOCKBUF_UNLOCK(&l2so->so_snd);
1385 	soclrstate(l2so, SS_NBIO);
1386 
1387 	mtx_destroy(&s->session_mtx);
1388 	bzero(s, sizeof(*s));
1389 	kfree(s, M_NETGRAPH_BTSOCKET_RFCOMM);
1390 
1391 	return (error);
1392 } /* ng_btsocket_rfcomm_session_create */
1393 
1394 /*
1395  * Process accept() on RFCOMM session
1396  * XXX FIXME locking for "l2so"?
1397  */
1398 
1399 static int
1400 ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0)
1401 {
1402 	struct socket			*l2so = NULL;
1403 	struct sockaddr_l2cap		*l2sa = NULL;
1404 	ng_btsocket_l2cap_pcb_t		*l2pcb = NULL;
1405 	ng_btsocket_rfcomm_session_p	 s = NULL;
1406 	int				 error = 0;
1407 
1408 	mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED);
1409 	mtx_assert(&s0->session_mtx, MA_OWNED);
1410 
1411 	/* Check if there is a complete L2CAP connection in the queue */
1412 	if ((error = s0->l2so->so_error) != 0) {
1413 		NG_BTSOCKET_RFCOMM_ERR(
1414 "%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error);
1415 		s0->l2so->so_error = 0;
1416 
1417 		return (error);
1418 	}
1419 
1420 	ACCEPT_LOCK();
1421 	if (TAILQ_EMPTY(&s0->l2so->so_comp)) {
1422 		ACCEPT_UNLOCK();
1423 		if (s0->l2so->so_rcv.sb_state & SBS_CANTRCVMORE)
1424 			return (ECONNABORTED);
1425 		return (EWOULDBLOCK);
1426 	}
1427 
1428 	/* Accept incoming L2CAP connection */
1429 	l2so = TAILQ_FIRST(&s0->l2so->so_comp);
1430 	if (l2so == NULL)
1431 		panic("%s: l2so == NULL\n", __func__);
1432 
1433 	TAILQ_REMOVE(&s0->l2so->so_comp, l2so, so_list);
1434 	s0->l2so->so_qlen --;
1435 	l2so->so_qstate &= ~SQ_COMP;
1436 	l2so->so_head = NULL;
1437 	SOCK_LOCK(l2so);
1438 	soref(l2so);
1439 	sosetstate(l2so, SS_NBIO);
1440 	SOCK_UNLOCK(l2so);
1441 	ACCEPT_UNLOCK();
1442 
1443 	error = soaccept(l2so, (struct sockaddr **) &l2sa);
1444 	if (error != 0) {
1445 		NG_BTSOCKET_RFCOMM_ERR(
1446 "%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error);
1447 		soclose(l2so);
1448 
1449 		return (error);
1450 	}
1451 
1452 	/*
1453 	 * Check if there is already active RFCOMM session between two devices.
1454 	 * If so then close L2CAP connection. We only support one RFCOMM session
1455 	 * between each pair of devices. Note that here we assume session in any
1456 	 * state. The session even could be in the middle of disconnecting.
1457 	 */
1458 
1459 	l2pcb = so2l2cap_pcb(l2so);
1460 	s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst);
1461 	if (s == NULL) {
1462 		/* Create a new RFCOMM session */
1463 		error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL,
1464 				curthread /* XXX */);
1465 		if (error == 0) {
1466 			mtx_lock(&s->session_mtx);
1467 
1468 			s->flags = 0;
1469 			s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED;
1470 
1471 			/*
1472 			 * Adjust MTU on incomming connection. Reserve 5 bytes:
1473 			 * RFCOMM frame header, one extra byte for length and
1474 			 * one extra byte for credits.
1475 			 */
1476 
1477 			s->mtu = min(l2pcb->imtu, l2pcb->omtu) -
1478 					sizeof(struct rfcomm_frame_hdr) - 1 - 1;
1479 
1480 			mtx_unlock(&s->session_mtx);
1481 		} else {
1482 			NG_BTSOCKET_RFCOMM_ALERT(
1483 "%s: Failed to create new RFCOMM session, error=%d\n", __func__, error);
1484 
1485 			soclose(l2so);
1486 		}
1487 	} else {
1488 		NG_BTSOCKET_RFCOMM_WARN(
1489 "%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \
1490 "dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n",	__func__,
1491 			l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3],
1492 			l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0],
1493 			l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3],
1494 			l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0],
1495 			s->state, s->flags);
1496 
1497 		error = EBUSY;
1498 		soclose(l2so);
1499 	}
1500 
1501 	return (error);
1502 } /* ng_btsocket_rfcomm_session_accept */
1503 
1504 /*
1505  * Process connect() on RFCOMM session
1506  * XXX FIXME locking for "l2so"?
1507  */
1508 
1509 static int
1510 ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s)
1511 {
1512 	ng_btsocket_l2cap_pcb_p	l2pcb = so2l2cap_pcb(s->l2so);
1513 	int			error;
1514 
1515 	mtx_assert(&s->session_mtx, MA_OWNED);
1516 
1517 	/* First check if connection has failed */
1518 	if ((error = s->l2so->so_error) != 0) {
1519 		s->l2so->so_error = 0;
1520 
1521 		NG_BTSOCKET_RFCOMM_ERR(
1522 "%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n",
1523 			__func__, error, s->state, s->flags);
1524 
1525 		return (error);
1526 	}
1527 
1528 	/* Is connection still in progress? */
1529 	if (s->l2so->so_state & SS_ISCONNECTING)
1530 		return (0);
1531 
1532 	/*
1533 	 * If we got here then we are connected. Send SABM on DLCI 0 to
1534 	 * open multiplexor channel.
1535 	 */
1536 
1537 	if (error == 0) {
1538 		s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED;
1539 
1540 		/*
1541 		 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM
1542 		 * frame header, one extra byte for length and one extra byte
1543 		 * for credits.
1544 		 */
1545 
1546 		s->mtu = min(l2pcb->imtu, l2pcb->omtu) -
1547 				sizeof(struct rfcomm_frame_hdr) - 1 - 1;
1548 
1549 		error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0);
1550 		if (error == 0)
1551 			error = ng_btsocket_rfcomm_task_wakeup();
1552 	}
1553 
1554 	return (error);
1555 }/* ng_btsocket_rfcomm_session_connect */
1556 
1557 /*
1558  * Receive data on RFCOMM session
1559  * XXX FIXME locking for "l2so"?
1560  */
1561 
1562 static int
1563 ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s)
1564 {
1565 	struct mbuf	*m = NULL;
1566 	struct uio	 uio;
1567 	int		 more, flags, error;
1568 
1569 	mtx_assert(&s->session_mtx, MA_OWNED);
1570 
1571 	/* Can we read from the L2CAP socket? */
1572 	if (!soreadable(s->l2so))
1573 		return (0);
1574 
1575 	/* First check for error on L2CAP socket */
1576 	if ((error = s->l2so->so_error) != 0) {
1577 		s->l2so->so_error = 0;
1578 
1579 		NG_BTSOCKET_RFCOMM_ERR(
1580 "%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n",
1581 			__func__, error, s->state, s->flags);
1582 
1583 		return (error);
1584 	}
1585 
1586 	/*
1587 	 * Read all packets from the L2CAP socket.
1588 	 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as
1589 	 * indication that there is more packets on the socket's buffer.
1590 	 * Also what should we use in uio.uio_resid?
1591 	 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1?
1592 	 */
1593 
1594 	for (more = 1; more; ) {
1595 		/* Try to get next packet from socket */
1596 		bzero(&uio, sizeof(uio));
1597 /*		uio.uio_td = NULL; */
1598 		uio.uio_resid = 1000000000;
1599 		flags = MSG_DONTWAIT;
1600 
1601 		m = NULL;
1602 		error = soreceive(s->l2so, NULL, &uio, &m, 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