blob: 4ed404bbcdf723ab4ea9f46eea49586f57c23549 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "app.h"
#include <iostream>
#include <linenoise.h>
#include "lib/fsl/tasks/message_loop.h"
#include "lib/fxl/functional/auto_call.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/strings/split_string.h"
#include "commands.h"
#include "helpers.h"
#include "logging.h"
namespace bluetoothcli {
App::App()
: context_(app::ApplicationContext::CreateFromStartupInfo()),
manager_delegate_(this),
adapter_delegate_(this) {
FXL_DCHECK(context_);
adapter_manager_ =
context_
->ConnectToEnvironmentService<bluetooth::control::AdapterManager>();
FXL_DCHECK(adapter_manager_);
adapter_manager_.set_connection_error_handler([] {
CLI_LOG() << "AdapterManager disconnected";
fsl::MessageLoop::GetCurrent()->PostQuitTask();
});
commands::RegisterCommands(this, &command_dispatcher_);
// Register with the AdapterManager as its delegate.
bluetooth::control::AdapterManagerDelegatePtr delegate;
fidl::InterfaceRequest<bluetooth::control::AdapterManagerDelegate>
delegate_request = fidl::GetProxy(&delegate);
manager_delegate_.Bind(std::move(delegate_request));
adapter_manager_->SetDelegate(std::move(delegate));
adapter_manager_->IsBluetoothAvailable([this](bool available) {
if (!available)
return;
adapter_manager_->GetActiveAdapter(fidl::GetProxy(&active_adapter_));
bluetooth::control::AdapterDelegatePtr delegate;
auto request = fidl::GetProxy(&delegate);
adapter_delegate_.Bind(std::move(request));
active_adapter_->SetDelegate(std::move(delegate));
});
}
void App::ReadNextInput() {
bool call_complete_cb = true;
auto complete_cb = [this] {
fsl::MessageLoop::GetCurrent()->task_runner()->PostTask(
[this] { ReadNextInput(); });
};
char* line = linenoise("bluetooth> ");
if (!line) {
fsl::MessageLoop::GetCurrent()->QuitNow();
return;
}
auto ac = fxl::MakeAutoCall([&call_complete_cb, line, complete_cb] {
if (call_complete_cb)
complete_cb();
free(line);
});
auto split =
fxl::SplitStringCopy(fxl::StringView(line, std::strlen(line)), " ",
fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
if (split.empty() || split[0] == "help") {
linenoiseHistoryAdd(line);
command_dispatcher_.DescribeAllCommands();
return;
}
bool cmd_found;
if (!command_dispatcher_.ExecuteCommand(split, complete_cb, &cmd_found)) {
if (!cmd_found)
CLI_LOG() << "Unknown command: " << line;
return;
}
call_complete_cb = false;
linenoiseHistoryAdd(line);
}
void App::OnActiveAdapterChanged(
bluetooth::control::AdapterInfoPtr active_adapter) {
if (!active_adapter) {
CLI_LOG() << "\n>>>> Active adapter is (null)";
active_adapter_ = nullptr;
return;
}
CLI_LOG() << "\n>>>> Active adapter: (id=" << active_adapter->identifier
<< ")\n";
adapter_manager_->GetActiveAdapter(fidl::GetProxy(&active_adapter_));
bluetooth::control::AdapterDelegatePtr delegate;
fidl::InterfaceRequest<bluetooth::control::AdapterDelegate> request =
fidl::GetProxy(&delegate);
adapter_delegate_.Bind(std::move(request));
active_adapter_->SetDelegate(std::move(delegate));
}
void App::OnAdapterAdded(bluetooth::control::AdapterInfoPtr adapter) {
CLI_LOG() << "\n>>>> Adapter added (id=" << adapter->identifier << ")\n";
}
void App::OnAdapterRemoved(const ::fidl::String& identifier) {
CLI_LOG() << "\n>>>> Adapter removed (id=" << identifier << ")\n";
}
void App::OnAdapterStateChanged(bluetooth::control::AdapterStatePtr state) {
CLI_LOG() << "\n>>>> Active adapter state changed\n";
}
void App::OnDeviceDiscovered(bluetooth::control::RemoteDevicePtr device) {
discovered_devices_[device->identifier] = std::move(device);
}
} // namespace bluetoothcli