1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2002-2010 Marcel Holtmann <marcel (at) holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #define _GNU_SOURCE 29 #include <stdio.h> 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <unistd.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <getopt.h> 36 #include <signal.h> 37 #include <termios.h> 38 #include <sys/poll.h> 39 #include <sys/param.h> 40 #include <sys/ioctl.h> 41 #include <sys/socket.h> 42 #include <sys/wait.h> 43 44 #include <bluetooth/bluetooth.h> 45 #include <bluetooth/hci.h> 46 #include <bluetooth/hci_lib.h> 47 #include <bluetooth/rfcomm.h> 48 49 #include "kword.h" 50 51 #ifdef NEED_PPOLL 52 #include "ppoll.h" 53 #endif 54 55 static char *rfcomm_config_file = NULL; 56 static int rfcomm_raw_tty = 0; 57 static int auth = 0; 58 static int encryption = 0; 59 static int secure = 0; 60 static int master = 0; 61 static int linger = 0; 62 63 static char *rfcomm_state[] = { 64 "unknown", 65 "connected", 66 "clean", 67 "bound", 68 "listening", 69 "connecting", 70 "connecting", 71 "config", 72 "disconnecting", 73 "closed" 74 }; 75 76 static volatile sig_atomic_t __io_canceled = 0; 77 78 static void sig_hup(int sig) 79 { 80 return; 81 } 82 83 static void sig_term(int sig) 84 { 85 __io_canceled = 1; 86 } 87 88 static char *rfcomm_flagstostr(uint32_t flags) 89 { 90 static char str[100]; 91 str[0] = 0; 92 93 strcat(str, "["); 94 95 if (flags & (1 << RFCOMM_REUSE_DLC)) 96 strcat(str, "reuse-dlc "); 97 98 if (flags & (1 << RFCOMM_RELEASE_ONHUP)) 99 strcat(str, "release-on-hup "); 100 101 if (flags & (1 << RFCOMM_TTY_ATTACHED)) 102 strcat(str, "tty-attached"); 103 104 strcat(str, "]"); 105 return str; 106 } 107 108 static void print_dev_info(struct rfcomm_dev_info *di) 109 { 110 char src[18], dst[18], addr[40]; 111 112 ba2str(&di->src, src); ba2str(&di->dst, dst); 113 114 if (bacmp(&di->src, BDADDR_ANY) == 0) 115 sprintf(addr, "%s", dst); 116 else 117 sprintf(addr, "%s -> %s", src, dst); 118 119 printf("rfcomm%d: %s channel %d %s %s\n", 120 di->id, addr, di->channel, 121 rfcomm_state[di->state], 122 di->flags ? rfcomm_flagstostr(di->flags) : ""); 123 } 124 125 static void print_dev_list(int ctl, int flags) 126 { 127 struct rfcomm_dev_list_req *dl; 128 struct rfcomm_dev_info *di; 129 int i; 130 131 dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); 132 if (!dl) { 133 perror("Can't allocate memory"); 134 exit(1); 135 } 136 137 dl->dev_num = RFCOMM_MAX_DEV; 138 di = dl->dev_info; 139 140 if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) { 141 perror("Can't get device list"); 142 free(dl); 143 exit(1); 144 } 145 146 for (i = 0; i < dl->dev_num; i++) 147 print_dev_info(di + i); 148 free(dl); 149 } 150 151 static int create_dev(int ctl, int dev, uint32_t flags, bdaddr_t *bdaddr, int argc, char **argv) 152 { 153 struct rfcomm_dev_req req; 154 int err; 155 156 memset(&req, 0, sizeof(req)); 157 req.dev_id = dev; 158 req.flags = flags; 159 bacpy(&req.src, bdaddr); 160 161 if (argc < 2) { 162 err = rfcomm_read_config(rfcomm_config_file); 163 if (err < 0) { 164 perror("Can't open RFCOMM config file"); 165 return err; 166 } 167 168 bacpy(&req.dst, &rfcomm_opts[dev].bdaddr); 169 req.channel = rfcomm_opts[dev].channel; 170 171 if (bacmp(&req.dst, BDADDR_ANY) == 0) { 172 fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); 173 return -EFAULT; 174 } 175 } else { 176 str2ba(argv[1], &req.dst); 177 178 if (argc > 2) 179 req.channel = atoi(argv[2]); 180 else 181 req.channel = 1; 182 } 183 184 err = ioctl(ctl, RFCOMMCREATEDEV, &req); 185 if (err == EOPNOTSUPP) 186 fprintf(stderr, "RFCOMM TTY support not available\n"); 187 else if (err < 0) 188 perror("Can't create device"); 189 190 return err; 191 } 192 193 static int create_all(int ctl) 194 { 195 struct rfcomm_dev_req req; 196 int i, err; 197 198 err = rfcomm_read_config(rfcomm_config_file); 199 if (err < 0) { 200 perror("Can't open RFCOMM config file"); 201 return err; 202 } 203 204 for (i = 0; i < RFCOMM_MAX_DEV; i++) { 205 if (!rfcomm_opts[i].bind) 206 continue; 207 208 memset(&req, 0, sizeof(req)); 209 req.dev_id = i; 210 req.flags = 0; 211 bacpy(&req.src, BDADDR_ANY); 212 bacpy(&req.dst, &rfcomm_opts[i].bdaddr); 213 req.channel = rfcomm_opts[i].channel; 214 215 if (bacmp(&req.dst, BDADDR_ANY) != 0) 216 ioctl(ctl, RFCOMMCREATEDEV, &req); 217 } 218 219 return 0; 220 } 221 222 static int release_dev(int ctl, int dev, uint32_t flags) 223 { 224 struct rfcomm_dev_req req; 225 int err; 226 227 memset(&req, 0, sizeof(req)); 228 req.dev_id = dev; 229 230 err = ioctl(ctl, RFCOMMRELEASEDEV, &req); 231 if (err < 0) 232 perror("Can't release device"); 233 234 return err; 235 } 236 237 static int release_all(int ctl) 238 { 239 struct rfcomm_dev_list_req *dl; 240 struct rfcomm_dev_info *di; 241 int i; 242 243 dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); 244 if (!dl) { 245 perror("Can't allocate memory"); 246 exit(1); 247 } 248 249 dl->dev_num = RFCOMM_MAX_DEV; 250 di = dl->dev_info; 251 252 if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) { 253 perror("Can't get device list"); 254 free(dl); 255 exit(1); 256 } 257 258 for (i = 0; i < dl->dev_num; i++) 259 release_dev(ctl, (di + i)->id, 0); 260 261 free(dl); 262 return 0; 263 } 264 265 static void run_cmdline(struct pollfd *p, sigset_t* sigs, char *devname, 266 int argc, char **argv) 267 { 268 int i; 269 pid_t pid; 270 char **cmdargv; 271 272 cmdargv = malloc((argc + 1) * sizeof(char*)); 273 if (!cmdargv) 274 return; 275 276 for (i = 0; i < argc; i++) 277 cmdargv[i] = (strcmp(argv[i], "{}") == 0) ? devname : argv[i]; 278 cmdargv[i] = NULL; 279 280 pid = fork(); 281 282 switch (pid) { 283 case 0: 284 i = execvp(cmdargv[0], cmdargv); 285 fprintf(stderr, "Couldn't execute command %s (errno=%d:%s)\n", 286 cmdargv[0], errno, strerror(errno)); 287 break; 288 case -1: 289 fprintf(stderr, "Couldn't fork to execute command %s\n", 290 cmdargv[0]); 291 break; 292 default: 293 while (1) { 294 int status; 295 pid_t child; 296 struct timespec ts; 297 298 child = waitpid(-1, &status, WNOHANG); 299 if (child == pid || (child < 0 && errno != EAGAIN)) 300 break; 301 302 p->revents = 0; 303 ts.tv_sec = 0; 304 ts.tv_nsec = 200; 305 if (ppoll(p, 1, &ts, sigs) || __io_canceled) { 306 kill(pid, SIGTERM); 307 waitpid(pid, &status, 0); 308 break; 309 } 310 } 311 break; 312 } 313 314 free(cmdargv); 315 } 316 317 static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) 318 { 319 struct sockaddr_rc laddr, raddr; 320 struct rfcomm_dev_req req; 321 struct termios ti; 322 struct sigaction sa; 323 struct pollfd p; 324 sigset_t sigs; 325 socklen_t alen; 326 char dst[18], devname[MAXPATHLEN]; 327 int sk, fd, try = 30; 328 329 laddr.rc_family = AF_BLUETOOTH; 330 bacpy(&laddr.rc_bdaddr, bdaddr); 331 laddr.rc_channel = 0; 332 333 if (argc < 2) { 334 if (rfcomm_read_config(rfcomm_config_file) < 0) { 335 perror("Can't open RFCOMM config file"); 336 return; 337 } 338 339 raddr.rc_family = AF_BLUETOOTH; 340 bacpy(&raddr.rc_bdaddr, &rfcomm_opts[dev].bdaddr); 341 raddr.rc_channel = rfcomm_opts[dev].channel; 342 343 if (bacmp(&raddr.rc_bdaddr, BDADDR_ANY) == 0) { 344 fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); 345 return; 346 } 347 } else { 348 raddr.rc_family = AF_BLUETOOTH; 349 str2ba(argv[1], &raddr.rc_bdaddr); 350 351 if (argc > 2) 352 raddr.rc_channel = atoi(argv[2]); 353 else 354 raddr.rc_channel = 1; 355 } 356 357 sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 358 if (sk < 0) { 359 perror("Can't create RFCOMM socket"); 360 return; 361 } 362 363 if (linger) { 364 struct linger l = { .l_onoff = 1, .l_linger = linger }; 365 366 if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { 367 perror("Can't set linger option"); 368 return; 369 } 370 } 371 372 if (bind(sk, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) { 373 perror("Can't bind RFCOMM socket"); 374 close(sk); 375 return; 376 } 377 378 if (connect(sk, (struct sockaddr *) &raddr, sizeof(raddr)) < 0) { 379 perror("Can't connect RFCOMM socket"); 380 close(sk); 381 return; 382 } 383 384 alen = sizeof(laddr); 385 if (getsockname(sk, (struct sockaddr *)&laddr, &alen) < 0) { 386 perror("Can't get RFCOMM socket name"); 387 close(sk); 388 return; 389 } 390 391 memset(&req, 0, sizeof(req)); 392 req.dev_id = dev; 393 req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); 394 395 bacpy(&req.src, &laddr.rc_bdaddr); 396 bacpy(&req.dst, &raddr.rc_bdaddr); 397 req.channel = raddr.rc_channel; 398 399 dev = ioctl(sk, RFCOMMCREATEDEV, &req); 400 if (dev < 0) { 401 perror("Can't create RFCOMM TTY"); 402 close(sk); 403 return; 404 } 405 406 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); 407 while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { 408 if (errno == EACCES) { 409 perror("Can't open RFCOMM device"); 410 goto release; 411 } 412 413 snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); 414 if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { 415 if (try--) { 416 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); 417 usleep(100 * 1000); 418 continue; 419 } 420 perror("Can't open RFCOMM device"); 421 goto release; 422 } 423 } 424 425 if (rfcomm_raw_tty) { 426 tcflush(fd, TCIOFLUSH); 427 428 cfmakeraw(&ti); 429 tcsetattr(fd, TCSANOW, &ti); 430 } 431 432 close(sk); 433 434 ba2str(&req.dst, dst); 435 printf("Connected %s to %s on channel %d\n", devname, dst, req.channel); 436 printf("Press CTRL-C for hangup\n"); 437 438 memset(&sa, 0, sizeof(sa)); 439 sa.sa_flags = SA_NOCLDSTOP; 440 sa.sa_handler = SIG_IGN; 441 sigaction(SIGCHLD, &sa, NULL); 442 sigaction(SIGPIPE, &sa, NULL); 443 444 sa.sa_handler = sig_term; 445 sigaction(SIGTERM, &sa, NULL); 446 sigaction(SIGINT, &sa, NULL); 447 448 sa.sa_handler = sig_hup; 449 sigaction(SIGHUP, &sa, NULL); 450 451 sigfillset(&sigs); 452 sigdelset(&sigs, SIGCHLD); 453 sigdelset(&sigs, SIGPIPE); 454 sigdelset(&sigs, SIGTERM); 455 sigdelset(&sigs, SIGINT); 456 sigdelset(&sigs, SIGHUP); 457 458 p.fd = fd; 459 p.events = POLLERR | POLLHUP; 460 461 while (!__io_canceled) { 462 p.revents = 0; 463 if (ppoll(&p, 1, NULL, &sigs) > 0) 464 break; 465 } 466 467 printf("Disconnected\n"); 468 469 close(fd); 470 return; 471 472 release: 473 memset(&req, 0, sizeof(req)); 474 req.dev_id = dev; 475 req.flags = (1 << RFCOMM_HANGUP_NOW); 476 ioctl(ctl, RFCOMMRELEASEDEV, &req); 477 478 close(sk); 479 } 480 481 static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) 482 { 483 struct sockaddr_rc laddr, raddr; 484 struct rfcomm_dev_req req; 485 struct termios ti; 486 struct sigaction sa; 487 struct pollfd p; 488 sigset_t sigs; 489 socklen_t alen; 490 char dst[18], devname[MAXPATHLEN]; 491 int sk, nsk, fd, lm, try = 30; 492 493 laddr.rc_family = AF_BLUETOOTH; 494 bacpy(&laddr.rc_bdaddr, bdaddr); 495 laddr.rc_channel = (argc < 2) ? 1 : atoi(argv[1]); 496 497 sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 498 if (sk < 0) { 499 perror("Can't create RFCOMM socket"); 500 return; 501 } 502 503 lm = 0; 504 if (master) 505 lm |= RFCOMM_LM_MASTER; 506 if (auth) 507 lm |= RFCOMM_LM_AUTH; 508 if (encryption) 509 lm |= RFCOMM_LM_ENCRYPT; 510 if (secure) 511 lm |= RFCOMM_LM_SECURE; 512 513 if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { 514 perror("Can't set RFCOMM link mode"); 515 close(sk); 516 return; 517 } 518 519 if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { 520 perror("Can't bind RFCOMM socket"); 521 close(sk); 522 return; 523 } 524 525 printf("Waiting for connection on channel %d\n", laddr.rc_channel); 526 527 listen(sk, 10); 528 529 alen = sizeof(raddr); 530 nsk = accept(sk, (struct sockaddr *) &raddr, &alen); 531 532 alen = sizeof(laddr); 533 if (getsockname(nsk, (struct sockaddr *)&laddr, &alen) < 0) { 534 perror("Can't get RFCOMM socket name"); 535 close(nsk); 536 return; 537 } 538 539 if (linger) { 540 struct linger l = { .l_onoff = 1, .l_linger = linger }; 541 542 if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { 543 perror("Can't set linger option"); 544 close(nsk); 545 return; 546 } 547 } 548 549 memset(&req, 0, sizeof(req)); 550 req.dev_id = dev; 551 req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); 552 553 bacpy(&req.src, &laddr.rc_bdaddr); 554 bacpy(&req.dst, &raddr.rc_bdaddr); 555 req.channel = raddr.rc_channel; 556 557 dev = ioctl(nsk, RFCOMMCREATEDEV, &req); 558 if (dev < 0) { 559 perror("Can't create RFCOMM TTY"); 560 close(sk); 561 return; 562 } 563 564 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); 565 while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { 566 if (errno == EACCES) { 567 perror("Can't open RFCOMM device"); 568 goto release; 569 } 570 571 snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); 572 if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { 573 if (try--) { 574 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); 575 usleep(100 * 1000); 576 continue; 577 } 578 perror("Can't open RFCOMM device"); 579 goto release; 580 } 581 } 582 583 if (rfcomm_raw_tty) { 584 tcflush(fd, TCIOFLUSH); 585 586 cfmakeraw(&ti); 587 tcsetattr(fd, TCSANOW, &ti); 588 } 589 590 close(sk); 591 close(nsk); 592 593 ba2str(&req.dst, dst); 594 printf("Connection from %s to %s\n", dst, devname); 595 printf("Press CTRL-C for hangup\n"); 596 597 memset(&sa, 0, sizeof(sa)); 598 sa.sa_flags = SA_NOCLDSTOP; 599 sa.sa_handler = SIG_IGN; 600 sigaction(SIGCHLD, &sa, NULL); 601 sigaction(SIGPIPE, &sa, NULL); 602 603 sa.sa_handler = sig_term; 604 sigaction(SIGTERM, &sa, NULL); 605 sigaction(SIGINT, &sa, NULL); 606 607 sa.sa_handler = sig_hup; 608 sigaction(SIGHUP, &sa, NULL); 609 610 sigfillset(&sigs); 611 sigdelset(&sigs, SIGCHLD); 612 sigdelset(&sigs, SIGPIPE); 613 sigdelset(&sigs, SIGTERM); 614 sigdelset(&sigs, SIGINT); 615 sigdelset(&sigs, SIGHUP); 616 617 p.fd = fd; 618 p.events = POLLERR | POLLHUP; 619 620 if (argc <= 2) { 621 while (!__io_canceled) { 622 p.revents = 0; 623 if (ppoll(&p, 1, NULL, &sigs) > 0) 624 break; 625 } 626 } else 627 run_cmdline(&p, &sigs, devname, argc - 2, argv + 2); 628 629 sa.sa_handler = NULL; 630 sigaction(SIGTERM, &sa, NULL); 631 sigaction(SIGINT, &sa, NULL); 632 633 printf("Disconnected\n"); 634 635 close(fd); 636 return; 637 638 release: 639 memset(&req, 0, sizeof(req)); 640 req.dev_id = dev; 641 req.flags = (1 << RFCOMM_HANGUP_NOW); 642 ioctl(ctl, RFCOMMRELEASEDEV, &req); 643 644 close(sk); 645 } 646 647 static void cmd_watch(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) 648 { 649 while (!__io_canceled) { 650 cmd_listen(ctl, dev, bdaddr, argc, argv); 651 usleep(10000); 652 } 653 } 654 655 static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) 656 { 657 if (strcmp(argv[0], "all") == 0) 658 create_all(ctl); 659 else 660 create_dev(ctl, dev, 0, bdaddr, argc, argv); 661 } 662 663 static void cmd_release(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) 664 { 665 if (strcmp(argv[0], "all") == 0) 666 release_all(ctl); 667 else 668 release_dev(ctl, dev, 0); 669 } 670 671 static void cmd_show(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) 672 { 673 if (strcmp(argv[0], "all") == 0) 674 print_dev_list(ctl, 0); 675 else { 676 struct rfcomm_dev_info di = { id: atoi(argv[0]) }; 677 if (ioctl(ctl, RFCOMMGETDEVINFO, &di) < 0) { 678 perror("Get info failed"); 679 exit(1); 680 } 681 682 print_dev_info(&di); 683 } 684 } 685 686 struct { 687 char *cmd; 688 char *alt; 689 void (*func)(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv); 690 char *opt; 691 char *doc; 692 } command[] = { 693 { "bind", "create", cmd_create, "<dev> <bdaddr> [channel]", "Bind device" }, 694 { "release", "unbind", cmd_release, "<dev>", "Release device" }, 695 { "show", "info", cmd_show, "<dev>", "Show device" }, 696 { "connect", "conn", cmd_connect, "<dev> <bdaddr> [channel]", "Connect device" }, 697 { "listen", "server", cmd_listen, "<dev> [channel [cmd]]", "Listen" }, 698 { "watch", "watch", cmd_watch, "<dev> [channel [cmd]]", "Watch" }, 699 { NULL, NULL, NULL, 0, 0 } 700 }; 701 702 static void usage(void) 703 { 704 int i; 705 706 printf("RFCOMM configuration utility ver %s\n", VERSION); 707 708 printf("Usage:\n" 709 "\trfcomm [options] <command> <dev>\n" 710 "\n"); 711 712 printf("Options:\n" 713 "\t-i [hciX|bdaddr] Local HCI device or BD Address\n" 714 "\t-h, --help Display help\n" 715 "\t-r, --raw Switch TTY into raw mode\n" 716 "\t-A, --auth Enable authentication\n" 717 "\t-E, --encrypt Enable encryption\n" 718 "\t-S, --secure Secure connection\n" 719 "\t-M, --master Become the master of a piconet\n" 720 "\t-f, --config [file] Specify alternate config file\n" 721 "\t-a Show all devices (default)\n" 722 "\n"); 723 724 printf("Commands:\n"); 725 for (i = 0; command[i].cmd; i++) 726 printf("\t%-8s %-24s\t%s\n", 727 command[i].cmd, 728 command[i].opt ? command[i].opt : " ", 729 command[i].doc); 730 printf("\n"); 731 } 732 733 static struct option main_options[] = { 734 { "help", 0, 0, 'h' }, 735 { "device", 1, 0, 'i' }, 736 { "config", 1, 0, 'f' }, 737 { "raw", 0, 0, 'r' }, 738 { "auth", 0, 0, 'A' }, 739 { "encrypt", 0, 0, 'E' }, 740 { "secure", 0, 0, 'S' }, 741 { "master", 0, 0, 'M' }, 742 { "linger", 1, 0, 'L' }, 743 { 0, 0, 0, 0 } 744 }; 745 746 int main(int argc, char *argv[]) 747 { 748 bdaddr_t bdaddr; 749 int i, opt, ctl, dev_id, show_all = 0; 750 751 bacpy(&bdaddr, BDADDR_ANY); 752 753 while ((opt = getopt_long(argc, argv, "+i:f:rahAESML:", main_options, NULL)) != -1) { 754 switch(opt) { 755 case 'i': 756 if (strncmp(optarg, "hci", 3) == 0) 757 hci_devba(atoi(optarg + 3), &bdaddr); 758 else 759 str2ba(optarg, &bdaddr); 760 break; 761 762 case 'f': 763 rfcomm_config_file = strdup(optarg); 764 break; 765 766 case 'r': 767 rfcomm_raw_tty = 1; 768 break; 769 770 case 'a': 771 show_all = 1; 772 break; 773 774 case 'h': 775 usage(); 776 exit(0); 777 778 case 'A': 779 auth = 1; 780 break; 781 782 case 'E': 783 encryption = 1; 784 break; 785 786 case 'S': 787 secure = 1; 788 break; 789 790 case 'M': 791 master = 1; 792 break; 793 794 case 'L': 795 linger = atoi(optarg); 796 break; 797 798 default: 799 exit(0); 800 } 801 } 802 803 argc -= optind; 804 argv += optind; 805 optind = 0; 806 807 if (argc < 2) { 808 if (argc != 0) { 809 usage(); 810 exit(1); 811 } else 812 show_all = 1; 813 } 814 815 ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); 816 if (ctl < 0) { 817 perror("Can't open RFCOMM control socket"); 818 exit(1); 819 } 820 821 if (show_all) { 822 print_dev_list(ctl, 0); 823 close(ctl); 824 exit(0); 825 } 826 827 if (strncmp(argv[1], "/dev/rfcomm", 11) == 0) 828 dev_id = atoi(argv[1] + 11); 829 else if (strncmp(argv[1], "rfcomm", 6) == 0) 830 dev_id = atoi(argv[1] + 6); 831 else 832 dev_id = atoi(argv[1]); 833 834 for (i = 0; command[i].cmd; i++) { 835 if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4)) 836 continue; 837 argc--; 838 argv++; 839 command[i].func(ctl, dev_id, &bdaddr, argc, argv); 840 close(ctl); 841 exit(0); 842 } 843 844 usage(); 845 846 close(ctl); 847 848 return 0; 849 } 850