OSDN Git Service

Remove obsolete LOCAL_MODULE_TAGS
[android-x86/external-bluetooth-bluez.git] / tools / rctest.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
6  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <getopt.h>
36 #include <syslog.h>
37 #include <signal.h>
38 #include <sys/time.h>
39 #include <sys/ioctl.h>
40 #include <sys/socket.h>
41 #include <sys/stat.h>
42
43 #include "lib/bluetooth.h"
44 #include "lib/hci.h"
45 #include "lib/hci_lib.h"
46 #include "lib/rfcomm.h"
47 #include "lib/sdp.h"
48 #include "lib/sdp_lib.h"
49
50 #include "src/shared/util.h"
51
52 /* Test modes */
53 enum {
54         SEND,
55         RECV,
56         RECONNECT,
57         MULTY,
58         DUMP,
59         CONNECT,
60         CRECV,
61         LSEND,
62         AUTO,
63 };
64
65 static unsigned char *buf;
66
67 /* Default data size */
68 static long data_size = 127;
69 static long num_frames = -1;
70
71 /* Default number of consecutive frames before the delay */
72 static int count = 1;
73
74 /* Default delay after sending count number of frames */
75 static unsigned long delay = 0;
76
77 /* Default addr and channel */
78 static bdaddr_t bdaddr;
79 static bdaddr_t auto_bdaddr;
80 static uint16_t uuid = 0x0000;
81 static uint8_t channel = 10;
82
83 static const char *filename = NULL;
84 static const char *savefile = NULL;
85 static int save_fd = -1;
86
87 static int master = 0;
88 static int auth = 0;
89 static int encr = 0;
90 static int secure = 0;
91 static int socktype = SOCK_STREAM;
92 static int linger = 0;
93 static int timestamp = 0;
94 static int defer_setup = 0;
95 static int priority = -1;
96
97 static float tv2fl(struct timeval tv)
98 {
99         return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0);
100 }
101
102 static uint8_t get_channel(const char *svr, uint16_t uuid)
103 {
104         sdp_session_t *sdp;
105         sdp_list_t *srch, *attrs, *rsp, *protos;
106         uuid_t svclass;
107         uint16_t attr;
108         bdaddr_t dst;
109         uint8_t channel = 0;
110         int err;
111
112         str2ba(svr, &dst);
113
114         sdp = sdp_connect(&bdaddr, &dst, SDP_RETRY_IF_BUSY);
115         if (!sdp)
116                 return 0;
117
118         sdp_uuid16_create(&svclass, uuid);
119         srch = sdp_list_append(NULL, &svclass);
120
121         attr = SDP_ATTR_PROTO_DESC_LIST;
122         attrs = sdp_list_append(NULL, &attr);
123
124         err = sdp_service_search_attr_req(sdp, srch,
125                                         SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
126         if (err)
127                 goto done;
128
129         for (; rsp; rsp = rsp->next) {
130                 sdp_record_t *rec = (sdp_record_t *) rsp->data;
131
132                 if (!sdp_get_access_protos(rec, &protos)) {
133                         channel = sdp_get_proto_port(protos, RFCOMM_UUID);
134                         if (channel > 0)
135                                 break;
136                 }
137         }
138
139         sdp_list_free(protos, NULL);
140
141 done:
142         sdp_list_free(srch, NULL);
143         sdp_list_free(attrs, NULL);
144         sdp_close(sdp);
145
146         return channel;
147 }
148
149 static int do_connect(const char *svr)
150 {
151         struct sockaddr_rc addr;
152         struct rfcomm_conninfo conn;
153         socklen_t optlen;
154         int sk, opt;
155
156         if (uuid != 0x0000)
157                 channel = get_channel(svr, uuid);
158
159         if (channel == 0) {
160                 syslog(LOG_ERR, "Can't get channel number");
161                 return -1;
162         }
163
164         /* Create socket */
165         sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM);
166         if (sk < 0) {
167                 syslog(LOG_ERR, "Can't create socket: %s (%d)",
168                                                         strerror(errno), errno);
169                 return -1;
170         }
171
172         /* Bind to local address */
173         memset(&addr, 0, sizeof(addr));
174         addr.rc_family = AF_BLUETOOTH;
175
176         if (bacmp(&auto_bdaddr, BDADDR_ANY))
177                 bacpy(&addr.rc_bdaddr, &auto_bdaddr);
178         else
179                 bacpy(&addr.rc_bdaddr, &bdaddr);
180
181         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
182                 syslog(LOG_ERR, "Can't bind socket: %s (%d)",
183                                                         strerror(errno), errno);
184                 goto error;
185         }
186
187 #if 0
188         /* Enable SO_TIMESTAMP */
189         if (timestamp) {
190                 int t = 1;
191
192                 if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) {
193                         syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)",
194                                                         strerror(errno), errno);
195                         goto error;
196                 }
197         }
198 #endif
199
200         /* Enable SO_LINGER */
201         if (linger) {
202                 struct linger l = { .l_onoff = 1, .l_linger = linger };
203
204                 if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
205                         syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)",
206                                                         strerror(errno), errno);
207                         goto error;
208                 }
209         }
210
211         /* Set link mode */
212         opt = 0;
213         if (master)
214                 opt |= RFCOMM_LM_MASTER;
215         if (auth)
216                 opt |= RFCOMM_LM_AUTH;
217         if (encr)
218                 opt |= RFCOMM_LM_ENCRYPT;
219         if (secure)
220                 opt |= RFCOMM_LM_SECURE;
221
222         if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) {
223                 syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)",
224                                                         strerror(errno), errno);
225                 goto error;
226         }
227
228         /* Connect to remote device */
229         memset(&addr, 0, sizeof(addr));
230         addr.rc_family = AF_BLUETOOTH;
231         str2ba(svr, &addr.rc_bdaddr);
232         addr.rc_channel = channel;
233
234         if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
235                 syslog(LOG_ERR, "Can't connect: %s (%d)",
236                                                         strerror(errno), errno);
237                 goto error;
238         }
239
240         /* Get connection information */
241         memset(&conn, 0, sizeof(conn));
242         optlen = sizeof(conn);
243
244         if (getsockopt(sk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) {
245                 syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)",
246                                                         strerror(errno), errno);
247                 //goto error;
248         }
249
250         if (priority > 0 && setsockopt(sk, SOL_SOCKET, SO_PRIORITY, &priority,
251                                                 sizeof(priority)) < 0) {
252                 syslog(LOG_ERR, "Can't set socket priority: %s (%d)",
253                                                         strerror(errno), errno);
254                 goto error;
255         }
256
257         if (getsockopt(sk, SOL_SOCKET, SO_PRIORITY, &opt, &optlen) < 0) {
258                 syslog(LOG_ERR, "Can't get socket priority: %s (%d)",
259                                                         strerror(errno), errno);
260                 goto error;
261         }
262
263         syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x, "
264                         "priority %d]", conn.hci_handle, conn.dev_class[2],
265                         conn.dev_class[1], conn.dev_class[0], opt);
266
267         return sk;
268
269 error:
270         close(sk);
271         return -1;
272 }
273
274 static void do_listen(void (*handler)(int sk))
275 {
276         struct sockaddr_rc addr;
277         struct rfcomm_conninfo conn;
278         socklen_t optlen;
279         int sk, nsk, opt;
280         char ba[18];
281
282         /* Create socket */
283         sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM);
284         if (sk < 0) {
285                 syslog(LOG_ERR, "Can't create socket: %s (%d)",
286                                                         strerror(errno), errno);
287                 exit(1);
288         }
289
290         /* Bind to local address */
291         memset(&addr, 0, sizeof(addr));
292         addr.rc_family = AF_BLUETOOTH;
293         bacpy(&addr.rc_bdaddr, &bdaddr);
294         addr.rc_channel = channel;
295
296         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
297                 syslog(LOG_ERR, "Can't bind socket: %s (%d)",
298                                                         strerror(errno), errno);
299                 goto error;
300         }
301
302         /* Set link mode */
303         opt = 0;
304         if (master)
305                 opt |= RFCOMM_LM_MASTER;
306         if (auth)
307                 opt |= RFCOMM_LM_AUTH;
308         if (encr)
309                 opt |= RFCOMM_LM_ENCRYPT;
310         if (secure)
311                 opt |= RFCOMM_LM_SECURE;
312
313         if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) {
314                 syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)",
315                                                         strerror(errno), errno);
316                 goto error;
317         }
318
319         /* Enable deferred setup */
320         opt = defer_setup;
321
322         if (opt && setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP,
323                                                 &opt, sizeof(opt)) < 0) {
324                 syslog(LOG_ERR, "Can't enable deferred setup : %s (%d)",
325                                                         strerror(errno), errno);
326                 goto error;
327         }
328
329         /* Listen for connections */
330         if (listen(sk, 10)) {
331                 syslog(LOG_ERR,"Can not listen on the socket: %s (%d)",
332                                                         strerror(errno), errno);
333                 goto error;
334         }
335
336         /* Check for socket address */
337         memset(&addr, 0, sizeof(addr));
338         optlen = sizeof(addr);
339
340         if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) {
341                 syslog(LOG_ERR, "Can't get socket name: %s (%d)",
342                                                         strerror(errno), errno);
343                 goto error;
344         }
345
346         channel = addr.rc_channel;
347
348         syslog(LOG_INFO, "Waiting for connection on channel %d ...", channel);
349
350         while (1) {
351                 memset(&addr, 0, sizeof(addr));
352                 optlen = sizeof(addr);
353
354                 nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
355                 if (nsk < 0) {
356                         syslog(LOG_ERR,"Accept failed: %s (%d)",
357                                                         strerror(errno), errno);
358                         goto error;
359                 }
360                 if (fork()) {
361                         /* Parent */
362                         close(nsk);
363                         continue;
364                 }
365                 /* Child */
366                 close(sk);
367
368                 /* Get connection information */
369                 memset(&conn, 0, sizeof(conn));
370                 optlen = sizeof(conn);
371
372                 if (getsockopt(nsk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) {
373                         syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)",
374                                                         strerror(errno), errno);
375                         //close(nsk);
376                         //goto error;
377                 }
378
379                 if (priority > 0 && setsockopt(sk, SOL_SOCKET, SO_PRIORITY,
380                                         &priority, sizeof(priority)) < 0) {
381                         syslog(LOG_ERR, "Can't set socket priority: %s (%d)",
382                                                 strerror(errno), errno);
383                         close(nsk);
384                         goto error;
385                 }
386
387                 optlen = sizeof(priority);
388                 if (getsockopt(nsk, SOL_SOCKET, SO_PRIORITY, &opt, &optlen) < 0) {
389                         syslog(LOG_ERR, "Can't get socket priority: %s (%d)",
390                                                         strerror(errno), errno);
391                         goto error;
392                 }
393
394                 ba2str(&addr.rc_bdaddr, ba);
395                 syslog(LOG_INFO, "Connect from %s [handle %d, "
396                                 "class 0x%02x%02x%02x, priority %d]",
397                                 ba, conn.hci_handle, conn.dev_class[2],
398                                 conn.dev_class[1], conn.dev_class[0], opt);
399
400 #if 0
401                 /* Enable SO_TIMESTAMP */
402                 if (timestamp) {
403                         int t = 1;
404
405                         if (setsockopt(nsk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) {
406                                 syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)",
407                                                         strerror(errno), errno);
408                                 goto error;
409                         }
410                 }
411 #endif
412
413                 /* Enable SO_LINGER */
414                 if (linger) {
415                         struct linger l = { .l_onoff = 1, .l_linger = linger };
416
417                         if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
418                                 syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)",
419                                                         strerror(errno), errno);
420                                 close(nsk);
421                                 goto error;
422                         }
423                 }
424
425                 /* Handle deferred setup */
426                 if (defer_setup) {
427                         syslog(LOG_INFO, "Waiting for %d seconds",
428                                                         abs(defer_setup) - 1);
429                         sleep(abs(defer_setup) - 1);
430
431                         if (defer_setup < 0) {
432                                 close(nsk);
433                                 goto error;
434                         }
435                 }
436
437                 handler(nsk);
438
439                 syslog(LOG_INFO, "Disconnect: %m");
440                 exit(0);
441         }
442
443 error:
444         close(sk);
445         exit(1);
446 }
447
448 static void dump_mode(int sk)
449 {
450         int len;
451
452         syslog(LOG_INFO, "Receiving ...");
453         while ((len = read(sk, buf, data_size)) > 0)
454                 syslog(LOG_INFO, "Received %d bytes", len);
455 }
456
457 static void save_mode(int sk)
458 {
459         int len, ret;
460         char *b;
461
462         b = malloc(data_size);
463         if (!b) {
464                 syslog(LOG_ERR, "Failed to open file to save recv data");
465                 return;
466         }
467
468         syslog(LOG_INFO, "Receiving ...");
469         while ((len = read(sk, b, data_size)) > 0) {
470                 ret = write(save_fd, b, len);
471                 if (ret < 0)
472                         goto done;
473         }
474
475 done:
476         free(b);
477 }
478
479 static void recv_mode(int sk)
480 {
481         struct timeval tv_beg, tv_end, tv_diff;
482         char ts[30];
483         long total;
484
485         syslog(LOG_INFO, "Receiving ...");
486
487         memset(ts, 0, sizeof(ts));
488
489         while (1) {
490                 gettimeofday(&tv_beg,NULL);
491                 total = 0;
492                 while (total < data_size) {
493                         //uint32_t sq;
494                         //uint16_t l;
495                         int r;
496
497                         if ((r = recv(sk, buf, data_size, 0)) < 0) {
498                                 if (r < 0)
499                                         syslog(LOG_ERR, "Read failed: %s (%d)",
500                                                         strerror(errno), errno);
501                                 return;
502                         }
503
504                         if (timestamp) {
505                                 struct timeval tv;
506
507                                 if (ioctl(sk, SIOCGSTAMP, &tv) < 0) {
508                                         timestamp = 0;
509                                         memset(ts, 0, sizeof(ts));
510                                 } else {
511                                         sprintf(ts, "[%ld.%ld] ",
512                                                         tv.tv_sec, tv.tv_usec);
513                                 }
514                         }
515
516 #if 0
517                         /* Check sequence */
518                         sq = btohl(*(uint32_t *) buf);
519                         if (seq != sq) {
520                                 syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq);
521                                 seq = sq;
522                         }
523                         seq++;
524
525                         /* Check length */
526                         l = btohs(*(uint16_t *) (buf + 4));
527                         if (r != l) {
528                                 syslog(LOG_INFO, "size missmatch: %d -> %d", r, l);
529                                 continue;
530                         }
531
532                         /* Verify data */
533                         for (i = 6; i < r; i++) {
534                                 if (buf[i] != 0x7f)
535                                         syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]);
536                         }
537 #endif
538                         total += r;
539                 }
540                 gettimeofday(&tv_end,NULL);
541
542                 timersub(&tv_end,&tv_beg,&tv_diff);
543
544                 syslog(LOG_INFO,"%s%ld bytes in %.2f sec, %.2f kB/s", ts, total,
545                         tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0);
546         }
547 }
548
549 static void do_send(int sk)
550 {
551         uint32_t seq;
552         int i, fd, len;
553
554         syslog(LOG_INFO,"Sending ...");
555
556         if (filename) {
557                 fd = open(filename, O_RDONLY);
558                 if (fd < 0) {
559                         syslog(LOG_ERR, "Open failed: %s (%d)",
560                                                         strerror(errno), errno);
561                         exit(1);
562                 }
563                 len = read(fd, buf, data_size);
564                 send(sk, buf, len, 0);
565                 close(fd);
566                 return;
567         } else {
568                 for (i = 6; i < data_size; i++)
569                         buf[i] = 0x7f;
570         }
571
572         seq = 0;
573         while ((num_frames == -1) || (num_frames-- > 0)) {
574                 put_le32(seq, buf);
575                 put_le16(data_size, buf + 4);
576
577                 seq++;
578
579                 if (send(sk, buf, data_size, 0) <= 0) {
580                         syslog(LOG_ERR, "Send failed: %s (%d)",
581                                                         strerror(errno), errno);
582                         exit(1);
583                 }
584
585                 if (num_frames && delay && count && !(seq % count))
586                         usleep(delay);
587         }
588 }
589
590 static void send_mode(int sk)
591 {
592         do_send(sk);
593
594         syslog(LOG_INFO, "Closing channel ...");
595         if (shutdown(sk, SHUT_RDWR) < 0)
596                 syslog(LOG_INFO, "Close failed: %m");
597         else
598                 syslog(LOG_INFO, "Done");
599         close(sk);
600 }
601
602 static void reconnect_mode(char *svr)
603 {
604         while(1) {
605                 int sk = do_connect(svr);
606                 close(sk);
607         }
608 }
609
610 static void multi_connect_mode(int argc, char *argv[])
611 {
612         int i, n, sk;
613
614         while (1) {
615                 for (n = 0; n < argc; n++) {
616                         for (i = 0; i < count; i++) {
617                                 if (fork())
618                                         continue;
619
620                                 /* Child */
621                                 sk = do_connect(argv[n]);
622                                 usleep(500);
623                                 close(sk);
624                                 exit(0);
625                         }
626                 }
627                 sleep(4);
628         }
629 }
630
631 static void automated_send_recv()
632 {
633         int sk;
634         char device[18];
635
636         if (fork()) {
637                 if (!savefile) {
638                         /* do_listen() never returns */
639                         do_listen(recv_mode);
640                 }
641
642                 save_fd = open(savefile, O_CREAT | O_WRONLY,
643                                                 S_IRUSR | S_IWUSR);
644                 if (save_fd < 0)
645                         syslog(LOG_ERR, "Failed to open file to save data");
646
647                 /* do_listen() never returns */
648                 do_listen(save_mode);
649         } else {
650                 ba2str(&bdaddr, device);
651
652                 sk = do_connect(device);
653                 if (sk < 0)
654                         exit(1);
655                 send_mode(sk);
656         }
657 }
658
659 static void sig_child_exit(int code)
660 {
661         if (save_fd >= 0)
662                 close(save_fd);
663
664         syslog(LOG_INFO, "Exit");
665         exit(0);
666 }
667
668 static void usage(void)
669 {
670         printf("rctest - RFCOMM testing\n"
671                 "Usage:\n");
672         printf("\trctest <mode> [options] [bdaddr]\n");
673         printf("Modes:\n"
674                 "\t-r listen and receive\n"
675                 "\t-w listen and send\n"
676                 "\t-d listen and dump incoming data\n"
677                 "\t-s connect and send\n"
678                 "\t-u connect and receive\n"
679                 "\t-n connect and be silent\n"
680                 "\t-c connect, disconnect, connect, ...\n"
681                 "\t-m multiple connects\n"
682                 "\t-a automated test (receive hcix as parameter)\n");
683
684         printf("Options:\n"
685                 "\t[-b bytes] [-i device] [-P channel] [-U uuid]\n"
686                 "\t[-L seconds] enabled SO_LINGER option\n"
687                 "\t[-W seconds] enable deferred setup\n"
688                 "\t[-B filename] use data packets from file\n"
689                 "\t[-O filename] save received data to file\n"
690                 "\t[-N num] number of frames to send\n"
691                 "\t[-C num] send num frames before delay (default = 1)\n"
692                 "\t[-D milliseconds] delay after sending num frames (default = 0)\n"
693                 "\t[-Y priority] socket priority\n"
694                 "\t[-A] request authentication\n"
695                 "\t[-E] request encryption\n"
696                 "\t[-S] secure connection\n"
697                 "\t[-M] become master\n"
698                 "\t[-T] enable timestamps\n");
699 }
700
701 int main(int argc, char *argv[])
702 {
703         struct sigaction sa;
704         int opt, sk, mode = RECV, need_addr = 0;
705
706         bacpy(&bdaddr, BDADDR_ANY);
707         bacpy(&auto_bdaddr, BDADDR_ANY);
708
709         while ((opt=getopt(argc,argv,"rdscuwmna:b:i:P:U:B:O:N:MAESL:W:C:D:Y:T")) != EOF) {
710                 switch (opt) {
711                 case 'r':
712                         mode = RECV;
713                         break;
714
715                 case 's':
716                         mode = SEND;
717                         need_addr = 1;
718                         break;
719
720                 case 'w':
721                         mode = LSEND;
722                         break;
723
724                 case 'u':
725                         mode = CRECV;
726                         need_addr = 1;
727                         break;
728
729                 case 'd':
730                         mode = DUMP;
731                         break;
732
733                 case 'c':
734                         mode = RECONNECT;
735                         need_addr = 1;
736                         break;
737
738                 case 'n':
739                         mode = CONNECT;
740                         need_addr = 1;
741                         break;
742
743                 case 'm':
744                         mode = MULTY;
745                         need_addr = 1;
746                         break;
747
748                 case 'a':
749                         mode = AUTO;
750
751                         if (!strncasecmp(optarg, "hci", 3))
752                                 hci_devba(atoi(optarg + 3), &auto_bdaddr);
753                         else
754                                 str2ba(optarg, &auto_bdaddr);
755                         break;
756
757                 case 'b':
758                         data_size = atoi(optarg);
759                         break;
760
761                 case 'i':
762                         if (!strncasecmp(optarg, "hci", 3))
763                                 hci_devba(atoi(optarg + 3), &bdaddr);
764                         else
765                                 str2ba(optarg, &bdaddr);
766                         break;
767
768                 case 'P':
769                         channel = atoi(optarg);
770                         break;
771
772                 case 'U':
773                         if (!strcasecmp(optarg, "spp"))
774                                 uuid = SERIAL_PORT_SVCLASS_ID;
775                         else if (!strncasecmp(optarg, "0x", 2))
776                                 uuid = strtoul(optarg + 2, NULL, 16);
777                         else
778                                 uuid = atoi(optarg);
779                         break;
780
781                 case 'M':
782                         master = 1;
783                         break;
784
785                 case 'A':
786                         auth = 1;
787                         break;
788
789                 case 'E':
790                         encr = 1;
791                         break;
792
793                 case 'S':
794                         secure = 1;
795                         break;
796
797                 case 'L':
798                         linger = atoi(optarg);
799                         break;
800
801                 case 'W':
802                         defer_setup = atoi(optarg);
803                         break;
804
805                 case 'B':
806                         filename = optarg;
807                         break;
808
809                 case 'O':
810                         savefile = optarg;
811                         break;
812
813                 case 'N':
814                         num_frames = atoi(optarg);
815                         break;
816
817                 case 'C':
818                         count = atoi(optarg);
819                         break;
820
821                 case 'D':
822                         delay = atoi(optarg) * 1000;
823                         break;
824
825                 case 'Y':
826                         priority = atoi(optarg);
827                         break;
828
829                 case 'T':
830                         timestamp = 1;
831                         break;
832
833                 default:
834                         usage();
835                         exit(1);
836                 }
837         }
838
839         if (need_addr && !(argc - optind)) {
840                 usage();
841                 exit(1);
842         }
843
844         if (!(buf = malloc(data_size))) {
845                 perror("Can't allocate data buffer");
846                 exit(1);
847         }
848
849         memset(&sa, 0, sizeof(sa));
850         if (mode == AUTO)
851                 sa.sa_handler = sig_child_exit;
852         else
853                 sa.sa_handler = SIG_IGN;
854         sa.sa_flags   = SA_NOCLDSTOP;
855         sigaction(SIGCHLD, &sa, NULL);
856
857         openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0);
858
859         switch (mode) {
860                 case RECV:
861                         do_listen(recv_mode);
862                         break;
863
864                 case CRECV:
865                         sk = do_connect(argv[optind]);
866                         if (sk < 0)
867                                 exit(1);
868                         recv_mode(sk);
869                         break;
870
871                 case DUMP:
872                         do_listen(dump_mode);
873                         break;
874
875                 case SEND:
876                         sk = do_connect(argv[optind]);
877                         if (sk < 0)
878                                 exit(1);
879                         send_mode(sk);
880                         break;
881
882                 case LSEND:
883                         do_listen(send_mode);
884                         break;
885
886                 case RECONNECT:
887                         reconnect_mode(argv[optind]);
888                         break;
889
890                 case MULTY:
891                         multi_connect_mode(argc - optind, argv + optind);
892                         break;
893
894                 case CONNECT:
895                         sk = do_connect(argv[optind]);
896                         if (sk < 0)
897                                 exit(1);
898                         dump_mode(sk);
899                         break;
900
901                 case AUTO:
902                         automated_send_recv();
903                         break;
904         }
905
906         syslog(LOG_INFO, "Exit");
907
908         closelog();
909
910         return 0;
911 }