OSDN Git Service

Pass unknown run_unit_tests long arguments to tests am: 6babef0456 am: bc2b435ab4
[android-x86/system-bt.git] / tools / bdtool / bdtool.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 #include <getopt.h>
20 #include <signal.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23
24 #include "btcore/include/bdaddr.h"
25 #include "btcore/include/property.h"
26 #include "osi/include/osi.h"
27 #include "test/suite/support/callbacks.h"
28 #include "test/suite/support/hal.h"
29
30 static const bt_uuid_t HFP_UUID = {{ 0x00, 0x00, 0x11, 0x1E, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }};
31 static const bt_uuid_t HFP_AG_UUID = {{ 0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }};
32
33 const bt_interface_t *bt_interface;
34
35 bt_bdaddr_t bt_remote_bdaddr;
36
37 static int f_verbose;
38 static bool discover = false;
39 static bool discoverable = false;
40 static bool bond = false;
41 static bool up = false;
42 static bool get_name = false;
43 static bool set_name = false;
44 static bool sco_listen = false;
45 static bool sco_connect = false;
46
47 static int timeout_in_sec = 30;
48 static char *bd_name;
49
50 static struct option long_options[] = {
51   {"bdaddr", required_argument, 0, 0 },
52   {"discover", no_argument, 0, 0 },
53   {"discoverable", no_argument, 0, 0 },
54   {"time", required_argument, 0, 0 },
55   {"bond", no_argument, 0, 0 },
56   {"up", no_argument, 0, 0 },
57   {"verbose", no_argument, 0, 0 },
58   {"get_name", no_argument, 0, 0 },
59   {"set_name", required_argument, 0, 0 },
60   {"sco_listen", no_argument, 0, 0 },
61   {"sco_connect", no_argument, 0, 0 },
62   {0, 0, 0, 0 }
63 };
64
65 static void usage(const char *name);
66 static bool parse_args(int argc, char **argv);
67 static void sig_handler(int signo);
68
69 bt_property_t *adapter_get_property(bt_property_type_t type);
70
71 int main(int argc, char **argv) {
72   if (!parse_args(argc, argv)) {
73     usage(argv[0]);
74   }
75
76   if (bond && discoverable) {
77     fprintf(stderr, "Can only select either bond or discoverable, not both\n");
78     usage(argv[0]);
79   }
80
81   if (sco_listen && sco_connect) {
82     fprintf(stderr, "Can only select either sco_listen or sco_connect, not both\n");
83     usage(argv[0]);
84   }
85
86   if (!bond && !discover && !discoverable && !up && !get_name && !set_name && !sco_listen && !sco_connect) {
87     fprintf(stderr, "Must specify one command\n");
88     usage(argv[0]);
89   }
90
91   if (signal(SIGINT, sig_handler) == SIG_ERR) {
92     fprintf(stderr, "Will be unable to catch signals\n");
93   }
94
95   fprintf(stdout, "Bringing up bluetooth adapter\n");
96   if (!hal_open(callbacks_get_adapter_struct())) {
97     fprintf(stderr, "Unable to open Bluetooth HAL.\n");
98     return 1;
99   }
100
101   if (discover) {
102     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
103     fprintf(stdout, "BT adapter is up\n");
104
105     fprintf(stdout, "Starting to start discovery\n");
106     CALL_AND_WAIT(bt_interface->start_discovery(), discovery_state_changed);
107     fprintf(stdout, "Started discovery for %d seconds\n", timeout_in_sec);
108
109     sleep(timeout_in_sec);
110
111     fprintf(stdout, "Starting to cancel discovery\n");
112     CALL_AND_WAIT(bt_interface->cancel_discovery(), discovery_state_changed);
113     fprintf(stdout, "Cancelled discovery after %d seconds\n", timeout_in_sec);
114   }
115
116   if (discoverable) {
117     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
118     fprintf(stdout, "BT adapter is up\n");
119
120     bt_property_t *property = property_new_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
121
122     int rc = bt_interface->set_adapter_property(property);
123     fprintf(stdout, "Set rc:%d device as discoverable for %d seconds\n", rc, timeout_in_sec);
124
125     sleep(timeout_in_sec);
126
127     property_free(property);
128   }
129
130    if (bond) {
131     if (bdaddr_is_empty(&bt_remote_bdaddr)) {
132       fprintf(stderr, "Must specify a remote device address [ --bdaddr=xx:yy:zz:aa:bb:cc ]\n");
133       exit(1);
134     }
135
136     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
137     fprintf(stdout, "BT adapter is up\n");
138
139     int rc = bt_interface->create_bond(&bt_remote_bdaddr, 0 /* UNKNOWN; Currently not documented :( */);
140     fprintf(stdout, "Started bonding:%d for %d seconds\n", rc, timeout_in_sec);
141
142     sleep(timeout_in_sec);
143   }
144
145   if (up) {
146     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
147     fprintf(stdout, "BT adapter is up\n");
148
149     fprintf(stdout, "Waiting for %d seconds\n", timeout_in_sec);
150     sleep(timeout_in_sec);
151   }
152
153   if (get_name) {
154     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
155     fprintf(stdout, "BT adapter is up\n");
156     int error;
157     CALL_AND_WAIT(error = bt_interface->get_adapter_property(BT_PROPERTY_BDNAME), adapter_properties);
158     if (error != BT_STATUS_SUCCESS) {
159       fprintf(stderr, "Unable to get adapter property\n");
160       exit(1);
161     }
162     bt_property_t *property = adapter_get_property(BT_PROPERTY_BDNAME);
163     const bt_bdname_t *name = property_as_name(property);
164     if (name)
165       printf("Queried bluetooth device name:%s\n", name->name);
166     else
167       printf("No name\n");
168   }
169
170   if (set_name) {
171     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
172     fprintf(stdout, "BT adapter is up\n");
173
174     bt_property_t *property = property_new_name(bd_name);
175     printf("Setting bluetooth device name to:%s\n", bd_name);
176     int error;
177     CALL_AND_WAIT(error = bt_interface->set_adapter_property(property), adapter_properties);
178     if (error != BT_STATUS_SUCCESS) {
179       fprintf(stderr, "Unable to set adapter property\n");
180       exit(1);
181     }
182     CALL_AND_WAIT(error = bt_interface->get_adapter_property(BT_PROPERTY_BDNAME), adapter_properties);
183     if (error != BT_STATUS_SUCCESS) {
184       fprintf(stderr, "Unable to get adapter property\n");
185       exit(1);
186     }
187     property_free(property);
188     sleep(timeout_in_sec);
189   }
190
191   if (sco_listen) {
192     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
193     fprintf(stdout, "BT adapter is up\n");
194
195     bt_property_t *property = property_new_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
196     CALL_AND_WAIT(bt_interface->set_adapter_property(property), adapter_properties);
197     property_free(property);
198
199     const btsock_interface_t *sock = bt_interface->get_profile_interface(BT_PROFILE_SOCKETS_ID);
200
201     int rfcomm_fd = INVALID_FD;
202     int error = sock->listen(BTSOCK_RFCOMM, "meow", (const uint8_t *)&HFP_AG_UUID, 0, &rfcomm_fd, 0);
203     if (error != BT_STATUS_SUCCESS) {
204       fprintf(stderr, "Unable to listen for incoming RFCOMM socket: %d\n", error);
205       exit(1);
206     }
207
208     int sock_fd = INVALID_FD;
209     error = sock->listen(BTSOCK_SCO, NULL, NULL, 5, &sock_fd, 0);
210     if (error != BT_STATUS_SUCCESS) {
211       fprintf(stderr, "Unable to listen for incoming SCO sockets: %d\n", error);
212       exit(1);
213     }
214     fprintf(stdout, "Waiting for incoming SCO connections...\n");
215     sleep(timeout_in_sec);
216   }
217
218   if (sco_connect) {
219     if (bdaddr_is_empty(&bt_remote_bdaddr)) {
220       fprintf(stderr, "Must specify a remote device address [ --bdaddr=xx:yy:zz:aa:bb:cc ]\n");
221       exit(1);
222     }
223
224     CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
225     fprintf(stdout, "BT adapter is up\n");
226
227     const btsock_interface_t *sock = bt_interface->get_profile_interface(BT_PROFILE_SOCKETS_ID);
228
229     int rfcomm_fd = INVALID_FD;
230     int error = sock->connect(&bt_remote_bdaddr, BTSOCK_RFCOMM, (const uint8_t *)&HFP_AG_UUID, 0, &rfcomm_fd, 0);
231     if (error != BT_STATUS_SUCCESS) {
232       fprintf(stderr, "Unable to connect to RFCOMM socket: %d.\n", error);
233       exit(1);
234     }
235
236     WAIT(acl_state_changed);
237
238     fprintf(stdout, "Establishing SCO connection...\n");
239
240     int sock_fd = INVALID_FD;
241     error = sock->connect(&bt_remote_bdaddr, BTSOCK_SCO, NULL, 5, &sock_fd, 0);
242     if (error != BT_STATUS_SUCCESS) {
243       fprintf(stderr, "Unable to connect to SCO socket: %d.\n", error);
244       exit(1);
245     }
246     sleep(timeout_in_sec);
247   }
248
249   CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed);
250   fprintf(stdout, "BT adapter is down\n");
251 }
252
253 static void sig_handler(int signo) {
254   if (signo == SIGINT) {
255     fprintf(stderr, "Received SIGINT\n");
256     CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed);
257     fprintf(stderr, "BT adapter is down\n");
258     exit(1);
259   }
260 }
261
262 static void usage(const char *name) {
263   fprintf(stderr, "Usage: %s [--bond|--discover|--discoverable|--up|--sco_listen|--sco_connect] [--bdaddr=<bdaddr>] [--time=<time_in_sec>] --verbose\n", name);
264   fprintf(stderr, "     bond: Discover actively advertising devices\n");
265   fprintf(stderr, "     discover: Discover actively advertising devices\n");
266   fprintf(stderr, "     discoverable: Set into a connectable and discoverable mode\n");
267   fprintf(stderr, "     up: Only bring up stack\n");
268   fprintf(stderr, "     sco_listen: Listen for incoming SCO connections\n");
269   fprintf(stderr, "     sco_connect: Establish a SCO connection with another device\n");
270   fprintf(stderr, "     time: Time to hold in the specified mode\n");
271   exit(1);
272 }
273
274 static bool parse_args(int argc, char **argv) {
275   while (1) {
276     int option_index = 0;
277     int c = getopt_long_only(argc, argv, "", long_options, &option_index);
278     if (c != 0)
279       break;
280
281     switch (c) {
282       case 0:
283         if (option_index == 0) {
284           if (!string_to_bdaddr(optarg, &bt_remote_bdaddr)) {
285             return false;
286           }
287         }
288         if (option_index == 1) {
289           discover = true;
290         }
291         if (option_index == 2) {
292           discoverable = true;
293         }
294         if (option_index == 3) {
295           timeout_in_sec = atoi(optarg);
296         }
297         if (option_index == 4) {
298           bond  = true;
299         }
300         if (option_index == 5) {
301           up = true;
302         }
303         if (option_index == 6) {
304           f_verbose++;
305         }
306         if (option_index == 7) {
307           get_name = true;
308         }
309         if (option_index == 8) {
310           bd_name = (char *)optarg;
311           set_name = true;
312         }
313         if (option_index == 9) {
314           sco_listen = true;
315         }
316         if (option_index == 10) {
317           sco_connect = true;
318         }
319         break;
320
321       default:
322         fprintf(stderr, "?? getopt returned character code 0%o ??\n", c);
323     }
324   }
325
326   if (optind < argc) {
327     fprintf(stderr, "non-option ARGV-elements: ");
328     while (optind < argc)
329       fprintf(stderr, "%s ", argv[optind++]);
330     fprintf(stderr, "\n");
331     return false;
332   }
333   return true;
334 }