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