• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2002-2010  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 
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 
sig_hup(int sig)78 static void sig_hup(int sig)
79 {
80 	return;
81 }
82 
sig_term(int sig)83 static void sig_term(int sig)
84 {
85 	__io_canceled = 1;
86 }
87 
rfcomm_flagstostr(uint32_t flags)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 
print_dev_info(struct rfcomm_dev_info * di)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 
print_dev_list(int ctl,int flags)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 
create_dev(int ctl,int dev,uint32_t flags,bdaddr_t * bdaddr,int argc,char ** argv)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 
create_all(int ctl)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 
release_dev(int ctl,int dev,uint32_t flags)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 
release_all(int ctl)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 
run_cmdline(struct pollfd * p,sigset_t * sigs,char * devname,int argc,char ** argv)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 
cmd_connect(int ctl,int dev,bdaddr_t * bdaddr,int argc,char ** argv)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 
cmd_listen(int ctl,int dev,bdaddr_t * bdaddr,int argc,char ** argv)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 
cmd_watch(int ctl,int dev,bdaddr_t * bdaddr,int argc,char ** argv)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 
cmd_create(int ctl,int dev,bdaddr_t * bdaddr,int argc,char ** argv)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 
cmd_release(int ctl,int dev,bdaddr_t * bdaddr,int argc,char ** argv)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 
cmd_show(int ctl,int dev,bdaddr_t * bdaddr,int argc,char ** argv)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 
usage(void)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 
main(int argc,char * argv[])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