Tizen 2.0 Release
[framework/connectivity/bluez.git] / tools / rfcomm.c
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
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 }