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

using fuchsia.bluetooth;
using fuchsia.bluetooth.gatt;

[Discoverable]
protocol Central {
    /// Returns the list of peripherals that are known to the system from previous scan, connection,
    /// and/or bonding procedures. The results can be filtered based on service UUIDs that are known to
    /// be present on the peripheral.
    ///
    /// This method only returns peripherals (i.e. connectable devices).
    GetPeripherals(vector<string>? service_uuids) -> (vector<RemoteDevice> peripherals);

    /// Returns information about a single peripheral that is known to the system from previous scan,
    /// connection, and/or bonding procedures based on its unique identifier. Returns null if
    /// `identifier` is not recognized.
    GetPeripheral(string identifier) -> (RemoteDevice? peripheral);

    /// Initiates a scan session for nearby peripherals and broadcasters. Discovered devices will be
    /// reported via CentralDelegate.OnDeviceDiscovered(). If a scan session is already in progress,
    /// `filter` will replace the existing session's filter.
    ///
    /// If `filter` is null or empty (i.e. none of its fields has been populated) then the delegate
    /// will be notified for all discoverable devices that are found. This is not recommended; clients
    /// should generally filter results by at least one of `filter.service_uuids`,
    /// `filter.service_data`, and/or `filter.manufacturer_identifier`.
    StartScan(ScanFilter? filter) -> (fuchsia.bluetooth.Status status);

    /// Terminate a previously started scan session.
    StopScan();

    /// Creates a connection to the peripheral device with the given identifier.
    /// Returns the status of the operation in `status`.
    ///
    /// On success, `gatt_client` will be bound and can be used for GATT client
    /// role procedures. On failure, `gatt_client` will be closed and `status` will
    /// indicate an error.
    ConnectPeripheral(string identifier, ConnectionOptions options,
                      request<fuchsia.bluetooth.gatt.Client> gatt_client)
        -> (fuchsia.bluetooth.Status status);

    /// Disconnects this Central's connection to the peripheral with the given identifier.
    DisconnectPeripheral(string identifier) -> (fuchsia.bluetooth.Status status);

    /// Called when the scan state changes, e.g. when a scan session terminates due to a call to
    /// Central.StopScan() or another unexpected condition.
    -> OnScanStateChanged(bool scanning);

    /// Called for each peripheral/broadcaster that is discovered during a scan session. `rssi`
    /// contains the received signal strength of the advertising packet that generated this event, if
    /// available.
    -> OnDeviceDiscovered(RemoteDevice device);

    /// Called when this Central's connection to a peripheral with the given identifier is terminated.
    -> OnPeripheralDisconnected(string identifier);
};
