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