1 /* $NetBSD: rfcomm_socket.c,v 1.34 2015/04/03 20:01:07 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.34 2015/04/03 20:01:07 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 sockaddr *nam, struct lwp *l) 146 { 147 struct rfcomm_dlc *pcb = so->so_pcb; 148 struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; 149 150 KASSERT(solocked(so)); 151 KASSERT(nam != NULL); 152 153 if (pcb == NULL) 154 return EINVAL; 155 156 if (sa->bt_len != sizeof(struct sockaddr_bt)) 157 return EINVAL; 158 159 if (sa->bt_family != AF_BLUETOOTH) 160 return EAFNOSUPPORT; 161 162 return rfcomm_bind_pcb(pcb, sa); 163 } 164 165 static int 166 rfcomm_listen(struct socket *so, struct lwp *l) 167 { 168 struct rfcomm_dlc *pcb = so->so_pcb; 169 170 KASSERT(solocked(so)); 171 172 if (pcb == NULL) 173 return EINVAL; 174 175 return rfcomm_listen_pcb(pcb); 176 } 177 178 static int 179 rfcomm_connect(struct socket *so, struct mbuf *nam, struct lwp *l) 180 { 181 struct rfcomm_dlc *pcb = so->so_pcb; 182 struct sockaddr_bt *sa; 183 184 KASSERT(solocked(so)); 185 KASSERT(nam != NULL); 186 187 if (pcb == NULL) 188 return EINVAL; 189 190 sa = mtod(nam, struct sockaddr_bt *); 191 if (sa->bt_len != sizeof(struct sockaddr_bt)) 192 return EINVAL; 193 194 if (sa->bt_family != AF_BLUETOOTH) 195 return EAFNOSUPPORT; 196 197 soisconnecting(so); 198 return rfcomm_connect_pcb(pcb, sa); 199 } 200 201 static int 202 rfcomm_connect2(struct socket *so, struct socket *so2) 203 { 204 struct rfcomm_dlc *pcb = so->so_pcb; 205 206 KASSERT(solocked(so)); 207 208 if (pcb == NULL) 209 return EINVAL; 210 211 return EOPNOTSUPP; 212 } 213 214 static int 215 rfcomm_disconnect(struct socket *so) 216 { 217 struct rfcomm_dlc *pcb = so->so_pcb; 218 219 KASSERT(solocked(so)); 220 221 if (pcb == NULL) 222 return EINVAL; 223 224 soisdisconnecting(so); 225 return rfcomm_disconnect_pcb(pcb, so->so_linger); 226 } 227 228 static int 229 rfcomm_shutdown(struct socket *so) 230 { 231 KASSERT(solocked(so)); 232 233 socantsendmore(so); 234 return 0; 235 } 236 237 static int 238 rfcomm_abort(struct socket *so) 239 { 240 struct rfcomm_dlc *pcb = so->so_pcb; 241 242 KASSERT(solocked(so)); 243 244 if (pcb == NULL) 245 return EINVAL; 246 247 rfcomm_disconnect_pcb(pcb, 0); 248 soisdisconnected(so); 249 rfcomm_detach(so); 250 return 0; 251 } 252 253 static int 254 rfcomm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 255 { 256 return EPASSTHROUGH; 257 } 258 259 static int 260 rfcomm_stat(struct socket *so, struct stat *ub) 261 { 262 KASSERT(solocked(so)); 263 264 return 0; 265 } 266 267 static int 268 rfcomm_peeraddr(struct socket *so, struct mbuf *nam) 269 { 270 struct rfcomm_dlc *pcb = so->so_pcb; 271 struct sockaddr_bt *sa; 272 273 KASSERT(solocked(so)); 274 KASSERT(pcb != NULL); 275 KASSERT(nam != NULL); 276 277 sa = mtod(nam, struct sockaddr_bt *); 278 nam->m_len = sizeof(struct sockaddr_bt); 279 return rfcomm_peeraddr_pcb(pcb, sa); 280 } 281 282 static int 283 rfcomm_sockaddr(struct socket *so, struct mbuf *nam) 284 { 285 struct rfcomm_dlc *pcb = so->so_pcb; 286 struct sockaddr_bt *sa; 287 288 KASSERT(solocked(so)); 289 KASSERT(pcb != NULL); 290 KASSERT(nam != NULL); 291 292 sa = mtod(nam, struct sockaddr_bt *); 293 nam->m_len = sizeof(struct sockaddr_bt); 294 return rfcomm_sockaddr_pcb(pcb, sa); 295 } 296 297 static int 298 rfcomm_rcvd(struct socket *so, int flags, struct lwp *l) 299 { 300 struct rfcomm_dlc *pcb = so->so_pcb; 301 302 KASSERT(solocked(so)); 303 304 if (pcb == NULL) 305 return EINVAL; 306 307 return rfcomm_rcvd_pcb(pcb, sbspace(&so->so_rcv)); 308 } 309 310 static int 311 rfcomm_recvoob(struct socket *so, struct mbuf *m, int flags) 312 { 313 KASSERT(solocked(so)); 314 315 return EOPNOTSUPP; 316 } 317 318 static int 319 rfcomm_send(struct socket *so, struct mbuf *m, struct mbuf *nam, 320 struct mbuf *control, struct lwp *l) 321 { 322 struct rfcomm_dlc *pcb = so->so_pcb; 323 int err = 0; 324 struct mbuf *m0; 325 326 KASSERT(solocked(so)); 327 KASSERT(m != NULL); 328 329 if (control) /* no use for that */ 330 m_freem(control); 331 332 if (pcb == NULL) { 333 err = EINVAL; 334 goto release; 335 } 336 337 m0 = m_copypacket(m, M_DONTWAIT); 338 if (m0 == NULL) { 339 err = ENOMEM; 340 goto release; 341 } 342 343 sbappendstream(&so->so_snd, m); 344 return rfcomm_send_pcb(pcb, m0); 345 346 release: 347 m_freem(m); 348 return err; 349 } 350 351 static int 352 rfcomm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 353 { 354 KASSERT(solocked(so)); 355 356 if (m) 357 m_freem(m); 358 if (control) 359 m_freem(control); 360 361 return EOPNOTSUPP; 362 } 363 364 static int 365 rfcomm_purgeif(struct socket *so, struct ifnet *ifp) 366 { 367 368 return EOPNOTSUPP; 369 } 370 371 /* 372 * User Request. 373 * up is socket 374 * m is optional mbuf chain containing message 375 * ctl is either 376 * optional mbuf chain containing socket options 377 * l is pointer to process requesting action (if any) 378 * 379 * we are responsible for disposing of m and ctl if 380 * they are mbuf chains 381 */ 382 static int 383 rfcomm_usrreq(struct socket *up, int req, struct mbuf *m, 384 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) 385 { 386 struct rfcomm_dlc *pcb = up->so_pcb; 387 int err = 0; 388 389 DPRINTFN(2, "%s\n", prurequests[req]); 390 KASSERT(req != PRU_ATTACH); 391 KASSERT(req != PRU_DETACH); 392 KASSERT(req != PRU_ACCEPT); 393 KASSERT(req != PRU_BIND); 394 KASSERT(req != PRU_LISTEN); 395 KASSERT(req != PRU_CONNECT); 396 KASSERT(req != PRU_CONNECT2); 397 KASSERT(req != PRU_DISCONNECT); 398 KASSERT(req != PRU_SHUTDOWN); 399 KASSERT(req != PRU_ABORT); 400 KASSERT(req != PRU_CONTROL); 401 KASSERT(req != PRU_SENSE); 402 KASSERT(req != PRU_PEERADDR); 403 KASSERT(req != PRU_SOCKADDR); 404 KASSERT(req != PRU_RCVD); 405 KASSERT(req != PRU_RCVOOB); 406 KASSERT(req != PRU_SEND); 407 KASSERT(req != PRU_SENDOOB); 408 KASSERT(req != PRU_PURGEIF); 409 410 if (pcb == NULL) { 411 err = EINVAL; 412 goto release; 413 } 414 415 switch(req) { 416 case PRU_FASTTIMO: 417 case PRU_SLOWTIMO: 418 case PRU_PROTORCV: 419 case PRU_PROTOSEND: 420 err = EOPNOTSUPP; 421 break; 422 423 default: 424 UNKNOWN(req); 425 err = EOPNOTSUPP; 426 break; 427 } 428 429 release: 430 if (m) m_freem(m); 431 if (ctl) m_freem(ctl); 432 return err; 433 } 434 435 /* 436 * rfcomm_ctloutput(req, socket, sockopt) 437 * 438 */ 439 int 440 rfcomm_ctloutput(int req, struct socket *so, struct sockopt *sopt) 441 { 442 struct rfcomm_dlc *pcb = so->so_pcb; 443 int err = 0; 444 445 DPRINTFN(2, "%s\n", prcorequests[req]); 446 447 if (pcb == NULL) 448 return EINVAL; 449 450 if (sopt->sopt_level != BTPROTO_RFCOMM) 451 return ENOPROTOOPT; 452 453 switch(req) { 454 case PRCO_GETOPT: 455 err = rfcomm_getopt(pcb, sopt); 456 break; 457 458 case PRCO_SETOPT: 459 err = rfcomm_setopt(pcb, sopt); 460 break; 461 462 default: 463 err = ENOPROTOOPT; 464 break; 465 } 466 467 return err; 468 } 469 470 /********************************************************************** 471 * 472 * RFCOMM callbacks 473 */ 474 475 static void 476 rfcomm_connecting(void *arg) 477 { 478 /* struct socket *so = arg; */ 479 480 KASSERT(arg != NULL); 481 DPRINTF("Connecting\n"); 482 } 483 484 static void 485 rfcomm_connected(void *arg) 486 { 487 struct socket *so = arg; 488 489 KASSERT(so != NULL); 490 DPRINTF("Connected\n"); 491 soisconnected(so); 492 } 493 494 static void 495 rfcomm_disconnected(void *arg, int err) 496 { 497 struct socket *so = arg; 498 499 KASSERT(so != NULL); 500 DPRINTF("Disconnected\n"); 501 502 so->so_error = err; 503 soisdisconnected(so); 504 } 505 506 static void * 507 rfcomm_newconn(void *arg, struct sockaddr_bt *laddr, 508 struct sockaddr_bt *raddr) 509 { 510 struct socket *so = arg; 511 512 DPRINTF("New Connection\n"); 513 so = sonewconn(so, false); 514 if (so == NULL) 515 return NULL; 516 517 soisconnecting(so); 518 519 return so->so_pcb; 520 } 521 522 /* 523 * rfcomm_complete(rfcomm_dlc, length) 524 * 525 * length bytes are sent and may be removed from socket buffer 526 */ 527 static void 528 rfcomm_complete(void *arg, int length) 529 { 530 struct socket *so = arg; 531 532 sbdrop(&so->so_snd, length); 533 sowwakeup(so); 534 } 535 536 /* 537 * rfcomm_linkmode(rfcomm_dlc, new) 538 * 539 * link mode change notification. 540 */ 541 static void 542 rfcomm_linkmode(void *arg, int new) 543 { 544 struct socket *so = arg; 545 struct sockopt sopt; 546 int mode; 547 548 DPRINTF("auth %s, encrypt %s, secure %s\n", 549 (new & RFCOMM_LM_AUTH ? "on" : "off"), 550 (new & RFCOMM_LM_ENCRYPT ? "on" : "off"), 551 (new & RFCOMM_LM_SECURE ? "on" : "off")); 552 553 sockopt_init(&sopt, BTPROTO_RFCOMM, SO_RFCOMM_LM, 0); 554 (void)rfcomm_getopt(so->so_pcb, &sopt); 555 (void)sockopt_getint(&sopt, &mode); 556 sockopt_destroy(&sopt); 557 558 if (((mode & RFCOMM_LM_AUTH) && !(new & RFCOMM_LM_AUTH)) 559 || ((mode & RFCOMM_LM_ENCRYPT) && !(new & RFCOMM_LM_ENCRYPT)) 560 || ((mode & RFCOMM_LM_SECURE) && !(new & RFCOMM_LM_SECURE))) 561 rfcomm_disconnect_pcb(so->so_pcb, 0); 562 } 563 564 /* 565 * rfcomm_input(rfcomm_dlc, mbuf) 566 */ 567 static void 568 rfcomm_input(void *arg, struct mbuf *m) 569 { 570 struct socket *so = arg; 571 572 KASSERT(so != NULL); 573 574 if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { 575 printf("%s: %d bytes dropped (socket buffer full)\n", 576 __func__, m->m_pkthdr.len); 577 m_freem(m); 578 return; 579 } 580 581 DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); 582 583 sbappendstream(&so->so_rcv, m); 584 sorwakeup(so); 585 } 586 587 PR_WRAP_USRREQS(rfcomm) 588 589 #define rfcomm_attach rfcomm_attach_wrapper 590 #define rfcomm_detach rfcomm_detach_wrapper 591 #define rfcomm_accept rfcomm_accept_wrapper 592 #define rfcomm_bind rfcomm_bind_wrapper 593 #define rfcomm_listen rfcomm_listen_wrapper 594 #define rfcomm_connect rfcomm_connect_wrapper 595 #define rfcomm_connect2 rfcomm_connect2_wrapper 596 #define rfcomm_disconnect rfcomm_disconnect_wrapper 597 #define rfcomm_shutdown rfcomm_shutdown_wrapper 598 #define rfcomm_abort rfcomm_abort_wrapper 599 #define rfcomm_ioctl rfcomm_ioctl_wrapper 600 #define rfcomm_stat rfcomm_stat_wrapper 601 #define rfcomm_peeraddr rfcomm_peeraddr_wrapper 602 #define rfcomm_sockaddr rfcomm_sockaddr_wrapper 603 #define rfcomm_rcvd rfcomm_rcvd_wrapper 604 #define rfcomm_recvoob rfcomm_recvoob_wrapper 605 #define rfcomm_send rfcomm_send_wrapper 606 #define rfcomm_sendoob rfcomm_sendoob_wrapper 607 #define rfcomm_purgeif rfcomm_purgeif_wrapper 608 #define rfcomm_usrreq rfcomm_usrreq_wrapper 609 610 const struct pr_usrreqs rfcomm_usrreqs = { 611 .pr_attach = rfcomm_attach, 612 .pr_detach = rfcomm_detach, 613 .pr_accept = rfcomm_accept, 614 .pr_bind = rfcomm_bind, 615 .pr_listen = rfcomm_listen, 616 .pr_connect = rfcomm_connect, 617 .pr_connect2 = rfcomm_connect2, 618 .pr_disconnect = rfcomm_disconnect, 619 .pr_shutdown = rfcomm_shutdown, 620 .pr_abort = rfcomm_abort, 621 .pr_ioctl = rfcomm_ioctl, 622 .pr_stat = rfcomm_stat, 623 .pr_peeraddr = rfcomm_peeraddr, 624 .pr_sockaddr = rfcomm_sockaddr, 625 .pr_rcvd = rfcomm_rcvd, 626 .pr_recvoob = rfcomm_recvoob, 627 .pr_send = rfcomm_send, 628 .pr_sendoob = rfcomm_sendoob, 629 .pr_purgeif = rfcomm_purgeif, 630 .pr_generic = rfcomm_usrreq, 631 }; 632