Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / monitor / main.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2011-2014  Intel Corporation
6  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2.1 of the License, or (at your option) any later version.
13  *
14  *  This library 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 GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; 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 <ctype.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <getopt.h>
34
35 #include "src/shared/mainloop.h"
36
37 #include "packet.h"
38 #include "lmp.h"
39 #include "keys.h"
40 #include "analyze.h"
41 #include "ellisys.h"
42 #include "control.h"
43
44 static void signal_callback(int signum, void *user_data)
45 {
46         switch (signum) {
47         case SIGINT:
48         case SIGTERM:
49                 mainloop_quit();
50                 break;
51         }
52 }
53
54 static void usage(void)
55 {
56         printf("btmon - Bluetooth monitor\n"
57                 "Usage:\n");
58         printf("\tbtmon [options]\n");
59         printf("options:\n"
60                 "\t-r, --read <file>      Read traces in btsnoop format\n"
61                 "\t-w, --write <file>     Save traces in btsnoop format\n"
62                 "\t-a, --analyze <file>   Analyze traces in btsnoop format\n"
63                 "\t-s, --server <socket>  Start monitor server socket\n"
64                 "\t-p, --priority <level> Show only priority or lower\n"
65                 "\t-i, --index <num>      Show only specified controller\n"
66                 "\t-t, --time             Show time instead of time offset\n"
67                 "\t-T, --date             Show time and date information\n"
68                 "\t-S, --sco              Dump SCO traffic\n"
69                 "\t-E, --ellisys [ip]     Send Ellisys HCI Injection\n"
70 #ifdef __TIZEN_PATCH__
71                 "\t-C, --count <num>      Save traces by <num> rotation\n"
72                 "\t-W, --size <num>       Save traces at most <num> size\n"
73 #endif
74                 "\t-h, --help             Show help options\n");
75 }
76
77 static const struct option main_options[] = {
78         { "read",    required_argument, NULL, 'r' },
79         { "write",   required_argument, NULL, 'w' },
80         { "analyze", required_argument, NULL, 'a' },
81         { "server",  required_argument, NULL, 's' },
82         { "priority",required_argument, NULL, 'p' },
83         { "index",   required_argument, NULL, 'i' },
84         { "time",    no_argument,       NULL, 't' },
85         { "date",    no_argument,       NULL, 'T' },
86         { "sco",     no_argument,       NULL, 'S' },
87         { "ellisys", required_argument, NULL, 'E' },
88 #ifdef __TIZEN_PATCH__
89         { "count",   required_argument, NULL, 'C' },
90         { "size",    required_argument, NULL, 'W' },
91 #endif
92         { "todo",    no_argument,       NULL, '#' },
93         { "version", no_argument,       NULL, 'v' },
94         { "help",    no_argument,       NULL, 'h' },
95         { }
96 };
97
98 int main(int argc, char *argv[])
99 {
100         unsigned long filter_mask = 0;
101         const char *reader_path = NULL;
102         const char *writer_path = NULL;
103         const char *analyze_path = NULL;
104         const char *ellisys_server = NULL;
105         unsigned short ellisys_port = 0;
106 #ifdef __TIZEN_PATCH__
107         int16_t rotate_count = -1;
108         ssize_t file_size = -1;
109 #endif
110         const char *str;
111         int exit_status;
112         sigset_t mask;
113
114         mainloop_init();
115
116         filter_mask |= PACKET_FILTER_SHOW_TIME_OFFSET;
117
118         for (;;) {
119                 int opt;
120
121 #ifdef __TIZEN_PATCH__
122                 opt = getopt_long(argc, argv, "r:w:a:s:p:i:tTSE:C:W:vh",
123                                                 main_options, NULL);
124 #else
125                 opt = getopt_long(argc, argv, "r:w:a:s:p:i:tTSE:vh",
126                                                 main_options, NULL);
127 #endif
128                 if (opt < 0)
129                         break;
130
131                 switch (opt) {
132                 case 'r':
133                         reader_path = optarg;
134                         break;
135                 case 'w':
136                         writer_path = optarg;
137                         break;
138                 case 'a':
139                         analyze_path = optarg;
140                         break;
141                 case 's':
142                         control_server(optarg);
143                         break;
144                 case 'p':
145                         packet_set_priority(optarg);
146                         break;
147                 case 'i':
148                         if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
149                                 str = optarg + 3;
150                         else
151                                 str = optarg;
152                         if (!isdigit(*str)) {
153                                 usage();
154                                 return EXIT_FAILURE;
155                         }
156                         packet_select_index(atoi(str));
157                         break;
158                 case 't':
159                         filter_mask &= ~PACKET_FILTER_SHOW_TIME_OFFSET;
160                         filter_mask |= PACKET_FILTER_SHOW_TIME;
161                         break;
162                 case 'T':
163                         filter_mask &= ~PACKET_FILTER_SHOW_TIME_OFFSET;
164                         filter_mask |= PACKET_FILTER_SHOW_TIME;
165                         filter_mask |= PACKET_FILTER_SHOW_DATE;
166                         break;
167                 case 'S':
168                         filter_mask |= PACKET_FILTER_SHOW_SCO_DATA;
169                         break;
170                 case 'E':
171                         ellisys_server = optarg;
172                         ellisys_port = 24352;
173                         break;
174 #ifdef __TIZEN_PATCH__
175                 case 'C':
176                         rotate_count = atoi(optarg);
177                         break;
178                 case 'W':
179                         file_size = atoll(optarg);
180                         break;
181 #endif
182                 case '#':
183                         packet_todo();
184                         lmp_todo();
185                         return EXIT_SUCCESS;
186                 case 'v':
187                         printf("%s\n", VERSION);
188                         return EXIT_SUCCESS;
189                 case 'h':
190                         usage();
191                         return EXIT_SUCCESS;
192                 default:
193                         return EXIT_FAILURE;
194                 }
195         }
196
197         if (argc - optind > 0) {
198                 fprintf(stderr, "Invalid command line parameters\n");
199                 return EXIT_FAILURE;
200         }
201
202         if (reader_path && analyze_path) {
203                 fprintf(stderr, "Display and analyze can't be combined\n");
204                 return EXIT_FAILURE;
205         }
206
207         sigemptyset(&mask);
208         sigaddset(&mask, SIGINT);
209         sigaddset(&mask, SIGTERM);
210
211         mainloop_set_signal(&mask, signal_callback, NULL, NULL);
212
213         printf("Bluetooth monitor ver %s\n", VERSION);
214
215         keys_setup();
216
217         packet_set_filter(filter_mask);
218
219         if (analyze_path) {
220                 analyze_trace(analyze_path);
221                 return EXIT_SUCCESS;
222         }
223
224         if (reader_path) {
225                 if (ellisys_server)
226                         ellisys_enable(ellisys_server, ellisys_port);
227
228                 control_reader(reader_path);
229                 return EXIT_SUCCESS;
230         }
231
232 #ifdef __TIZEN_PATCH__
233         if (writer_path && !control_writer(writer_path,
234                                 rotate_count, file_size)) {
235                 printf("Failed to open '%s'\n", writer_path);
236                 return EXIT_FAILURE;
237         }
238 #else
239         if (writer_path && !control_writer(writer_path)) {
240                 printf("Failed to open '%s'\n", writer_path);
241                 return EXIT_FAILURE;
242         }
243 #endif
244
245         if (ellisys_server)
246                 ellisys_enable(ellisys_server, ellisys_port);
247
248         if (control_tracing() < 0)
249                 return EXIT_FAILURE;
250
251         exit_status = mainloop_run();
252
253         keys_cleanup();
254
255         return exit_status;
256 }