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