1 /* $DragonFly: src/sys/netbt/rfcomm_upper.c,v 1.3 2008/06/20 20:52:29 aggelos Exp $ */ 2 /* $OpenBSD: src/sys/netbt/rfcomm_upper.c,v 1.4 2008/02/24 21:34:48 uwe Exp $ */ 3 /* $NetBSD: rfcomm_upper.c,v 1.10 2007/11/20 20:25:57 plunky Exp $ */ 4 5 /*- 6 * Copyright (c) 2006 Itronix Inc. 7 * All rights reserved. 8 * 9 * Written by Iain Hibbert for Itronix Inc. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of Itronix Inc. may not be used to endorse 20 * or promote products derived from this software without specific 21 * prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/param.h> 37 #include <sys/kernel.h> 38 #include <sys/mbuf.h> 39 #include <sys/proc.h> 40 #include <sys/systm.h> 41 #include <sys/socketvar.h> 42 43 #include <netbt/bluetooth.h> 44 #include <netbt/hci.h> 45 #include <netbt/l2cap.h> 46 #include <netbt/rfcomm.h> 47 48 /**************************************************************************** 49 * 50 * RFCOMM DLC - Upper Protocol API 51 * 52 * Currently the only 'Port Emulation Entity' is the RFCOMM socket code 53 * but it is should be possible to provide a pseudo-device for a direct 54 * tty interface. 55 */ 56 57 /* 58 * rfcomm_attach(handle, proto, upper) 59 * 60 * attach a new RFCOMM DLC to handle, populate with reasonable defaults 61 */ 62 int 63 rfcomm_attach(struct rfcomm_dlc **handle, 64 const struct btproto *proto, void *upper) 65 { 66 struct rfcomm_dlc *dlc; 67 68 KKASSERT(handle != NULL); 69 KKASSERT(proto != NULL); 70 KKASSERT(upper != NULL); 71 72 dlc = kmalloc(sizeof(*dlc), M_BLUETOOTH, M_NOWAIT | M_ZERO); 73 if (dlc == NULL) 74 return ENOMEM; 75 76 dlc->rd_state = RFCOMM_DLC_CLOSED; 77 dlc->rd_mtu = rfcomm_mtu_default; 78 79 dlc->rd_proto = proto; 80 dlc->rd_upper = upper; 81 82 dlc->rd_laddr.bt_len = sizeof(struct sockaddr_bt); 83 dlc->rd_laddr.bt_family = AF_BLUETOOTH; 84 dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM; 85 86 dlc->rd_raddr.bt_len = sizeof(struct sockaddr_bt); 87 dlc->rd_raddr.bt_family = AF_BLUETOOTH; 88 dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM; 89 90 dlc->rd_lmodem = RFCOMM_MSC_RTC | RFCOMM_MSC_RTR | RFCOMM_MSC_DV; 91 92 callout_init(&dlc->rd_timeout); 93 94 *handle = dlc; 95 return 0; 96 } 97 98 /* 99 * rfcomm_bind(dlc, sockaddr) 100 * 101 * bind DLC to local address 102 */ 103 int 104 rfcomm_bind(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr) 105 { 106 107 memcpy(&dlc->rd_laddr, addr, sizeof(struct sockaddr_bt)); 108 return 0; 109 } 110 111 /* 112 * rfcomm_sockaddr(dlc, sockaddr) 113 * 114 * return local address 115 */ 116 int 117 rfcomm_sockaddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr) 118 { 119 120 memcpy(addr, &dlc->rd_laddr, sizeof(struct sockaddr_bt)); 121 return 0; 122 } 123 124 /* 125 * rfcomm_connect(dlc, sockaddr) 126 * 127 * Initiate connection of RFCOMM DLC to remote address. 128 */ 129 int 130 rfcomm_connect(struct rfcomm_dlc *dlc, struct sockaddr_bt *dest) 131 { 132 struct rfcomm_session *rs; 133 int err = 0; 134 135 if (dlc->rd_state != RFCOMM_DLC_CLOSED) 136 return EISCONN; 137 138 memcpy(&dlc->rd_raddr, dest, sizeof(struct sockaddr_bt)); 139 140 if (dlc->rd_raddr.bt_channel < RFCOMM_CHANNEL_MIN 141 || dlc->rd_raddr.bt_channel > RFCOMM_CHANNEL_MAX 142 || bdaddr_any(&dlc->rd_raddr.bt_bdaddr)) 143 return EDESTADDRREQ; 144 145 if (dlc->rd_raddr.bt_psm == L2CAP_PSM_ANY) 146 dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM; 147 else if (dlc->rd_raddr.bt_psm != L2CAP_PSM_RFCOMM 148 && (dlc->rd_raddr.bt_psm < 0x1001 149 || L2CAP_PSM_INVALID(dlc->rd_raddr.bt_psm))) 150 return EINVAL; 151 152 /* 153 * We are allowed only one RFCOMM session between any 2 Bluetooth 154 * devices, so see if there is a session already otherwise create 155 * one and set it connecting. 156 */ 157 rs = rfcomm_session_lookup(&dlc->rd_laddr, &dlc->rd_raddr); 158 if (rs == NULL) { 159 rs = rfcomm_session_alloc(&rfcomm_session_active, 160 &dlc->rd_laddr); 161 if (rs == NULL) 162 return ENOMEM; 163 164 rs->rs_flags |= RFCOMM_SESSION_INITIATOR; 165 rs->rs_state = RFCOMM_SESSION_WAIT_CONNECT; 166 167 err = l2cap_connect(rs->rs_l2cap, &dlc->rd_raddr); 168 if (err) { 169 rfcomm_session_free(rs); 170 return err; 171 } 172 173 /* 174 * This session will start up automatically when its 175 * L2CAP channel is connected. 176 */ 177 } 178 179 /* construct DLC */ 180 dlc->rd_dlci = RFCOMM_MKDLCI(IS_INITIATOR(rs) ? 0:1, dest->bt_channel); 181 if (rfcomm_dlc_lookup(rs, dlc->rd_dlci)) 182 return EBUSY; 183 184 l2cap_sockaddr(rs->rs_l2cap, &dlc->rd_laddr); 185 186 /* 187 * attach the DLC to the session and start it off 188 */ 189 dlc->rd_session = rs; 190 dlc->rd_state = RFCOMM_DLC_WAIT_SESSION; 191 LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next); 192 193 if (rs->rs_state == RFCOMM_SESSION_OPEN) 194 err = rfcomm_dlc_connect(dlc); 195 196 return err; 197 } 198 199 /* 200 * rfcomm_peeraddr(dlc, sockaddr) 201 * 202 * return remote address 203 */ 204 int 205 rfcomm_peeraddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr) 206 { 207 208 memcpy(addr, &dlc->rd_raddr, sizeof(struct sockaddr_bt)); 209 return 0; 210 } 211 212 /* 213 * rfcomm_disconnect(dlc, linger) 214 * 215 * disconnect RFCOMM DLC 216 */ 217 int 218 rfcomm_disconnect(struct rfcomm_dlc *dlc, int linger) 219 { 220 struct rfcomm_session *rs = dlc->rd_session; 221 int err = 0; 222 223 KKASSERT(dlc != NULL); 224 225 switch (dlc->rd_state) { 226 case RFCOMM_DLC_CLOSED: 227 case RFCOMM_DLC_LISTEN: 228 return EINVAL; 229 230 case RFCOMM_DLC_WAIT_SEND_UA: 231 err = rfcomm_session_send_frame(rs, 232 RFCOMM_FRAME_DM, dlc->rd_dlci); 233 234 /* fall through */ 235 case RFCOMM_DLC_WAIT_SESSION: 236 case RFCOMM_DLC_WAIT_CONNECT: 237 case RFCOMM_DLC_WAIT_SEND_SABM: 238 rfcomm_dlc_close(dlc, 0); 239 break; 240 241 case RFCOMM_DLC_OPEN: 242 if (dlc->rd_txbuf != NULL && linger != 0) { 243 dlc->rd_flags |= RFCOMM_DLC_SHUTDOWN; 244 break; 245 } 246 247 /* else fall through */ 248 case RFCOMM_DLC_WAIT_RECV_UA: 249 dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT; 250 err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 251 dlc->rd_dlci); 252 callout_reset(&dlc->rd_timeout, rfcomm_ack_timeout * hz, 253 rfcomm_dlc_timeout, dlc); 254 break; 255 256 case RFCOMM_DLC_WAIT_DISCONNECT: 257 err = EALREADY; 258 break; 259 260 default: 261 UNKNOWN(dlc->rd_state); 262 break; 263 } 264 265 return err; 266 } 267 268 /* 269 * rfcomm_detach(handle) 270 * 271 * detach RFCOMM DLC from handle 272 */ 273 int 274 rfcomm_detach(struct rfcomm_dlc **handle) 275 { 276 struct rfcomm_dlc *dlc = *handle; 277 278 if (dlc->rd_state != RFCOMM_DLC_CLOSED) 279 rfcomm_dlc_close(dlc, 0); 280 281 if (dlc->rd_txbuf != NULL) { 282 m_freem(dlc->rd_txbuf); 283 dlc->rd_txbuf = NULL; 284 } 285 286 dlc->rd_upper = NULL; 287 *handle = NULL; 288 289 /* 290 * If callout is invoking we can't free the DLC so 291 * mark it and let the callout release it. 292 */ 293 if (callout_active(&dlc->rd_timeout)) 294 dlc->rd_flags |= RFCOMM_DLC_DETACH; 295 else 296 kfree(dlc, M_BLUETOOTH); 297 298 return 0; 299 } 300 301 /* 302 * rfcomm_listen(dlc) 303 * 304 * This DLC is a listener. We look for an existing listening session 305 * with a matching address to attach to or else create a new one on 306 * the listeners list. If the ANY channel is given, allocate the first 307 * available for the session. 308 */ 309 int 310 rfcomm_listen(struct rfcomm_dlc *dlc) 311 { 312 struct rfcomm_session *rs; 313 struct rfcomm_dlc *used; 314 struct sockaddr_bt addr; 315 int err, channel; 316 317 if (dlc->rd_state != RFCOMM_DLC_CLOSED) 318 return EISCONN; 319 320 if (dlc->rd_laddr.bt_channel != RFCOMM_CHANNEL_ANY 321 && (dlc->rd_laddr.bt_channel < RFCOMM_CHANNEL_MIN 322 || dlc->rd_laddr.bt_channel > RFCOMM_CHANNEL_MAX)) 323 return EADDRNOTAVAIL; 324 325 if (dlc->rd_laddr.bt_psm == L2CAP_PSM_ANY) 326 dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM; 327 else if (dlc->rd_laddr.bt_psm != L2CAP_PSM_RFCOMM 328 && (dlc->rd_laddr.bt_psm < 0x1001 329 || L2CAP_PSM_INVALID(dlc->rd_laddr.bt_psm))) 330 return EADDRNOTAVAIL; 331 332 LIST_FOREACH(rs, &rfcomm_session_listen, rs_next) { 333 l2cap_sockaddr(rs->rs_l2cap, &addr); 334 335 if (addr.bt_psm != dlc->rd_laddr.bt_psm) 336 continue; 337 338 if (bdaddr_same(&dlc->rd_laddr.bt_bdaddr, &addr.bt_bdaddr)) 339 break; 340 } 341 342 if (rs == NULL) { 343 rs = rfcomm_session_alloc(&rfcomm_session_listen, 344 &dlc->rd_laddr); 345 if (rs == NULL) 346 return ENOMEM; 347 348 rs->rs_state = RFCOMM_SESSION_LISTEN; 349 350 err = l2cap_listen(rs->rs_l2cap); 351 if (err) { 352 rfcomm_session_free(rs); 353 return err; 354 } 355 } 356 357 if (dlc->rd_laddr.bt_channel == RFCOMM_CHANNEL_ANY) { 358 channel = RFCOMM_CHANNEL_MIN; 359 used = LIST_FIRST(&rs->rs_dlcs); 360 361 while (used != NULL) { 362 if (used->rd_laddr.bt_channel == channel) { 363 if (channel++ == RFCOMM_CHANNEL_MAX) 364 return EADDRNOTAVAIL; 365 366 used = LIST_FIRST(&rs->rs_dlcs); 367 } else { 368 used = LIST_NEXT(used, rd_next); 369 } 370 } 371 372 dlc->rd_laddr.bt_channel = channel; 373 } 374 375 dlc->rd_session = rs; 376 dlc->rd_state = RFCOMM_DLC_LISTEN; 377 LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next); 378 379 return 0; 380 } 381 382 /* 383 * rfcomm_send(dlc, mbuf) 384 * 385 * Output data on DLC. This is streamed data, so we add it 386 * to our buffer and start the DLC, which will assemble 387 * packets and send them if it can. 388 */ 389 int 390 rfcomm_send(struct rfcomm_dlc *dlc, struct mbuf *m) 391 { 392 393 if (dlc->rd_txbuf != NULL) { 394 dlc->rd_txbuf->m_pkthdr.len += m->m_pkthdr.len; 395 m_cat(dlc->rd_txbuf, m); 396 } else { 397 dlc->rd_txbuf = m; 398 } 399 400 if (dlc->rd_state == RFCOMM_DLC_OPEN) 401 rfcomm_dlc_start(dlc); 402 403 return 0; 404 } 405 406 /* 407 * rfcomm_rcvd(dlc, space) 408 * 409 * Indicate space now available in receive buffer 410 * 411 * This should be used to give an initial value of the receive buffer 412 * size when the DLC is attached and anytime data is cleared from the 413 * buffer after that. 414 */ 415 int 416 rfcomm_rcvd(struct rfcomm_dlc *dlc, size_t space) 417 { 418 419 KKASSERT(dlc != NULL); 420 421 dlc->rd_rxsize = space; 422 423 /* 424 * if we are using credit based flow control, we may 425 * want to send some credits.. 426 */ 427 if (dlc->rd_state == RFCOMM_DLC_OPEN 428 && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC)) 429 rfcomm_dlc_start(dlc); 430 431 return 0; 432 } 433 434 /* 435 * rfcomm_setopt(dlc, option, addr) 436 * 437 * set DLC options 438 */ 439 int 440 rfcomm_setopt(struct rfcomm_dlc *dlc, int opt, void *addr) 441 { 442 int mode, err = 0; 443 uint16_t mtu; 444 445 switch (opt) { 446 case SO_RFCOMM_MTU: 447 mtu = *(uint16_t *)addr; 448 if (mtu < RFCOMM_MTU_MIN || mtu > RFCOMM_MTU_MAX) 449 err = EINVAL; 450 else if (dlc->rd_state == RFCOMM_DLC_CLOSED) 451 dlc->rd_mtu = mtu; 452 else 453 err = EBUSY; 454 455 break; 456 457 case SO_RFCOMM_LM: 458 mode = *(int *)addr; 459 mode &= (RFCOMM_LM_SECURE | RFCOMM_LM_ENCRYPT | RFCOMM_LM_AUTH); 460 461 if (mode & RFCOMM_LM_SECURE) 462 mode |= RFCOMM_LM_ENCRYPT; 463 464 if (mode & RFCOMM_LM_ENCRYPT) 465 mode |= RFCOMM_LM_AUTH; 466 467 dlc->rd_mode = mode; 468 469 if (dlc->rd_state == RFCOMM_DLC_OPEN) 470 err = rfcomm_dlc_setmode(dlc); 471 472 break; 473 474 default: 475 err = ENOPROTOOPT; 476 break; 477 } 478 return err; 479 } 480 481 482 int 483 rfcomm_setopt2(struct rfcomm_dlc *dlc, int opt, struct socket *so, 484 struct sockopt *sopt) 485 { 486 int mode, err = 0; 487 uint16_t mtu; 488 489 switch (opt) { 490 case SO_RFCOMM_MTU: 491 err = soopt_to_kbuf(sopt, &mtu, sizeof(uint16_t), 492 sizeof(uint16_t)); 493 if (err) break; 494 495 if (mtu < RFCOMM_MTU_MIN || mtu > RFCOMM_MTU_MAX) 496 err = EINVAL; 497 else if (dlc->rd_state == RFCOMM_DLC_CLOSED) 498 dlc->rd_mtu = mtu; 499 else 500 err = EBUSY; 501 502 break; 503 504 case SO_RFCOMM_LM: 505 err = soopt_to_kbuf(sopt, &mode, sizeof(int), sizeof(int)); 506 if (err) break; 507 508 mode &= (RFCOMM_LM_SECURE | RFCOMM_LM_ENCRYPT | RFCOMM_LM_AUTH); 509 510 if (mode & RFCOMM_LM_SECURE) 511 mode |= RFCOMM_LM_ENCRYPT; 512 513 if (mode & RFCOMM_LM_ENCRYPT) 514 mode |= RFCOMM_LM_AUTH; 515 516 dlc->rd_mode = mode; 517 518 if (dlc->rd_state == RFCOMM_DLC_OPEN) 519 err = rfcomm_dlc_setmode(dlc); 520 521 break; 522 523 default: 524 err = ENOPROTOOPT; 525 break; 526 } 527 return err; 528 } 529 530 /* 531 * rfcomm_getopt(dlc, option, addr) 532 * 533 * get DLC options 534 */ 535 int 536 rfcomm_getopt(struct rfcomm_dlc *dlc, int opt, void *addr) 537 { 538 struct rfcomm_fc_info *fc; 539 540 switch (opt) { 541 case SO_RFCOMM_MTU: 542 *(uint16_t *)addr = dlc->rd_mtu; 543 return sizeof(uint16_t); 544 545 case SO_RFCOMM_FC_INFO: 546 fc = addr; 547 memset(fc, 0, sizeof(*fc)); 548 fc->lmodem = dlc->rd_lmodem; 549 fc->rmodem = dlc->rd_rmodem; 550 fc->tx_cred = max(dlc->rd_txcred, 0xff); 551 fc->rx_cred = max(dlc->rd_rxcred, 0xff); 552 if (dlc->rd_session 553 && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC)) 554 fc->cfc = 1; 555 556 return sizeof(*fc); 557 558 case SO_RFCOMM_LM: 559 *(int *)addr = dlc->rd_mode; 560 return sizeof(int); 561 562 default: 563 break; 564 } 565 566 return 0; 567 } 568