main.cc revision 5192309af14408c3f170f15c1282ae5c1eb5abff
1f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//
2f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  Copyright (C) 2015 Google, Inc.
3f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//
4f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  Licensed under the Apache License, Version 2.0 (the "License");
5f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  you may not use this file except in compliance with the License.
6f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  You may obtain a copy of the License at:
7f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//
8f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  http://www.apache.org/licenses/LICENSE-2.0
9f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//
10f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  Unless required by applicable law or agreed to in writing, software
11f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  distributed under the License is distributed on an "AS IS" BASIS,
12f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  See the License for the specific language governing permissions and
14f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//  limitations under the License.
15f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray//
16f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
17fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray#include <iostream>
18fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray#include <string>
19fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
20f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray#include <base/logging.h>
215192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray#include <base/strings/string_split.h>
225192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray#include <base/strings/string_util.h>
23f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
242117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#include "service/adapter_state.h"
25f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray#include "service/ipc/binder/IBluetooth.h"
26f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
27fcf2e0391950a8b140082fbe78688fa89471fbedArman Ugurayusing namespace std;
28fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
29f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Ugurayusing android::sp;
30f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
31f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Ugurayusing ipc::binder::IBluetooth;
32f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
332117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguraynamespace {
342117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
352117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_OFF         "\x1B[0m"
362117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_RED         "\x1B[0;91m"
372117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_GREEN       "\x1B[0;92m"
382117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_YELLOW      "\x1B[0;93m"
392117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_BLUE        "\x1B[0;94m"
402117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_MAGENTA     "\x1B[0;95m"
412117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_BOLDGRAY    "\x1B[1;30m"
422117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_BOLDWHITE   "\x1B[1;37m"
432117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray#define COLOR_BOLDYELLOW  "\x1B[1;93m"
44fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
45fcf2e0391950a8b140082fbe78688fa89471fbedArman Ugurayconst char kCommandDisable[] = "disable";
46fcf2e0391950a8b140082fbe78688fa89471fbedArman Ugurayconst char kCommandEnable[] = "enable";
47fcf2e0391950a8b140082fbe78688fa89471fbedArman Ugurayconst char kCommandGetState[] = "get-state";
48fcf2e0391950a8b140082fbe78688fa89471fbedArman Ugurayconst char kCommandIsEnabled[] = "is-enabled";
49fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
505192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray#define CHECK_ARGS_COUNT(args, op, num, msg) \
515192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  if (!(args.size() op num)) { \
525192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    PrintError(msg); \
535192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    return; \
545192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  }
555192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray#define CHECK_NO_ARGS(args) \
565192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_ARGS_COUNT(args, ==, 0, "Expected no arguments")
575192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
585192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid PrintError(const string& message) {
595192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  cout << COLOR_RED << message << COLOR_OFF << endl;
605192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
615192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
62fcf2e0391950a8b140082fbe78688fa89471fbedArman Ugurayvoid PrintCommandStatus(bool status) {
63fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  cout << COLOR_BOLDWHITE "Command status: " COLOR_OFF
64fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray       << (status ? (COLOR_GREEN "success") : (COLOR_RED "failure"))
65fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray       << COLOR_OFF << endl << endl;
66fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray}
67fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
685192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid PrintFieldAndValue(const string& field, const string& value) {
695192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  cout << COLOR_BOLDWHITE << field << ": " << COLOR_BOLDYELLOW << value
705192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray       << COLOR_OFF << endl;
715192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
725192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
735192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid PrintFieldAndBoolValue(const string& field, bool value) {
745192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue(field, (value ? "true" : "false"));
755192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
765192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
775192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleDisable(IBluetooth* bt_iface, const vector<string>& args) {
785192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
79fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  PrintCommandStatus(bt_iface->Disable());
80fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray}
81fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
825192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleEnable(IBluetooth* bt_iface, const vector<string>& args) {
835192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
84fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  PrintCommandStatus(bt_iface->Enable());
85fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray}
86fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
875192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleGetState(IBluetooth* bt_iface, const vector<string>& args) {
885192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
892117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  bluetooth::AdapterState state = static_cast<bluetooth::AdapterState>(
902117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray      bt_iface->GetState());
915192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue("Adapter state", bluetooth::AdapterStateToString(state));
92fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray}
93fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
945192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleIsEnabled(IBluetooth* bt_iface, const vector<string>& args) {
955192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
96fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  bool enabled = bt_iface->IsEnabled();
975192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndBoolValue("Adapter enabled", enabled);
98fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray}
99fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
1005192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleGetLocalAddress(IBluetooth* bt_iface, const vector<string>& args) {
1015192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
1025192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  string address = bt_iface->GetAddress();
1035192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue("Adapter address", address);
1045192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
1055192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1065192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleSetLocalName(IBluetooth* bt_iface, const vector<string>& args) {
1075192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_ARGS_COUNT(args, >=, 1, "No name was given");
1085192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1095192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  std::string name;
1105192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  for (const auto& arg : args)
1115192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    name += arg + " ";
1125192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1135192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &name);
1145192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1155192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintCommandStatus(bt_iface->SetName(name));
1165192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
1175192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1185192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleGetLocalName(IBluetooth* bt_iface, const vector<string>& args) {
1195192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
1205192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  string name = bt_iface->GetName();
1215192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue("Adapter name", name);
1225192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
1235192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1245192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleAdapterInfo(IBluetooth* bt_iface, const vector<string>& args) {
1255192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  CHECK_NO_ARGS(args);
1265192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1275192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  cout << COLOR_BOLDWHITE "Adapter Properties: " COLOR_OFF << endl;
1285192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1295192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue("\tAddress", bt_iface->GetAddress());
1305192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue("\tState", bluetooth::AdapterStateToString(
1315192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray      static_cast<bluetooth::AdapterState>(bt_iface->GetState())));
1325192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  PrintFieldAndValue("\tName", bt_iface->GetName());
1335192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray}
1345192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1355192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleHelp(IBluetooth* bt_iface, const vector<string>& args);
1362117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
137fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguraystruct {
138fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  string command;
1395192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  void (*func)(IBluetooth*, const vector<string>& args);
1402117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  string help;
141fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray} kCommandMap[] = {
1425192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "help", HandleHelp, "\t\t\tDisplay this message" },
1435192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "disable", HandleDisable, "\t\t\tDisable Bluetooth" },
1445192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "enable", HandleEnable, "\t\t\tEnable Bluetooth" },
1455192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "get-state", HandleGetState, "\t\tGet the current adapter state" },
1465192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "is-enabled", HandleIsEnabled, "\t\tReturn if Bluetooth is enabled" },
1475192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "get-local-address", HandleGetLocalAddress,
1485192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    "\tGet the local adapter address" },
1495192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "set-local-name", HandleSetLocalName, "\t\tSet the local adapter name" },
1505192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "get-local-name", HandleGetLocalName, "\t\tGet the local adapter name" },
1515192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray  { "adapter-info", HandleAdapterInfo, "\t\tPrint adapter properties" },
152fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  {},
153fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray};
154f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
1555192309af14408c3f170f15c1282ae5c1eb5abffArman Ugurayvoid HandleHelp(IBluetooth* /* bt_iface */, const vector<string>& /* args */) {
1562117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  cout << endl;
1572117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  for (int i = 0; kCommandMap[i].func; i++)
1582117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    cout << "\t" << kCommandMap[i].command << kCommandMap[i].help << endl;
1592117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  cout << endl;
1602117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray}
1612117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
1622117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray}  // namespace
1632117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
164f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Ugurayint main() {
165f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray  sp<IBluetooth> bt_iface = IBluetooth::getClientInterface();
166f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray  if (!bt_iface.get()) {
167f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray    LOG(ERROR) << "Failed to obtain handle on IBluetooth";
168f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray    return EXIT_FAILURE;
169f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray  }
170f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
171fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  cout << COLOR_BOLDWHITE << "Fluoride Command-Line Interface\n" << COLOR_OFF
1722117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray       << endl
1732117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray       << "Type \"help\" to see possible commands.\n"
174fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray       << endl;
175fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
176fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  while (true) {
177fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray    string command;
1785192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
179fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray    cout << COLOR_BLUE << "[FCLI] " << COLOR_OFF;
180fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray    getline(cin, command);
181fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
1825192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    vector<string> args;
1835192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    base::SplitString(command, ' ', &args);
1845192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1855192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    if (args.empty())
1865192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray      continue;
1875192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
1885192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    // The first argument is the command while the remaning are what we pass to
1895192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    // the handler functions.
1905192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    command = args[0];
1915192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray    args.erase(args.begin());
1925192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray
193fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray    bool command_handled = false;
1942117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    for (int i = 0; kCommandMap[i].func && !command_handled; i++) {
195fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray      if (command == kCommandMap[i].command) {
1965192309af14408c3f170f15c1282ae5c1eb5abffArman Uguray        kCommandMap[i].func(bt_iface.get(), args);
197fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray        command_handled = true;
198fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray      }
199fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray    }
200fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray
201fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray    if (!command_handled)
202fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray      cout << "Unrecognized command: " << command << endl;
203fcf2e0391950a8b140082fbe78688fa89471fbedArman Uguray  }
204f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray
205f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray  return EXIT_SUCCESS;
206f52095257e36b887d7ddfd1f00871b9311dbfa1bArman Uguray}
207