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