blob: 5cf5405f6d731a45fc0b8e2b1a6dd33660ab2068 [file] [log] [blame]
// Copyright 2018 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.
#ifndef GARNET_DRIVERS_BLUETOOTH_HOST_FIDL_HOST_SERVER_H_
#define GARNET_DRIVERS_BLUETOOTH_HOST_FIDL_HOST_SERVER_H_
#include <memory>
#include <unordered_map>
#include <fuchsia/bluetooth/control/cpp/fidl.h>
#include <fuchsia/bluetooth/host/cpp/fidl.h>
#include <lib/zx/channel.h>
#include "lib/fidl/cpp/binding.h"
#include "lib/fidl/cpp/interface_request.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/weak_ptr.h"
#include "garnet/drivers/bluetooth/host/fidl/server_base.h"
#include "garnet/drivers/bluetooth/lib/gap/adapter.h"
#include "garnet/drivers/bluetooth/lib/gap/bredr_connection_manager.h"
#include "garnet/drivers/bluetooth/lib/gap/bredr_discovery_manager.h"
#include "garnet/drivers/bluetooth/lib/gap/low_energy_discovery_manager.h"
#include "garnet/drivers/bluetooth/lib/gap/pairing_delegate.h"
namespace bthost {
class GattHost;
// Implements the Host FIDL interface. Owns all FIDL connections that have been
// opened through it.
class HostServer : public AdapterServerBase<fuchsia::bluetooth::host::Host>,
public btlib::gap::PairingDelegate {
public:
HostServer(zx::channel channel, fxl::WeakPtr<btlib::gap::Adapter> adapter,
fbl::RefPtr<GattHost> gatt_host);
~HostServer() override;
private:
// ::fuchsia::bluetooth::Host overrides:
void GetInfo(GetInfoCallback callback) override;
void ListDevices(ListDevicesCallback callback) override;
void AddBondedDevices(
::std::vector<fuchsia::bluetooth::host::BondingData> bonds,
AddBondedDevicesCallback callback) override;
void SetLocalName(::std::string local_name,
SetLocalNameCallback callback) override;
void StartDiscovery(StartDiscoveryCallback callback) override;
void StopDiscovery(StopDiscoveryCallback callback) override;
void SetConnectable(bool connectable,
SetConnectableCallback callback) override;
void SetDiscoverable(bool discoverable,
SetDiscoverableCallback callback) override;
void EnableBackgroundScan(bool enabled) override;
void SetPairingDelegate(
::fuchsia::bluetooth::control::InputCapabilityType input,
::fuchsia::bluetooth::control::OutputCapabilityType output,
::fidl::InterfaceHandle<::fuchsia::bluetooth::control::PairingDelegate>
delegate) override;
void Connect(::std::string device_id, ConnectCallback callback) override;
void RequestLowEnergyCentral(
::fidl::InterfaceRequest<fuchsia::bluetooth::le::Central> central)
override;
void RequestLowEnergyPeripheral(
::fidl::InterfaceRequest<fuchsia::bluetooth::le::Peripheral> peripheral)
override;
void RequestGattServer(
::fidl::InterfaceRequest<fuchsia::bluetooth::gatt::Server> server)
override;
void RequestProfile(
::fidl::InterfaceRequest<fuchsia::bluetooth::bredr::Profile> profile)
override;
void Close() override;
// ::btlib::gap::PairingDelegate overrides:
btlib::sm::IOCapability io_capability() const override;
void CompletePairing(std::string id, btlib::sm::Status status) override;
void ConfirmPairing(std::string id, ConfirmCallback confirm) override;
void DisplayPasskey(std::string id, uint32_t passkey,
ConfirmCallback confirm) override;
void RequestPasskey(std::string id, PasskeyResponseCallback respond) override;
// Called by |adapter()->remote_device_cache()| when a remote device is
// updated.
void OnRemoteDeviceUpdated(const ::btlib::gap::RemoteDevice& remote_device);
// Called by |adapter()->remote_device_cache()| when a remote device is
// removed.
void OnRemoteDeviceRemoved(const std::string& identifier);
// Called by |adapter()->remote_device_cache()| when a remote device is
// bonded.
void OnRemoteDeviceBonded(const ::btlib::gap::RemoteDevice& remote_device);
// Called when a connection is established to a remote device, either when
// initiated by a user via a client of Host.fidl, or automatically by the GAP
// adapter
void OnConnect(btlib::gap::LowEnergyConnectionRefPtr conn_ref,
bool auto_connect);
// Called when |server| receives a channel connection error.
void OnConnectionError(Server* server);
// Helper to start LE Discovery (called by StartDiscovery)
void StartLEDiscovery(StartDiscoveryCallback callback);
// Resets the I/O capability of this server to no I/O and tells the GAP layer
// to reject incoming pairing requests.
void ResetPairingDelegate();
// Helper for binding a fidl::InterfaceRequest to a FIDL server of type
// ServerType.
template <typename ServerType, typename... Args>
void BindServer(Args... args) {
auto server = std::make_unique<ServerType>(adapter()->AsWeakPtr(),
std::move(args)...);
Server* s = server.get();
server->set_error_handler(
[this, s](zx_status_t status) { this->OnConnectionError(s); });
servers_[server.get()] = std::move(server);
}
fuchsia::bluetooth::control::PairingDelegatePtr pairing_delegate_;
// We hold a reference to GattHost for dispatching GATT FIDL requests.
fbl::RefPtr<GattHost> gatt_host_;
bool requesting_discovery_;
std::unique_ptr<::btlib::gap::LowEnergyDiscoverySession>
le_discovery_session_;
std::unique_ptr<::btlib::gap::BrEdrDiscoverySession> bredr_discovery_session_;
bool requesting_discoverable_;
std::unique_ptr<::btlib::gap::BrEdrDiscoverableSession>
bredr_discoverable_session_;
btlib::sm::IOCapability io_capability_;
// All active FIDL interface servers.
// NOTE: Each key is a raw pointer that is owned by the corresponding value.
// This allows us to create a set of managed objects that can be looked up via
// raw pointer.
std::unordered_map<Server*, std::unique_ptr<Server>> servers_;
// All LE connections that were either initiated by this HostServer or
// auto-connected by the system.
// TODO(armansito): Consider storing auto-connected references separately from
// directly connected references.
std::unordered_map<std::string, btlib::gap::LowEnergyConnectionRefPtr>
le_connections_;
// Keep this as the last member to make sure that all weak pointers are
// invalidated before other members get destroyed.
fxl::WeakPtrFactory<HostServer> weak_ptr_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(HostServer);
};
} // namespace bthost
#endif // GARNET_DRIVERS_BLUETOOTH_HOST_FIDL_HOST_SERVER_H_