bdtool.c revision 8ce36bd339ac4a6a861399377e82b8f6070d2da3
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 30const bt_interface_t *bt_interface; 31 32bt_bdaddr_t bt_remote_bdaddr; 33 34static int f_verbose; 35static bool discover = false; 36static bool discoverable = false; 37static bool bond = false; 38static bool up = false; 39static bool get_name = false; 40static bool set_name = false; 41 42static int timeout_in_sec = 30; 43static char *bd_name; 44 45static struct option long_options[] = { 46 {"bdaddr", required_argument, 0, 0 }, 47 {"discover", no_argument, 0, 0 }, 48 {"discoverable", no_argument, 0, 0 }, 49 {"time", required_argument, 0, 0 }, 50 {"bond", no_argument, 0, 0 }, 51 {"up", no_argument, 0, 0 }, 52 {"verbose", no_argument, 0, 0 }, 53 {"get_name", no_argument, 0, 0 }, 54 {"set_name", required_argument, 0, 0 }, 55 {0, 0, 0, 0 } 56}; 57 58static void usage(const char *name); 59static bool parse_args(int argc, char **argv); 60static void sig_handler(int signo); 61 62bt_property_t *adapter_get_property(bt_property_type_t type); 63 64int main(int argc, char **argv) { 65 if (!parse_args(argc, argv)) { 66 usage(argv[0]); 67 } 68 69 if (bond && discoverable) { 70 fprintf(stderr, "Can only select either bond or discoverable, not both\n"); 71 usage(argv[0]); 72 } 73 74 if (!bond && !discover && !discoverable && !up && !get_name && !set_name) { 75 fprintf(stderr, "Must specify one command\n"); 76 usage(argv[0]); 77 } 78 79 if (signal(SIGINT, sig_handler) == SIG_ERR) { 80 fprintf(stderr, "Will be unable to catch signals\n"); 81 } 82 83 fprintf(stdout, "Bringing up bluetooth adapter\n"); 84 if (!hal_open(callbacks_get_adapter_struct())) { 85 fprintf(stderr, "Unable to open Bluetooth HAL.\n"); 86 return 1; 87 } 88 89 if (discover) { 90 CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed); 91 fprintf(stdout, "BT adapter is up\n"); 92 93 fprintf(stdout, "Starting to start discovery\n"); 94 CALL_AND_WAIT(bt_interface->start_discovery(), discovery_state_changed); 95 fprintf(stdout, "Started discovery for %d seconds\n", timeout_in_sec); 96 97 sleep(timeout_in_sec); 98 99 fprintf(stdout, "Starting to cancel discovery\n"); 100 CALL_AND_WAIT(bt_interface->cancel_discovery(), discovery_state_changed); 101 fprintf(stdout, "Cancelled discovery after %d seconds\n", timeout_in_sec); 102 } 103 104 if (discoverable) { 105 CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed); 106 fprintf(stdout, "BT adapter is up\n"); 107 108 bt_property_t *property = property_new_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); 109 110 int rc = bt_interface->set_adapter_property(property); 111 fprintf(stdout, "Set rc:%d device as discoverable for %d seconds\n", rc, timeout_in_sec); 112 113 sleep(timeout_in_sec); 114 115 property_free(property); 116 } 117 118 if (bond) { 119 if (bdaddr_is_empty(&bt_remote_bdaddr)) { 120 fprintf(stderr, "Must specify a remote device address [ --bdaddr=xx:yy:zz:aa:bb:cc ]\n"); 121 exit(1); 122 } 123 124 CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed); 125 fprintf(stdout, "BT adapter is up\n"); 126 127 int rc = bt_interface->create_bond(&bt_remote_bdaddr, 0 /* UNKNOWN; Currently not documented :( */); 128 fprintf(stdout, "Started bonding:%d for %d seconds\n", rc, timeout_in_sec); 129 130 sleep(timeout_in_sec); 131 } 132 133 if (up) { 134 CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed); 135 fprintf(stdout, "BT adapter is up\n"); 136 137 fprintf(stdout, "Waiting for %d seconds\n", timeout_in_sec); 138 sleep(timeout_in_sec); 139 } 140 141 if (get_name) { 142 CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed); 143 fprintf(stdout, "BT adapter is up\n"); 144 CALL_AND_WAIT(bt_interface->get_adapter_property(BT_PROPERTY_BDNAME), adapter_properties); 145 bt_property_t *property = adapter_get_property(BT_PROPERTY_BDNAME); 146 const bt_bdname_t *bdname = property_extract_bdname(property); 147 if (bdname) 148 printf("Queried bluetooth device name:%s\n", bdname->name); 149 else 150 printf("No name\n"); 151 } 152 153 if (set_name) { 154 CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed); 155 fprintf(stdout, "BT adapter is up\n"); 156 157 bt_property_t *property = property_new_name(bd_name); 158 printf("Setting bluetooth device name to:%s\n", bd_name); 159 CALL_AND_WAIT(bt_interface->set_adapter_property(property), adapter_properties); 160 CALL_AND_WAIT(bt_interface->get_adapter_property(BT_PROPERTY_BDNAME), adapter_properties); 161 property_free(property); 162 sleep(timeout_in_sec); 163 } 164 165 CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed); 166 fprintf(stdout, "BT adapter is down\n"); 167} 168 169static void sig_handler(int signo) { 170 if (signo == SIGINT) { 171 fprintf(stderr, "Received SIGINT\n"); 172 CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed); 173 fprintf(stderr, "BT adapter is down\n"); 174 exit(1); 175 } 176} 177 178static void usage(const char *name) { 179 fprintf(stderr, "Usage: %s [--bond|--discover|--discoverable-|-up] [--bdaddr=<bdaddr>] [--time=<time_in_sec>] --verbose\n", name); 180 fprintf(stderr, " bond: Discover actively advertising devices\n"); 181 fprintf(stderr, " discover: Discover actively advertising devices\n"); 182 fprintf(stderr, " discoverable: Set into a connectable and discoverable mode\n"); 183 fprintf(stderr, " up: Only bring up stack\n"); 184 fprintf(stderr, " time: Time to hold in the specified mode\n"); 185 exit(1); 186} 187 188static bool parse_args(int argc, char **argv) { 189 while (1) { 190 int option_index = 0; 191 int c = getopt_long_only(argc, argv, "", long_options, &option_index); 192 if (c != 0) 193 break; 194 195 switch (c) { 196 case 0: 197 if (option_index == 0) { 198 if (!string_to_bdaddr(optarg, &bt_remote_bdaddr)) { 199 return false; 200 } 201 } 202 if (option_index == 1) { 203 discover = true; 204 } 205 if (option_index == 2) { 206 discoverable = true; 207 } 208 if (option_index == 3) { 209 timeout_in_sec = atoi(optarg); 210 } 211 if (option_index == 4) { 212 bond = true; 213 } 214 if (option_index == 5) { 215 up = true; 216 } 217 if (option_index == 6) { 218 f_verbose++; 219 } 220 if (option_index == 7) { 221 get_name = true; 222 } 223 if (option_index == 8) { 224 bd_name = (char *)optarg; 225 set_name = true; 226 } 227 break; 228 229 default: 230 fprintf(stderr, "?? getopt returned character code 0%o ??\n", c); 231 } 232 } 233 234 if (optind < argc) { 235 fprintf(stderr, "non-option ARGV-elements: "); 236 while (optind < argc) 237 fprintf(stderr, "%s ", argv[optind++]); 238 fprintf(stderr, "\n"); 239 return false; 240 } 241 return true; 242} 243