// 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.

library fuchsia.bluetooth.host;

using fuchsia.bluetooth;
using fuchsia.bluetooth.control;
using fuchsia.bluetooth.gatt;
using fuchsia.bluetooth.le;
using fuchsia.bluetooth.bredr;

// Interface for interacting with a Bluetooth host device (bt-host)
interface Host {
    // The following methods fulfill a given interface request. bt-host device
    // will start processing FIDL messages. If the request cannot be fulfilled,
    // the bt-host device will close its end of the given channel.
    RequestLowEnergyCentral(request<fuchsia.bluetooth.le.Central> central);
    RequestLowEnergyPeripheral(request<fuchsia.bluetooth.le.Peripheral> peripheral);
    RequestGattServer(request<fuchsia.bluetooth.gatt.Server> server);
    RequestProfile(request<fuchsia.bluetooth.bredr.Profile> profile);

    // Shuts down the host, ending all active Bluetooth procedures:
    //
    // * All FIDL interface handles associated with this host are closed and all
    //   connections initiated via FIDL clients are severed.
    // * All scan, discovery, and advertising procedures are stopped.
    // * Bonded devices are cleared and removed from the auto-connect lists.
    // * Auto-connected peripherals are disconnected.
    //
    // This effectively resets the host to its initial state and the host remains
    // available for future requests.
    //
    // The Host will continue to send OnDeviceUpdated events as procedures get
    // terminated.
    Close();

    // Returns information about the Bluetooth adapter managed by this host.
    GetInfo() -> (fuchsia.bluetooth.control.AdapterInfo info);

    // Returns a list of all known connectable devices, included those that are
    // currently connected and/or bonded. This list does not include
    // non-connectable devices such as LE broadcasters.
    //
    // Notes:
    //
    // - When used in the GAP central role (BR/EDR or LE) the listed devices are
    // obtained during discovery and connection procedures. While in the
    // peripheral role, this will contain devices that have successfully initiated
    // connections to this host.
    //
    // - This list contains connectable devices that are discovered or connected
    // via other interfaces obtained using the interface request methods declared
    // above.
    ListDevices() -> (vector<fuchsia.bluetooth.control.RemoteDevice> devices);

    // Sets the local name for this adapter.
    SetLocalName(string local_name) -> (fuchsia.bluetooth.Status status);

    // Initiates a general discovery procedure for BR/EDR and LE devices. On success, discovered
    // devices will be reported via AdapterDelegate.OnDeviceDiscovered().
    //
    // On the LE transport, only general-discoverable and connectable peripherals will be reported.
    //
    // Discovery will continue until it is terminated via StopDiscovery() or if the proxy to the
    // Adapter gets disconnected. If the device does not support BR/EDR, only LE
    // discovery will be performed.
    //
    // An OnDeviceUpdated event will be sent when the discovery procedures are
    // started.
    StartDiscovery() -> (fuchsia.bluetooth.Status status);

    // Terminates discovery if one was started via StartDiscovery(). The AdapterDelegate will stop
    // receiving device discovery notifications.
    //
    // NOTE: If another client is performing discovery (e.g. via its own le.Central interface handle),
    // then the system will continue performing device discovery even if this method results in
    // success.
    StopDiscovery() -> (fuchsia.bluetooth.Status status);

    // Sets whether this host should be connectable.
    SetConnectable(bool enabled) -> (fuchsia.bluetooth.Status status);

    // Sets whether this host should be discoverable.
    SetDiscoverable(bool enabled) -> (fuchsia.bluetooth.Status status);

    // Enable or disable a passive LE background scan. When enabled, the bt-host
    // device will continuously perform a passive LE scan in the background when
    // no device discovery sessions are active and accept connection requests from
    // bonded peripherals.
    EnableBackgroundScan(bool enabled);

    // Assigns the pairing delegate that will respond to authentication challenges using the given
    // I/O capabilities. Setting a pairing delegate cancels any on-going pairing procedure started
    // using a previous delegate. Pairing requests will be rejected if no PairingDelegate has been
    // assigned.
    SetPairingDelegate(
        fuchsia.bluetooth.control.InputCapabilityType input,
        fuchsia.bluetooth.control.OutputCapabilityType output,
        fuchsia.bluetooth.control.PairingDelegate? delegate);

    // TODO(NET-1148): Add Forget() method to remove a device from the cache.

    // Adds existing bonded devices to the host. The host will be configured to automatically connect
    // to these devices when they are in range and connectable. Future connections will be encrypted
    // using the provided bonding data.
    AddBondedDevices(vector<BondingData> bonds) -> (fuchsia.bluetooth.Status status);

    // ===== Events =====

    // Notifies when the adapter state changes.
    -> OnAdapterStateChanged(fuchsia.bluetooth.control.AdapterState state);

    // Events that are sent when a connectable device is added, updated, or
    // removed as a result of connection and discovery procedures.
    -> OnDeviceUpdated(fuchsia.bluetooth.control.RemoteDevice device);
    -> OnDeviceRemoved(string identifier);

    // Notifies when bonding data for a device has been updated.
    -> OnNewBondingData(BondingData data);

    // TODO(NET-1148): Introduce a "OnBondRemoved()" event to notify when existing
    // keys become stale.
};
