Home | History | Annotate | Download | only in tools
      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