// 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);

    // Establish a BR/EDR and/or LE connection to the remote device with identifier |device_id|:
    //
    //   - If the device is known to support the BR/EDR transport then a logical link over that 
    //     transport will be established to the device. If the connection attempt is successful,
    //     local services registered using "RequestProfile()" will be available to the peer.
    //     Traditional services discovered on the peer will be notified to local services
    //     asynchronously.
    //
    //   - If the device is known to support the LE transport then a logical link over that
    //     transport will be established to the device. If the connection attempt is successful,
    //     GATT services in the local database (populated via RequestGattServer()) will become
    //     available to the peer. Similarly, remote GATT services that are discovered on the
    //     peer will become available to holders of a gatt.Client capability and to device drivers
    //     that can bind to the bt-gatt-svc class of devices.
    //
    // The result of the procedure will be communicated via |status|. If the remote device
    // supports both BR/EDR and LE transports and a link cannot be established over both, then an
    // error Status will be returned and neither transport will be connected.
    Connect(string device_id) -> (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.
};
