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