1 // 2 // Copyright (C) 2015 Google, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include <iostream> 18 #include <string> 19 20 #include <base/at_exit.h> 21 #include <base/command_line.h> 22 #include <base/logging.h> 23 #include <base/macros.h> 24 #include <base/strings/string_number_conversions.h> 25 #include <base/strings/string_split.h> 26 #include <base/strings/string_util.h> 27 #include <binder/IPCThreadState.h> 28 #include <binder/IServiceManager.h> 29 #include <binder/ProcessState.h> 30 31 #include <android/bluetooth/BnBluetoothCallback.h> 32 #include <android/bluetooth/BnBluetoothGattClientCallback.h> 33 #include <android/bluetooth/BnBluetoothLeAdvertiserCallback.h> 34 #include <android/bluetooth/BnBluetoothLeScannerCallback.h> 35 #include <android/bluetooth/BnBluetoothLowEnergyCallback.h> 36 #include <android/bluetooth/IBluetooth.h> 37 #include <android/bluetooth/IBluetoothGattClient.h> 38 #include <android/bluetooth/IBluetoothLeAdvertiser.h> 39 #include <android/bluetooth/IBluetoothLeScanner.h> 40 #include <android/bluetooth/IBluetoothLowEnergy.h> 41 #include <bluetooth/adapter_state.h> 42 #include <bluetooth/low_energy_constants.h> 43 #include <bluetooth/scan_filter.h> 44 #include <bluetooth/scan_settings.h> 45 #include <bluetooth/uuid.h> 46 47 using namespace std; 48 49 using android::sp; 50 using android::String8; 51 using android::String16; 52 using android::binder::Status; 53 using android::OK; 54 using android::getService; 55 56 using android::bluetooth::IBluetooth; 57 using android::bluetooth::IBluetoothGattClient; 58 using android::bluetooth::IBluetoothLeAdvertiser; 59 using android::bluetooth::IBluetoothLeScanner; 60 using android::bluetooth::IBluetoothLowEnergy; 61 62 namespace { 63 64 #define COLOR_OFF "\x1B[0m" 65 #define COLOR_RED "\x1B[0;91m" 66 #define COLOR_GREEN "\x1B[0;92m" 67 #define COLOR_YELLOW "\x1B[0;93m" 68 #define COLOR_BLUE "\x1B[0;94m" 69 #define COLOR_MAGENTA "\x1B[0;95m" 70 #define COLOR_BOLDGRAY "\x1B[1;30m" 71 #define COLOR_BOLDWHITE "\x1B[1;37m" 72 #define COLOR_BOLDYELLOW "\x1B[1;93m" 73 #define CLEAR_LINE "\x1B[2K" 74 75 #define CHECK_ARGS_COUNT(args, op, num, msg) \ 76 if (!((args).size() op num)) { \ 77 PrintError(msg); \ 78 return; \ 79 } 80 #define CHECK_NO_ARGS(args) \ 81 CHECK_ARGS_COUNT(args, ==, 0, "Expected no arguments") 82 83 // TODO(armansito): Clean up this code. Right now everything is in this 84 // monolithic file. We should organize this into different classes for command 85 // handling, console output/printing, callback handling, etc. 86 // (See http://b/23387611) 87 88 // Used to synchronize the printing of the command-line prompt and incoming 89 // Binder callbacks. 90 std::atomic_bool showing_prompt(false); 91 92 // The registered IBluetoothLowEnergy client handle. If |ble_registering| is 93 // true then an operation to register the client is in progress. 94 std::atomic_bool ble_registering(false); 95 std::atomic_int ble_client_id(0); 96 97 // The registered IBluetoothLeAdvertiser handle. If |ble_advertiser_registering| 98 // is true then an operation to register the advertiser is in progress. 99 const int invalid_advertiser_id = -1; 100 std::atomic_bool ble_advertiser_registering(false); 101 std::atomic_int ble_advertiser_id(invalid_advertiser_id); 102 103 // The registered IBluetoothLeScanner handle. If |ble_scanner_registering| is 104 // true then an operation to register the scanner is in progress. 105 std::atomic_bool ble_scanner_registering(false); 106 std::atomic_int ble_scanner_id(0); 107 108 // The registered IBluetoothGattClient client handle. If |gatt_registering| is 109 // true then an operation to register the client is in progress. 110 std::atomic_bool gatt_registering(false); 111 std::atomic_int gatt_client_id(0); 112 113 // True if we should dump the scan record bytes for incoming scan results. 114 std::atomic_bool dump_scan_record(false); 115 116 // True if the remote process has died and we should exit. 117 std::atomic_bool should_exit(false); 118 119 std::string kServiceName = "bluetooth-service"; 120 121 void PrintPrompt() { cout << COLOR_BLUE "[FCLI] " COLOR_OFF << flush; } 122 123 void PrintError(const string& message) { 124 cout << COLOR_RED << message << COLOR_OFF << endl; 125 } 126 127 void PrintOpStatus(const std::string& op, bool status) { 128 cout << COLOR_BOLDWHITE << op << " status: " COLOR_OFF 129 << (status ? (COLOR_GREEN "success") : (COLOR_RED "failure")) 130 << COLOR_OFF << endl; 131 } 132 133 inline void BeginAsyncOut() { 134 if (showing_prompt.load()) cout << CLEAR_LINE << "\r"; 135 } 136 137 inline void EndAsyncOut() { 138 std::flush(cout); 139 if (showing_prompt.load()) 140 PrintPrompt(); 141 else 142 cout << endl; 143 } 144 145 class CLIBluetoothCallback : public android::bluetooth::BnBluetoothCallback { 146 public: 147 CLIBluetoothCallback() = default; 148 ~CLIBluetoothCallback() override = default; 149 150 // IBluetoothCallback overrides: 151 Status OnBluetoothStateChange(int32_t prev_state, 152 int32_t new_state) override { 153 BeginAsyncOut(); 154 cout << COLOR_BOLDWHITE "Adapter state changed: " COLOR_OFF << COLOR_MAGENTA 155 << AdapterStateToString(bluetooth::AdapterState(prev_state)) 156 << COLOR_OFF << COLOR_BOLDWHITE " -> " COLOR_OFF << COLOR_BOLDYELLOW 157 << AdapterStateToString(bluetooth::AdapterState(new_state)) 158 << COLOR_OFF; 159 EndAsyncOut(); 160 161 return Status::ok(); 162 } 163 164 private: 165 DISALLOW_COPY_AND_ASSIGN(CLIBluetoothCallback); 166 }; 167 168 class CLIBluetoothLowEnergyCallback 169 : public android::bluetooth::BnBluetoothLowEnergyCallback { 170 public: 171 CLIBluetoothLowEnergyCallback() = default; 172 ~CLIBluetoothLowEnergyCallback() override = default; 173 174 // IBluetoothLowEnergyCallback overrides: 175 Status OnClientRegistered(int status, int client_id) override { 176 BeginAsyncOut(); 177 if (status != bluetooth::BLE_STATUS_SUCCESS) { 178 PrintError("Failed to register BLE client"); 179 } else { 180 ble_client_id = client_id; 181 cout << COLOR_BOLDWHITE "Registered BLE client with ID: " COLOR_OFF 182 << COLOR_GREEN << client_id << COLOR_OFF; 183 } 184 EndAsyncOut(); 185 186 ble_registering = false; 187 return Status::ok(); 188 } 189 190 Status OnConnectionState(int status, int client_id, const String16& address, 191 bool connected) override { 192 BeginAsyncOut(); 193 cout << COLOR_BOLDWHITE "Connection state: " << COLOR_BOLDYELLOW "[" 194 << address << " connected: " << (connected ? "true" : "false") << " ] " 195 << COLOR_BOLDWHITE "- status: " << status 196 << COLOR_BOLDWHITE " - client_id: " << client_id << COLOR_OFF; 197 EndAsyncOut(); 198 return Status::ok(); 199 } 200 201 Status OnMtuChanged(int status, const String16& address, int mtu) override { 202 BeginAsyncOut(); 203 cout << COLOR_BOLDWHITE "MTU changed: " << COLOR_BOLDYELLOW "[" << address 204 << " ] " << COLOR_BOLDWHITE " - status: " << status 205 << COLOR_BOLDWHITE " - mtu: " << mtu << COLOR_OFF; 206 EndAsyncOut(); 207 return Status::ok(); 208 } 209 210 private: 211 DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLowEnergyCallback); 212 }; 213 214 class CLIBluetoothLeAdvertiserCallback 215 : public android::bluetooth::BnBluetoothLeAdvertiserCallback { 216 public: 217 CLIBluetoothLeAdvertiserCallback() = default; 218 ~CLIBluetoothLeAdvertiserCallback() override = default; 219 220 // IBluetoothLowEnergyCallback overrides: 221 Status OnAdvertiserRegistered(int status, int advertiser_id) override { 222 BeginAsyncOut(); 223 if (status != bluetooth::BLE_STATUS_SUCCESS) { 224 PrintError("Failed to register BLE advertiser"); 225 } else { 226 ble_advertiser_id = advertiser_id; 227 cout << COLOR_BOLDWHITE "Registered BLE advertiser with ID: " COLOR_OFF 228 << COLOR_GREEN << advertiser_id << COLOR_OFF; 229 } 230 EndAsyncOut(); 231 232 ble_advertiser_registering = false; 233 return Status::ok(); 234 } 235 236 Status OnMultiAdvertiseCallback( 237 int status, bool is_start, 238 const android::bluetooth::AdvertiseSettings& /* settings */) { 239 BeginAsyncOut(); 240 std::string op = is_start ? "start" : "stop"; 241 242 PrintOpStatus("Advertising " + op, status == bluetooth::BLE_STATUS_SUCCESS); 243 EndAsyncOut(); 244 return Status::ok(); 245 } 246 247 private: 248 DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLeAdvertiserCallback); 249 }; 250 251 class CLIBluetoothLeScannerCallback 252 : public android::bluetooth::BnBluetoothLeScannerCallback { 253 public: 254 CLIBluetoothLeScannerCallback() = default; 255 ~CLIBluetoothLeScannerCallback() override = default; 256 257 // IBluetoothLowEnergyCallback overrides: 258 Status OnScannerRegistered(int status, int scanner_id) override { 259 BeginAsyncOut(); 260 if (status != bluetooth::BLE_STATUS_SUCCESS) { 261 PrintError("Failed to register BLE client"); 262 } else { 263 ble_scanner_id = scanner_id; 264 cout << COLOR_BOLDWHITE "Registered BLE client with ID: " COLOR_OFF 265 << COLOR_GREEN << scanner_id << COLOR_OFF; 266 } 267 EndAsyncOut(); 268 269 ble_scanner_registering = false; 270 return Status::ok(); 271 } 272 273 Status OnScanResult( 274 const android::bluetooth::ScanResult& scan_result) override { 275 BeginAsyncOut(); 276 cout << COLOR_BOLDWHITE "Scan result: " << COLOR_BOLDYELLOW "[" 277 << scan_result.device_address() << "] " 278 << COLOR_BOLDWHITE "- RSSI: " << scan_result.rssi() << COLOR_OFF; 279 280 if (dump_scan_record) { 281 cout << " - Record: " 282 << base::HexEncode(scan_result.scan_record().data(), 283 scan_result.scan_record().size()); 284 } 285 EndAsyncOut(); 286 return Status::ok(); 287 } 288 289 private: 290 DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLeScannerCallback); 291 }; 292 293 class CLIGattClientCallback 294 : public android::bluetooth::BnBluetoothGattClientCallback { 295 public: 296 CLIGattClientCallback() = default; 297 ~CLIGattClientCallback() override = default; 298 299 // IBluetoothGattClientCallback overrides: 300 Status OnClientRegistered(int status, int client_id) override { 301 BeginAsyncOut(); 302 if (status != bluetooth::BLE_STATUS_SUCCESS) { 303 PrintError("Failed to register GATT client"); 304 } else { 305 gatt_client_id = client_id; 306 cout << COLOR_BOLDWHITE "Registered GATT client with ID: " COLOR_OFF 307 << COLOR_GREEN << client_id << COLOR_OFF; 308 } 309 EndAsyncOut(); 310 311 gatt_registering = false; 312 return Status::ok(); 313 } 314 315 private: 316 DISALLOW_COPY_AND_ASSIGN(CLIGattClientCallback); 317 }; 318 319 void PrintCommandStatus(bool status) { PrintOpStatus("Command", status); } 320 321 void PrintFieldAndValue(const string& field, const string& value) { 322 cout << COLOR_BOLDWHITE << field << ": " << COLOR_BOLDYELLOW << value 323 << COLOR_OFF << endl; 324 } 325 326 void PrintFieldAndBoolValue(const string& field, bool value) { 327 PrintFieldAndValue(field, (value ? "true" : "false")); 328 } 329 330 void HandleDisable(IBluetooth* bt_iface, const vector<string>& args) { 331 CHECK_NO_ARGS(args); 332 bool status; 333 bt_iface->Disable(&status); 334 PrintCommandStatus(status); 335 } 336 337 void HandleEnable(IBluetooth* bt_iface, const vector<string>& args) { 338 bool is_restricted_mode = false; 339 340 for (auto iter : args) { 341 const std::string& arg = iter; 342 if (arg == "-h") { 343 static const char kUsage[] = 344 "Usage: start-adv [flags]\n" 345 "\n" 346 "Flags:\n" 347 "\t--restricted|-r\tStart in restricted mode\n"; 348 cout << kUsage << endl; 349 return; 350 } else if (arg == "--restricted" || arg == "-r") { 351 is_restricted_mode = true; 352 } 353 } 354 355 bool status; 356 bt_iface->Enable(is_restricted_mode, &status); 357 PrintCommandStatus(status); 358 } 359 360 void HandleGetState(IBluetooth* bt_iface, const vector<string>& args) { 361 CHECK_NO_ARGS(args); 362 363 int32_t st; 364 bt_iface->GetState(&st); 365 bluetooth::AdapterState state = static_cast<bluetooth::AdapterState>(st); 366 PrintFieldAndValue("Adapter state", bluetooth::AdapterStateToString(state)); 367 } 368 369 void HandleIsEnabled(IBluetooth* bt_iface, const vector<string>& args) { 370 CHECK_NO_ARGS(args); 371 bool enabled; 372 bt_iface->IsEnabled(&enabled); 373 PrintFieldAndBoolValue("Adapter enabled", enabled); 374 } 375 376 void HandleGetLocalAddress(IBluetooth* bt_iface, const vector<string>& args) { 377 CHECK_NO_ARGS(args); 378 String16 address; 379 bt_iface->GetAddress(&address); 380 PrintFieldAndValue("Adapter address", std::string(String8(address).string())); 381 } 382 383 void HandleSetLocalName(IBluetooth* bt_iface, const vector<string>& args) { 384 CHECK_ARGS_COUNT(args, >=, 1, "No name was given"); 385 386 std::string name; 387 for (const auto& arg : args) name += arg + " "; 388 389 base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &name); 390 391 bool status; 392 bt_iface->SetName(String16(String8(name.c_str())), &status); 393 PrintCommandStatus(status); 394 } 395 396 void HandleGetLocalName(IBluetooth* bt_iface, const vector<string>& args) { 397 CHECK_NO_ARGS(args); 398 String16 name; 399 bt_iface->GetName(&name); 400 PrintFieldAndValue("Adapter name", std::string(String8(name).string())); 401 } 402 403 void HandleAdapterInfo(IBluetooth* bt_iface, const vector<string>& args) { 404 CHECK_NO_ARGS(args); 405 406 cout << COLOR_BOLDWHITE "Adapter Properties: " COLOR_OFF << endl; 407 408 String16 address; 409 bt_iface->GetAddress(&address); 410 PrintFieldAndValue("\tAddress", std::string(String8(address).string())); 411 412 int adapter_state; 413 bt_iface->GetState(&adapter_state); 414 PrintFieldAndValue("\tState", 415 bluetooth::AdapterStateToString( 416 static_cast<bluetooth::AdapterState>(adapter_state))); 417 418 String16 name; 419 bt_iface->GetName(&name); 420 PrintFieldAndValue("\tName", std::string(String8(name).string())); 421 422 bool multi_adv; 423 bt_iface->IsMultiAdvertisementSupported(&multi_adv); 424 PrintFieldAndBoolValue("\tMulti-Adv. supported", multi_adv); 425 } 426 427 void HandleSupportsMultiAdv(IBluetooth* bt_iface, const vector<string>& args) { 428 CHECK_NO_ARGS(args); 429 430 bool multi_adv; 431 bt_iface->IsMultiAdvertisementSupported(&multi_adv); 432 PrintFieldAndBoolValue("Multi-advertisement support", multi_adv); 433 } 434 435 void HandleRegisterBLEAdvertiser(IBluetooth* bt_iface, 436 const vector<string>& args) { 437 CHECK_NO_ARGS(args); 438 439 if (ble_advertiser_registering.load()) { 440 PrintError("In progress"); 441 return; 442 } 443 444 if (ble_advertiser_id.load() != invalid_advertiser_id) { 445 PrintError("Already registered"); 446 return; 447 } 448 449 sp<IBluetoothLeAdvertiser> ble_advertiser_iface; 450 bt_iface->GetLeAdvertiserInterface(&ble_advertiser_iface); 451 if (!ble_advertiser_iface.get()) { 452 PrintError("Failed to obtain handle to Bluetooth Le Advertiser interface"); 453 return; 454 } 455 456 bool status; 457 ble_advertiser_iface->RegisterAdvertiser( 458 new CLIBluetoothLeAdvertiserCallback(), &status); 459 ble_advertiser_registering = status; 460 PrintCommandStatus(status); 461 } 462 463 void HandleUnregisterBLEAdvertiser(IBluetooth* bt_iface, 464 const vector<string>& args) { 465 CHECK_NO_ARGS(args); 466 467 if (ble_advertiser_id.load() == invalid_advertiser_id) { 468 PrintError("Not registered"); 469 return; 470 } 471 472 sp<IBluetoothLeAdvertiser> ble_advertiser_iface; 473 bt_iface->GetLeAdvertiserInterface(&ble_advertiser_iface); 474 if (!ble_advertiser_iface.get()) { 475 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 476 return; 477 } 478 479 ble_advertiser_iface->UnregisterAdvertiser(ble_advertiser_id.load()); 480 ble_advertiser_id = invalid_advertiser_id; 481 PrintCommandStatus(true); 482 } 483 484 void HandleRegisterBLE(IBluetooth* bt_iface, const vector<string>& args) { 485 CHECK_NO_ARGS(args); 486 487 if (ble_registering.load()) { 488 PrintError("In progress"); 489 return; 490 } 491 492 if (ble_client_id.load()) { 493 PrintError("Already registered"); 494 return; 495 } 496 497 sp<IBluetoothLowEnergy> ble_iface; 498 bt_iface->GetLowEnergyInterface(&ble_iface); 499 if (!ble_iface.get()) { 500 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 501 return; 502 } 503 504 bool status; 505 ble_iface->RegisterClient(new CLIBluetoothLowEnergyCallback(), &status); 506 ble_registering = status; 507 PrintCommandStatus(status); 508 } 509 510 void HandleUnregisterBLE(IBluetooth* bt_iface, const vector<string>& args) { 511 CHECK_NO_ARGS(args); 512 513 if (!ble_client_id.load()) { 514 PrintError("Not registered"); 515 return; 516 } 517 518 sp<IBluetoothLowEnergy> ble_iface; 519 bt_iface->GetLowEnergyInterface(&ble_iface); 520 if (!ble_iface.get()) { 521 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 522 return; 523 } 524 525 ble_iface->UnregisterClient(ble_client_id.load()); 526 ble_client_id = 0; 527 PrintCommandStatus(true); 528 } 529 530 void HandleUnregisterAllBLE(IBluetooth* bt_iface, const vector<string>& args) { 531 CHECK_NO_ARGS(args); 532 533 sp<IBluetoothLowEnergy> ble_iface; 534 bt_iface->GetLowEnergyInterface(&ble_iface); 535 if (!ble_iface.get()) { 536 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 537 return; 538 } 539 540 ble_iface->UnregisterAll(); 541 PrintCommandStatus(true); 542 } 543 544 void HandleRegisterGATT(IBluetooth* bt_iface, const vector<string>& args) { 545 CHECK_NO_ARGS(args); 546 547 if (gatt_registering.load()) { 548 PrintError("In progress"); 549 return; 550 } 551 552 if (gatt_client_id.load()) { 553 PrintError("Already registered"); 554 return; 555 } 556 557 sp<IBluetoothGattClient> gatt_iface; 558 bt_iface->GetGattClientInterface(&gatt_iface); 559 if (!gatt_iface.get()) { 560 PrintError("Failed to obtain handle to Bluetooth GATT Client interface"); 561 return; 562 } 563 564 bool status; 565 gatt_iface->RegisterClient(new CLIGattClientCallback(), &status); 566 gatt_registering = status; 567 PrintCommandStatus(status); 568 } 569 570 void HandleUnregisterGATT(IBluetooth* bt_iface, const vector<string>& args) { 571 CHECK_NO_ARGS(args); 572 573 if (!gatt_client_id.load()) { 574 PrintError("Not registered"); 575 return; 576 } 577 578 sp<IBluetoothGattClient> gatt_iface; 579 bt_iface->GetGattClientInterface(&gatt_iface); 580 if (!gatt_iface.get()) { 581 PrintError("Failed to obtain handle to Bluetooth GATT Client interface"); 582 return; 583 } 584 585 gatt_iface->UnregisterClient(gatt_client_id.load()); 586 gatt_client_id = 0; 587 PrintCommandStatus(true); 588 } 589 590 void HandleStartAdv(IBluetooth* bt_iface, const vector<string>& args) { 591 bool include_name = false; 592 bool include_tx_power = false; 593 bool connectable = false; 594 bool set_manufacturer_data = false; 595 bool set_uuid = false; 596 bluetooth::UUID uuid; 597 598 for (auto iter = args.begin(); iter != args.end(); ++iter) { 599 const std::string& arg = *iter; 600 if (arg == "-n") 601 include_name = true; 602 else if (arg == "-t") 603 include_tx_power = true; 604 else if (arg == "-c") 605 connectable = true; 606 else if (arg == "-m") 607 set_manufacturer_data = true; 608 else if (arg == "-u") { 609 // This flag has a single argument. 610 ++iter; 611 if (iter == args.end()) { 612 PrintError("Expected a UUID after -u"); 613 return; 614 } 615 616 std::string uuid_str = *iter; 617 uuid = bluetooth::UUID(uuid_str); 618 if (!uuid.is_valid()) { 619 PrintError("Invalid UUID: " + uuid_str); 620 return; 621 } 622 623 set_uuid = true; 624 } else if (arg == "-h") { 625 static const char kUsage[] = 626 "Usage: start-adv [flags]\n" 627 "\n" 628 "Flags:\n" 629 "\t-n\tInclude device name\n" 630 "\t-t\tInclude TX power\n" 631 "\t-c\tSend connectable adv. packets (default is non-connectable)\n" 632 "\t-m\tInclude random manufacturer data\n" 633 "\t-h\tShow this help message\n"; 634 cout << kUsage << endl; 635 return; 636 } else { 637 PrintError("Unrecognized option: " + arg); 638 return; 639 } 640 } 641 642 if (ble_advertiser_id.load() == invalid_advertiser_id) { 643 PrintError("BLE advertiser not registered"); 644 return; 645 } 646 647 sp<IBluetoothLeAdvertiser> ble_advertiser_iface; 648 bt_iface->GetLeAdvertiserInterface(&ble_advertiser_iface); 649 if (!ble_advertiser_iface.get()) { 650 PrintError("Failed to obtain handle to Bluetooth Le Advertiser interface"); 651 return; 652 } 653 654 std::vector<uint8_t> data; 655 if (set_manufacturer_data) { 656 data = {{0x07, bluetooth::kEIRTypeManufacturerSpecificData, 0xe0, 0x00, 'T', 657 'e', 's', 't'}}; 658 } 659 660 if (set_uuid) { 661 // Determine the type and length bytes. 662 int uuid_size = uuid.GetShortestRepresentationSize(); 663 uint8_t type; 664 if (uuid_size == bluetooth::UUID::kNumBytes128) 665 type = bluetooth::kEIRTypeComplete128BitUUIDs; 666 else if (uuid_size == bluetooth::UUID::kNumBytes32) 667 type = bluetooth::kEIRTypeComplete32BitUUIDs; 668 else if (uuid_size == bluetooth::UUID::kNumBytes16) 669 type = bluetooth::kEIRTypeComplete16BitUUIDs; 670 else 671 NOTREACHED() << "Unexpected size: " << uuid_size; 672 673 data.push_back(uuid_size + 1); 674 data.push_back(type); 675 676 auto uuid_bytes = uuid.GetFullLittleEndian(); 677 int index = (uuid_size == 16) ? 0 : 12; 678 data.insert(data.end(), uuid_bytes.data() + index, 679 uuid_bytes.data() + index + uuid_size); 680 } 681 682 base::TimeDelta timeout; 683 684 bluetooth::AdvertiseSettings settings( 685 bluetooth::AdvertiseSettings::MODE_LOW_POWER, timeout, 686 bluetooth::AdvertiseSettings::TX_POWER_LEVEL_MEDIUM, connectable); 687 688 if (include_tx_power) { 689 data.push_back(0x02); 690 data.push_back(bluetooth::kEIRTypeTxPower); 691 data.push_back(0x00); 692 } 693 694 bluetooth::AdvertiseData adv_data(data); 695 696 if (include_name) { 697 String16 name_param; 698 bt_iface->GetName(&name_param); 699 std::string name(String8(name_param).string()); 700 data.push_back(name.length() + 1); 701 data.push_back(bluetooth::kEIRTypeCompleteLocalName); 702 data.insert(data.begin(), name.c_str(), name.c_str() + name.length()); 703 } 704 705 bluetooth::AdvertiseData scan_rsp; 706 707 bool status; 708 ble_advertiser_iface->StartMultiAdvertising( 709 ble_advertiser_id.load(), adv_data, scan_rsp, settings, &status); 710 PrintCommandStatus(status); 711 } 712 713 void HandleStopAdv(IBluetooth* bt_iface, const vector<string>& args) { 714 if (ble_advertiser_id.load() == invalid_advertiser_id) { 715 PrintError("BLE advertiser not registered"); 716 return; 717 } 718 719 sp<IBluetoothLeAdvertiser> ble_advertiser_iface; 720 bt_iface->GetLeAdvertiserInterface(&ble_advertiser_iface); 721 if (!ble_advertiser_iface.get()) { 722 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 723 return; 724 } 725 726 bool status; 727 ble_advertiser_iface->StopMultiAdvertising(ble_advertiser_id.load(), &status); 728 PrintCommandStatus(status); 729 } 730 731 void HandleConnect(IBluetooth* bt_iface, const vector<string>& args) { 732 string address; 733 734 if (args.size() != 1) { 735 PrintError("Expected MAC address as only argument"); 736 return; 737 } 738 739 address = args[0]; 740 741 if (!ble_client_id.load()) { 742 PrintError("BLE not registered"); 743 return; 744 } 745 746 sp<IBluetoothLowEnergy> ble_iface; 747 bt_iface->GetLowEnergyInterface(&ble_iface); 748 if (!ble_iface.get()) { 749 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 750 return; 751 } 752 753 bool status; 754 ble_iface->Connect(ble_client_id.load(), 755 String16(address.c_str(), address.length()), 756 false /* is_direct */, &status); 757 758 PrintCommandStatus(status); 759 } 760 761 void HandleDisconnect(IBluetooth* bt_iface, const vector<string>& args) { 762 string address; 763 764 if (args.size() != 1) { 765 PrintError("Expected MAC address as only argument"); 766 return; 767 } 768 769 address = args[0]; 770 771 if (!ble_client_id.load()) { 772 PrintError("BLE not registered"); 773 return; 774 } 775 776 sp<IBluetoothLowEnergy> ble_iface; 777 bt_iface->GetLowEnergyInterface(&ble_iface); 778 if (!ble_iface.get()) { 779 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 780 return; 781 } 782 783 bool status; 784 ble_iface->Disconnect(ble_client_id.load(), 785 String16(address.c_str(), address.length()), &status); 786 PrintCommandStatus(status); 787 } 788 789 void HandleSetMtu(IBluetooth* bt_iface, const vector<string>& args) { 790 string address; 791 int mtu; 792 793 if (args.size() != 2) { 794 PrintError("Usage: set-mtu [address] [mtu]"); 795 return; 796 } 797 798 address = args[0]; 799 mtu = std::stoi(args[1]); 800 801 if (mtu < 23) { 802 PrintError("MTU must be 23 or larger"); 803 return; 804 } 805 806 if (!ble_client_id.load()) { 807 PrintError("BLE not registered"); 808 return; 809 } 810 811 sp<IBluetoothLowEnergy> ble_iface; 812 bt_iface->GetLowEnergyInterface(&ble_iface); 813 if (!ble_iface.get()) { 814 PrintError("Failed to obtain handle to Bluetooth Low Energy interface"); 815 return; 816 } 817 818 bool status; 819 ble_iface->SetMtu(ble_client_id.load(), 820 String16(address.c_str(), address.length()), mtu, &status); 821 PrintCommandStatus(status); 822 } 823 824 void HandleRegisterBLEScanner(IBluetooth* bt_iface, 825 const vector<string>& args) { 826 CHECK_NO_ARGS(args); 827 828 if (ble_scanner_registering.load()) { 829 PrintError("In progress"); 830 return; 831 } 832 833 if (ble_scanner_id.load()) { 834 PrintError("Already registered"); 835 return; 836 } 837 838 sp<IBluetoothLeScanner> ble_scanner_iface; 839 bt_iface->GetLeScannerInterface(&ble_scanner_iface); 840 if (!ble_scanner_iface.get()) { 841 PrintError("Failed to obtain handle to Bluetooth LE Scanner interface"); 842 return; 843 } 844 845 bool status; 846 ble_scanner_iface->RegisterScanner(new CLIBluetoothLeScannerCallback(), 847 &status); 848 ble_scanner_registering = status; 849 PrintCommandStatus(status); 850 } 851 852 void HandleUnregisterBLEScanner(IBluetooth* bt_iface, 853 const vector<string>& args) { 854 CHECK_NO_ARGS(args); 855 856 if (!ble_scanner_id.load()) { 857 PrintError("Not registered"); 858 return; 859 } 860 861 sp<IBluetoothLeScanner> ble_scanner_iface; 862 bt_iface->GetLeScannerInterface(&ble_scanner_iface); 863 if (!ble_scanner_iface.get()) { 864 PrintError("Failed to obtain handle to Bluetooth LE scanner interface"); 865 return; 866 } 867 868 ble_scanner_iface->UnregisterScanner(ble_scanner_id.load()); 869 ble_scanner_id = 0; 870 PrintCommandStatus(true); 871 } 872 873 void HandleStartLeScan(IBluetooth* bt_iface, const vector<string>& args) { 874 if (!ble_client_id.load()) { 875 PrintError("BLE not registered"); 876 return; 877 } 878 879 for (const auto& arg : args) { 880 if (arg == "-d") { 881 dump_scan_record = true; 882 } else if (arg == "-h") { 883 static const char kUsage[] = 884 "Usage: start-le-scan [flags]\n" 885 "\n" 886 "Flags:\n" 887 "\t-d\tDump scan record\n" 888 "\t-h\tShow this help message\n"; 889 cout << kUsage << endl; 890 return; 891 } 892 } 893 894 sp<IBluetoothLeScanner> ble_scanner_iface; 895 bt_iface->GetLeScannerInterface(&ble_scanner_iface); 896 if (!ble_scanner_iface.get()) { 897 PrintError("Failed to obtain handle to Bluetooth LE scanner interface"); 898 return; 899 } 900 901 bluetooth::ScanSettings settings; 902 std::vector<android::bluetooth::ScanFilter> filters; 903 904 bool status; 905 ble_scanner_iface->StartScan(ble_scanner_id.load(), settings, filters, 906 &status); 907 PrintCommandStatus(status); 908 } 909 910 void HandleStopLeScan(IBluetooth* bt_iface, const vector<string>& args) { 911 if (!ble_client_id.load()) { 912 PrintError("BLE not registered"); 913 return; 914 } 915 916 sp<IBluetoothLeScanner> ble_scanner_iface; 917 bt_iface->GetLeScannerInterface(&ble_scanner_iface); 918 if (!ble_scanner_iface.get()) { 919 PrintError("Failed to obtain handle to Bluetooth LE scanner interface"); 920 return; 921 } 922 923 bool status; 924 ble_scanner_iface->StopScan(ble_scanner_id.load(), &status); 925 PrintCommandStatus(status); 926 } 927 928 void HandleHelp(IBluetooth* bt_iface, const vector<string>& args); 929 930 struct { 931 string command; 932 void (*func)(IBluetooth*, const vector<string>& args); 933 string help; 934 } kCommandMap[] = { 935 {"help", HandleHelp, "\t\t\tDisplay this message"}, 936 {"disable", HandleDisable, "\t\t\tDisable Bluetooth"}, 937 {"enable", HandleEnable, "\t\t\tEnable Bluetooth (-h for options)"}, 938 {"get-state", HandleGetState, "\t\tGet the current adapter state"}, 939 {"is-enabled", HandleIsEnabled, "\t\tReturn if Bluetooth is enabled"}, 940 {"get-local-address", HandleGetLocalAddress, 941 "\tGet the local adapter address"}, 942 {"set-local-name", HandleSetLocalName, "\t\tSet the local adapter name"}, 943 {"get-local-name", HandleGetLocalName, "\t\tGet the local adapter name"}, 944 {"adapter-info", HandleAdapterInfo, "\t\tPrint adapter properties"}, 945 {"supports-multi-adv", HandleSupportsMultiAdv, 946 "\tWhether multi-advertisement is currently supported"}, 947 {"register-le-advertiser", HandleRegisterBLEAdvertiser, 948 "\t\tRegister with the Bluetooth Low Energy Advertiser interface"}, 949 {"unregister-le-advertiser", HandleUnregisterBLEAdvertiser, 950 "\t\tUnregister from the Bluetooth LE Advertiser interface"}, 951 {"register-ble", HandleRegisterBLE, 952 "\t\tRegister with the Bluetooth Low Energy interface"}, 953 {"unregister-ble", HandleUnregisterBLE, 954 "\t\tUnregister from the Bluetooth Low Energy interface"}, 955 {"unregister-all-ble", HandleUnregisterAllBLE, 956 "\tUnregister all clients from the Bluetooth Low Energy interface"}, 957 {"register-gatt", HandleRegisterGATT, 958 "\t\tRegister with the Bluetooth GATT Client interface"}, 959 {"unregister-gatt", HandleUnregisterGATT, 960 "\t\tUnregister from the Bluetooth GATT Client interface"}, 961 {"connect-le", HandleConnect, "\t\tConnect to LE device (-h for options)"}, 962 {"disconnect-le", HandleDisconnect, 963 "\t\tDisconnect LE device (-h for options)"}, 964 {"set-mtu", HandleSetMtu, "\t\tSet MTU (-h for options)"}, 965 {"start-adv", HandleStartAdv, "\t\tStart advertising (-h for options)"}, 966 {"stop-adv", HandleStopAdv, "\t\tStop advertising"}, 967 {"register-le-scanner", HandleRegisterBLEScanner, 968 "\t\tRegister with the Bluetooth Low Energy scanner interface"}, 969 {"unregister-le-scanner", HandleUnregisterBLEScanner, 970 "\t\tUnregister from the Bluetooth LE scanner interface"}, 971 {"start-le-scan", HandleStartLeScan, 972 "\t\tStart LE device scan (-h for options)"}, 973 {"stop-le-scan", HandleStopLeScan, "\t\tStop LE device scan"}, 974 {}, 975 }; 976 977 void HandleHelp(IBluetooth* /* bt_iface */, const vector<string>& /* args */) { 978 cout << endl; 979 for (int i = 0; kCommandMap[i].func; i++) 980 cout << "\t" << kCommandMap[i].command << kCommandMap[i].help << endl; 981 cout << endl; 982 } 983 984 const char kExecuteLong[] = "exec"; 985 const char kExecuteShort[] = "e"; 986 987 bool ExecuteCommand(const sp<IBluetooth>& bt_iface, std::string& command) { 988 vector<string> args = base::SplitString(command, " ", base::TRIM_WHITESPACE, 989 base::SPLIT_WANT_ALL); 990 991 if (args.empty()) return true; 992 993 // The first argument is the command while the remaining are what we pass to 994 // the handler functions. 995 command = args[0]; 996 args.erase(args.begin()); 997 998 for (int i = 0; kCommandMap[i].func; i++) { 999 if (command == kCommandMap[i].command) { 1000 kCommandMap[i].func(bt_iface.get(), args); 1001 return true; 1002 } 1003 } 1004 1005 cout << "Unrecognized command: " << command << endl; 1006 return false; 1007 } 1008 1009 } // namespace 1010 1011 class BluetoothDeathRecipient : public android::IBinder::DeathRecipient { 1012 public: 1013 BluetoothDeathRecipient() = default; 1014 ~BluetoothDeathRecipient() override = default; 1015 1016 // android::IBinder::DeathRecipient override: 1017 void binderDied(const android::wp<android::IBinder>& /* who */) override { 1018 BeginAsyncOut(); 1019 cout << COLOR_BOLDWHITE "The Bluetooth daemon has died" COLOR_OFF << endl; 1020 cout << "\nPress 'ENTER' to exit."; 1021 EndAsyncOut(); 1022 1023 android::IPCThreadState::self()->stopProcess(); 1024 should_exit = true; 1025 } 1026 1027 private: 1028 DISALLOW_COPY_AND_ASSIGN(BluetoothDeathRecipient); 1029 }; 1030 1031 int main(int argc, char* argv[]) { 1032 base::AtExitManager exit_manager; 1033 base::CommandLine::Init(argc, argv); 1034 logging::LoggingSettings log_settings; 1035 1036 if (!logging::InitLogging(log_settings)) { 1037 LOG(ERROR) << "Failed to set up logging"; 1038 return EXIT_FAILURE; 1039 } 1040 1041 sp<IBluetooth> bt_iface; 1042 status_t status = getService(String16(kServiceName.c_str()), &bt_iface); 1043 if (status != OK) { 1044 LOG(ERROR) << "Failed to get service binder: '" << kServiceName 1045 << "' status=" << status; 1046 return EXIT_FAILURE; 1047 } 1048 1049 sp<BluetoothDeathRecipient> dr(new BluetoothDeathRecipient()); 1050 if (android::IInterface::asBinder(bt_iface.get())->linkToDeath(dr) != 1051 android::NO_ERROR) { 1052 LOG(ERROR) << "Failed to register DeathRecipient for IBluetooth"; 1053 return EXIT_FAILURE; 1054 } 1055 1056 // Initialize the Binder process thread pool. We have to set this up, 1057 // otherwise, incoming callbacks from IBluetoothCallback will block the main 1058 // thread (in other words, we have to do this as we are a "Binder server"). 1059 android::ProcessState::self()->startThreadPool(); 1060 1061 // Register Adapter state-change callback 1062 sp<CLIBluetoothCallback> callback = new CLIBluetoothCallback(); 1063 bt_iface->RegisterCallback(callback); 1064 1065 cout << COLOR_BOLDWHITE << "Fluoride Command-Line Interface\n" 1066 << COLOR_OFF << endl 1067 << "Type \"help\" to see possible commands.\n" 1068 << endl; 1069 1070 string command; 1071 1072 // Add commands from the command line, if they exist. 1073 auto command_line = base::CommandLine::ForCurrentProcess(); 1074 if (command_line->HasSwitch(kExecuteLong)) { 1075 command += command_line->GetSwitchValueASCII(kExecuteLong); 1076 } 1077 1078 if (command_line->HasSwitch(kExecuteShort)) { 1079 if (!command.empty()) command += " ; "; 1080 command += command_line->GetSwitchValueASCII(kExecuteShort); 1081 } 1082 1083 while (true) { 1084 vector<string> commands = base::SplitString( 1085 command, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 1086 for (string command : commands) { 1087 if (!ExecuteCommand(bt_iface, command)) break; 1088 } 1089 1090 commands.clear(); 1091 1092 PrintPrompt(); 1093 1094 showing_prompt = true; 1095 auto& istream = getline(cin, command); 1096 showing_prompt = false; 1097 1098 if (istream.eof() || should_exit.load()) { 1099 cout << "\nExiting" << endl; 1100 return EXIT_SUCCESS; 1101 } 1102 1103 if (!istream.good()) { 1104 LOG(ERROR) << "An error occured while reading input"; 1105 return EXIT_FAILURE; 1106 } 1107 } 1108 1109 return EXIT_SUCCESS; 1110 } 1111