Home | History | Annotate | Download | only in client
      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