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