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