xref: /netbsd-src/sys/netbt/rfcomm_socket.c (revision aad9773e38ed2370a628a6416e098f9008fc10a7)
1 /*	$NetBSD: rfcomm_socket.c,v 1.33 2014/08/09 05:33:01 rtr Exp $	*/
2 
3 /*-
4  * Copyright (c) 2006 Itronix Inc.
5  * All rights reserved.
6  *
7  * Written by Iain Hibbert for Itronix Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of Itronix Inc. may not be used to endorse
18  *    or promote products derived from this software without specific
19  *    prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.33 2014/08/09 05:33:01 rtr Exp $");
36 
37 /* load symbolic names */
38 #ifdef BLUETOOTH_DEBUG
39 #define PRUREQUESTS
40 #define PRCOREQUESTS
41 #endif
42 
43 #include <sys/param.h>
44 #include <sys/domain.h>
45 #include <sys/kernel.h>
46 #include <sys/mbuf.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/systm.h>
52 
53 #include <netbt/bluetooth.h>
54 #include <netbt/rfcomm.h>
55 
56 /****************************************************************************
57  *
58  *	RFCOMM SOCK_STREAM Sockets - serial line emulation
59  *
60  */
61 
62 static void rfcomm_connecting(void *);
63 static void rfcomm_connected(void *);
64 static void rfcomm_disconnected(void *, int);
65 static void *rfcomm_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
66 static void rfcomm_complete(void *, int);
67 static void rfcomm_linkmode(void *, int);
68 static void rfcomm_input(void *, struct mbuf *);
69 
70 static const struct btproto rfcomm_proto = {
71 	rfcomm_connecting,
72 	rfcomm_connected,
73 	rfcomm_disconnected,
74 	rfcomm_newconn,
75 	rfcomm_complete,
76 	rfcomm_linkmode,
77 	rfcomm_input,
78 };
79 
80 /* sysctl variables */
81 int rfcomm_sendspace = 4096;
82 int rfcomm_recvspace = 4096;
83 
84 static int
85 rfcomm_attach(struct socket *so, int proto)
86 {
87 	int error;
88 
89 	KASSERT(so->so_pcb == NULL);
90 
91 	if (so->so_lock == NULL) {
92 		mutex_obj_hold(bt_lock);
93 		so->so_lock = bt_lock;
94 		solock(so);
95 	}
96 	KASSERT(solocked(so));
97 
98 	/*
99 	 * Since we have nothing to add, we attach the DLC
100 	 * structure directly to our PCB pointer.
101 	 */
102 	error = soreserve(so, rfcomm_sendspace, rfcomm_recvspace);
103 	if (error)
104 		return error;
105 
106 	error = rfcomm_attach_pcb((struct rfcomm_dlc **)&so->so_pcb,
107 				&rfcomm_proto, so);
108 	if (error)
109 		return error;
110 
111 	error = rfcomm_rcvd_pcb(so->so_pcb, sbspace(&so->so_rcv));
112 	if (error) {
113 		rfcomm_detach_pcb((struct rfcomm_dlc **)&so->so_pcb);
114 		return error;
115 	}
116 	return 0;
117 }
118 
119 static void
120 rfcomm_detach(struct socket *so)
121 {
122 	KASSERT(so->so_pcb != NULL);
123 	rfcomm_detach_pcb((struct rfcomm_dlc **)&so->so_pcb);
124 	KASSERT(so->so_pcb == NULL);
125 }
126 
127 static int
128 rfcomm_accept(struct socket *so, struct mbuf *nam)
129 {
130 	struct rfcomm_dlc *pcb = so->so_pcb;
131 	struct sockaddr_bt *sa;
132 
133 	KASSERT(solocked(so));
134 	KASSERT(nam != NULL);
135 
136 	if (pcb == NULL)
137 		return EINVAL;
138 
139 	sa = mtod(nam, struct sockaddr_bt *);
140 	nam->m_len = sizeof(struct sockaddr_bt);
141 	return rfcomm_peeraddr_pcb(pcb, sa);
142 }
143 
144 static int
145 rfcomm_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
146 {
147 	struct rfcomm_dlc *pcb = so->so_pcb;
148 	struct sockaddr_bt *sa;
149 
150 	KASSERT(solocked(so));
151 	KASSERT(nam != NULL);
152 
153 	if (pcb == NULL)
154 		return EINVAL;
155 
156 	sa = mtod(nam, struct sockaddr_bt *);
157 	if (sa->bt_len != sizeof(struct sockaddr_bt))
158 		return EINVAL;
159 
160 	if (sa->bt_family != AF_BLUETOOTH)
161 		return EAFNOSUPPORT;
162 
163 	return rfcomm_bind_pcb(pcb, sa);
164 }
165 
166 static int
167 rfcomm_listen(struct socket *so, struct lwp *l)
168 {
169 	struct rfcomm_dlc *pcb = so->so_pcb;
170 
171 	KASSERT(solocked(so));
172 
173 	if (pcb == NULL)
174 		return EINVAL;
175 
176 	return rfcomm_listen_pcb(pcb);
177 }
178 
179 static int
180 rfcomm_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
181 {
182 	struct rfcomm_dlc *pcb = so->so_pcb;
183 	struct sockaddr_bt *sa;
184 
185 	KASSERT(solocked(so));
186 	KASSERT(nam != NULL);
187 
188 	if (pcb == NULL)
189 		return EINVAL;
190 
191 	sa = mtod(nam, struct sockaddr_bt *);
192 	if (sa->bt_len != sizeof(struct sockaddr_bt))
193 		return EINVAL;
194 
195 	if (sa->bt_family != AF_BLUETOOTH)
196 		return EAFNOSUPPORT;
197 
198 	soisconnecting(so);
199 	return rfcomm_connect_pcb(pcb, sa);
200 }
201 
202 static int
203 rfcomm_connect2(struct socket *so, struct socket *so2)
204 {
205 	struct rfcomm_dlc *pcb = so->so_pcb;
206 
207 	KASSERT(solocked(so));
208 
209 	if (pcb == NULL)
210 		return EINVAL;
211 
212 	return EOPNOTSUPP;
213 }
214 
215 static int
216 rfcomm_disconnect(struct socket *so)
217 {
218 	struct rfcomm_dlc *pcb = so->so_pcb;
219 
220 	KASSERT(solocked(so));
221 
222 	if (pcb == NULL)
223 		return EINVAL;
224 
225 	soisdisconnecting(so);
226 	return rfcomm_disconnect_pcb(pcb, so->so_linger);
227 }
228 
229 static int
230 rfcomm_shutdown(struct socket *so)
231 {
232 	KASSERT(solocked(so));
233 
234 	socantsendmore(so);
235 	return 0;
236 }
237 
238 static int
239 rfcomm_abort(struct socket *so)
240 {
241 	struct rfcomm_dlc *pcb = so->so_pcb;
242 
243 	KASSERT(solocked(so));
244 
245 	if (pcb == NULL)
246 		return EINVAL;
247 
248 	rfcomm_disconnect_pcb(pcb, 0);
249 	soisdisconnected(so);
250 	rfcomm_detach(so);
251 	return 0;
252 }
253 
254 static int
255 rfcomm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
256 {
257 	return EPASSTHROUGH;
258 }
259 
260 static int
261 rfcomm_stat(struct socket *so, struct stat *ub)
262 {
263 	KASSERT(solocked(so));
264 
265 	return 0;
266 }
267 
268 static int
269 rfcomm_peeraddr(struct socket *so, struct mbuf *nam)
270 {
271 	struct rfcomm_dlc *pcb = so->so_pcb;
272 	struct sockaddr_bt *sa;
273 
274 	KASSERT(solocked(so));
275 	KASSERT(pcb != NULL);
276 	KASSERT(nam != NULL);
277 
278 	sa = mtod(nam, struct sockaddr_bt *);
279 	nam->m_len = sizeof(struct sockaddr_bt);
280 	return rfcomm_peeraddr_pcb(pcb, sa);
281 }
282 
283 static int
284 rfcomm_sockaddr(struct socket *so, struct mbuf *nam)
285 {
286 	struct rfcomm_dlc *pcb = so->so_pcb;
287 	struct sockaddr_bt *sa;
288 
289 	KASSERT(solocked(so));
290 	KASSERT(pcb != NULL);
291 	KASSERT(nam != NULL);
292 
293 	sa = mtod(nam, struct sockaddr_bt *);
294 	nam->m_len = sizeof(struct sockaddr_bt);
295 	return rfcomm_sockaddr_pcb(pcb, sa);
296 }
297 
298 static int
299 rfcomm_rcvd(struct socket *so, int flags, struct lwp *l)
300 {
301 	struct rfcomm_dlc *pcb = so->so_pcb;
302 
303 	KASSERT(solocked(so));
304 
305 	if (pcb == NULL)
306 		return EINVAL;
307 
308 	return rfcomm_rcvd_pcb(pcb, sbspace(&so->so_rcv));
309 }
310 
311 static int
312 rfcomm_recvoob(struct socket *so, struct mbuf *m, int flags)
313 {
314 	KASSERT(solocked(so));
315 
316 	return EOPNOTSUPP;
317 }
318 
319 static int
320 rfcomm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
321     struct mbuf *control, struct lwp *l)
322 {
323 	struct rfcomm_dlc *pcb = so->so_pcb;
324 	int err = 0;
325 	struct mbuf *m0;
326 
327 	KASSERT(solocked(so));
328 	KASSERT(m != NULL);
329 
330 	if (control)	/* no use for that */
331 		m_freem(control);
332 
333 	if (pcb == NULL) {
334 		err = EINVAL;
335 		goto release;
336 	}
337 
338 	m0 = m_copypacket(m, M_DONTWAIT);
339 	if (m0 == NULL) {
340 		err = ENOMEM;
341 		goto release;
342 	}
343 
344 	sbappendstream(&so->so_snd, m);
345 	return rfcomm_send_pcb(pcb, m0);
346 
347 release:
348 	m_freem(m);
349 	return err;
350 }
351 
352 static int
353 rfcomm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
354 {
355 	KASSERT(solocked(so));
356 
357 	if (m)
358 		m_freem(m);
359 	if (control)
360 		m_freem(control);
361 
362 	return EOPNOTSUPP;
363 }
364 
365 static int
366 rfcomm_purgeif(struct socket *so, struct ifnet *ifp)
367 {
368 
369 	return EOPNOTSUPP;
370 }
371 
372 /*
373  * User Request.
374  * up is socket
375  * m is optional mbuf chain containing message
376  * ctl is either
377  *	optional mbuf chain containing socket options
378  * l is pointer to process requesting action (if any)
379  *
380  * we are responsible for disposing of m and ctl if
381  * they are mbuf chains
382  */
383 static int
384 rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
385 		struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
386 {
387 	struct rfcomm_dlc *pcb = up->so_pcb;
388 	int err = 0;
389 
390 	DPRINTFN(2, "%s\n", prurequests[req]);
391 	KASSERT(req != PRU_ATTACH);
392 	KASSERT(req != PRU_DETACH);
393 	KASSERT(req != PRU_ACCEPT);
394 	KASSERT(req != PRU_BIND);
395 	KASSERT(req != PRU_LISTEN);
396 	KASSERT(req != PRU_CONNECT);
397 	KASSERT(req != PRU_CONNECT2);
398 	KASSERT(req != PRU_DISCONNECT);
399 	KASSERT(req != PRU_SHUTDOWN);
400 	KASSERT(req != PRU_ABORT);
401 	KASSERT(req != PRU_CONTROL);
402 	KASSERT(req != PRU_SENSE);
403 	KASSERT(req != PRU_PEERADDR);
404 	KASSERT(req != PRU_SOCKADDR);
405 	KASSERT(req != PRU_RCVD);
406 	KASSERT(req != PRU_RCVOOB);
407 	KASSERT(req != PRU_SEND);
408 	KASSERT(req != PRU_SENDOOB);
409 	KASSERT(req != PRU_PURGEIF);
410 
411 	if (pcb == NULL) {
412 		err = EINVAL;
413 		goto release;
414 	}
415 
416 	switch(req) {
417 	case PRU_FASTTIMO:
418 	case PRU_SLOWTIMO:
419 	case PRU_PROTORCV:
420 	case PRU_PROTOSEND:
421 		err = EOPNOTSUPP;
422 		break;
423 
424 	default:
425 		UNKNOWN(req);
426 		err = EOPNOTSUPP;
427 		break;
428 	}
429 
430 release:
431 	if (m) m_freem(m);
432 	if (ctl) m_freem(ctl);
433 	return err;
434 }
435 
436 /*
437  * rfcomm_ctloutput(req, socket, sockopt)
438  *
439  */
440 int
441 rfcomm_ctloutput(int req, struct socket *so, struct sockopt *sopt)
442 {
443 	struct rfcomm_dlc *pcb = so->so_pcb;
444 	int err = 0;
445 
446 	DPRINTFN(2, "%s\n", prcorequests[req]);
447 
448 	if (pcb == NULL)
449 		return EINVAL;
450 
451 	if (sopt->sopt_level != BTPROTO_RFCOMM)
452 		return ENOPROTOOPT;
453 
454 	switch(req) {
455 	case PRCO_GETOPT:
456 		err = rfcomm_getopt(pcb, sopt);
457 		break;
458 
459 	case PRCO_SETOPT:
460 		err = rfcomm_setopt(pcb, sopt);
461 		break;
462 
463 	default:
464 		err = ENOPROTOOPT;
465 		break;
466 	}
467 
468 	return err;
469 }
470 
471 /**********************************************************************
472  *
473  * RFCOMM callbacks
474  */
475 
476 static void
477 rfcomm_connecting(void *arg)
478 {
479 	/* struct socket *so = arg; */
480 
481 	KASSERT(arg != NULL);
482 	DPRINTF("Connecting\n");
483 }
484 
485 static void
486 rfcomm_connected(void *arg)
487 {
488 	struct socket *so = arg;
489 
490 	KASSERT(so != NULL);
491 	DPRINTF("Connected\n");
492 	soisconnected(so);
493 }
494 
495 static void
496 rfcomm_disconnected(void *arg, int err)
497 {
498 	struct socket *so = arg;
499 
500 	KASSERT(so != NULL);
501 	DPRINTF("Disconnected\n");
502 
503 	so->so_error = err;
504 	soisdisconnected(so);
505 }
506 
507 static void *
508 rfcomm_newconn(void *arg, struct sockaddr_bt *laddr,
509     struct sockaddr_bt *raddr)
510 {
511 	struct socket *so = arg;
512 
513 	DPRINTF("New Connection\n");
514 	so = sonewconn(so, false);
515 	if (so == NULL)
516 		return NULL;
517 
518 	soisconnecting(so);
519 
520 	return so->so_pcb;
521 }
522 
523 /*
524  * rfcomm_complete(rfcomm_dlc, length)
525  *
526  * length bytes are sent and may be removed from socket buffer
527  */
528 static void
529 rfcomm_complete(void *arg, int length)
530 {
531 	struct socket *so = arg;
532 
533 	sbdrop(&so->so_snd, length);
534 	sowwakeup(so);
535 }
536 
537 /*
538  * rfcomm_linkmode(rfcomm_dlc, new)
539  *
540  * link mode change notification.
541  */
542 static void
543 rfcomm_linkmode(void *arg, int new)
544 {
545 	struct socket *so = arg;
546 	struct sockopt sopt;
547 	int mode;
548 
549 	DPRINTF("auth %s, encrypt %s, secure %s\n",
550 		(new & RFCOMM_LM_AUTH ? "on" : "off"),
551 		(new & RFCOMM_LM_ENCRYPT ? "on" : "off"),
552 		(new & RFCOMM_LM_SECURE ? "on" : "off"));
553 
554 	sockopt_init(&sopt, BTPROTO_RFCOMM, SO_RFCOMM_LM, 0);
555 	(void)rfcomm_getopt(so->so_pcb, &sopt);
556 	(void)sockopt_getint(&sopt, &mode);
557 	sockopt_destroy(&sopt);
558 
559 	if (((mode & RFCOMM_LM_AUTH) && !(new & RFCOMM_LM_AUTH))
560 	    || ((mode & RFCOMM_LM_ENCRYPT) && !(new & RFCOMM_LM_ENCRYPT))
561 	    || ((mode & RFCOMM_LM_SECURE) && !(new & RFCOMM_LM_SECURE)))
562 		rfcomm_disconnect_pcb(so->so_pcb, 0);
563 }
564 
565 /*
566  * rfcomm_input(rfcomm_dlc, mbuf)
567  */
568 static void
569 rfcomm_input(void *arg, struct mbuf *m)
570 {
571 	struct socket *so = arg;
572 
573 	KASSERT(so != NULL);
574 
575 	if (m->m_pkthdr.len > sbspace(&so->so_rcv)) {
576 		printf("%s: %d bytes dropped (socket buffer full)\n",
577 			__func__, m->m_pkthdr.len);
578 		m_freem(m);
579 		return;
580 	}
581 
582 	DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len);
583 
584 	sbappendstream(&so->so_rcv, m);
585 	sorwakeup(so);
586 }
587 
588 PR_WRAP_USRREQS(rfcomm)
589 
590 #define	rfcomm_attach		rfcomm_attach_wrapper
591 #define	rfcomm_detach		rfcomm_detach_wrapper
592 #define	rfcomm_accept		rfcomm_accept_wrapper
593 #define	rfcomm_bind		rfcomm_bind_wrapper
594 #define	rfcomm_listen		rfcomm_listen_wrapper
595 #define	rfcomm_connect		rfcomm_connect_wrapper
596 #define	rfcomm_connect2		rfcomm_connect2_wrapper
597 #define	rfcomm_disconnect	rfcomm_disconnect_wrapper
598 #define	rfcomm_shutdown		rfcomm_shutdown_wrapper
599 #define	rfcomm_abort		rfcomm_abort_wrapper
600 #define	rfcomm_ioctl		rfcomm_ioctl_wrapper
601 #define	rfcomm_stat		rfcomm_stat_wrapper
602 #define	rfcomm_peeraddr		rfcomm_peeraddr_wrapper
603 #define	rfcomm_sockaddr		rfcomm_sockaddr_wrapper
604 #define	rfcomm_rcvd		rfcomm_rcvd_wrapper
605 #define	rfcomm_recvoob		rfcomm_recvoob_wrapper
606 #define	rfcomm_send		rfcomm_send_wrapper
607 #define	rfcomm_sendoob		rfcomm_sendoob_wrapper
608 #define	rfcomm_purgeif		rfcomm_purgeif_wrapper
609 #define	rfcomm_usrreq		rfcomm_usrreq_wrapper
610 
611 const struct pr_usrreqs rfcomm_usrreqs = {
612 	.pr_attach	= rfcomm_attach,
613 	.pr_detach	= rfcomm_detach,
614 	.pr_accept	= rfcomm_accept,
615 	.pr_bind	= rfcomm_bind,
616 	.pr_listen	= rfcomm_listen,
617 	.pr_connect	= rfcomm_connect,
618 	.pr_connect2	= rfcomm_connect2,
619 	.pr_disconnect	= rfcomm_disconnect,
620 	.pr_shutdown	= rfcomm_shutdown,
621 	.pr_abort	= rfcomm_abort,
622 	.pr_ioctl	= rfcomm_ioctl,
623 	.pr_stat	= rfcomm_stat,
624 	.pr_peeraddr	= rfcomm_peeraddr,
625 	.pr_sockaddr	= rfcomm_sockaddr,
626 	.pr_rcvd	= rfcomm_rcvd,
627 	.pr_recvoob	= rfcomm_recvoob,
628 	.pr_send	= rfcomm_send,
629 	.pr_sendoob	= rfcomm_sendoob,
630 	.pr_purgeif	= rfcomm_purgeif,
631 	.pr_generic	= rfcomm_usrreq,
632 };
633