// Copyright 2021 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.gatt2;

using fuchsia.bluetooth as bt;

/// Wrapper around a possible truncated value received from the server.
type ReadValue = table {
    /// Characteristic or descriptor handle. Always present.
    1: handle Handle;
    /// The value of the characteristic or descriptor. Always present.
    2: value vector<uint8>:MAX_VALUE_LENGTH;
    /// True if `value` might be truncated (the buffer was completely filled
    /// by the server). `ReadCharacteristic` or `ReadDescriptor` should be used
    /// to read the complete value.
    /// Always present.
    3: maybe_truncated bool;
};

/// A result returned by `RemoteService.ReadByType`.
type ReadByTypeResult = table {
    /// Characteristic or descriptor handle.
    1: handle Handle;
    /// The value of the characteristic or descriptor, if it was read successfully.
    2: value ReadValue;
    /// Reason the value could not be read, if reading it resulted in an error.
    3: error Error;
};

/// Listens to characteristic notifications & indications.
closed protocol CharacteristicNotifier {
    /// Called when a characteristic value notification or indication is
    /// received from the server.
    ///
    /// + request `value` the value of the updated characteristic.
    /// - response An empty response should be sent immediately as an
    ///   acknowledgement that the notification was received (for flow control).
    strict OnNotification(struct {
        value ReadValue;
    }) -> ();
};

closed protocol RemoteService {
    /// Returns the characteristics and characteristic descriptors that belong to
    /// this service.
    strict DiscoverCharacteristics() -> (struct {
        characteristics vector<Characteristic>:MAX_CHARACTERISTIC_COUNT;
    });

    /// Reads characteristics and descriptors with the given `uuid`.
    ///
    /// This method is useful for reading values before discovery has completed,
    /// thereby reducing latency.
    ///
    /// + request `uuid` The UUID of the characteristics/descriptors to read.
    /// - response `results` The results of the read. May be empty if no
    ///            matching values are read. If reading a value results in a
    ///            permission error, the handle and error will be included.
    /// * error Returns `INVALID_PARAMETERS` if `uuid` refers to an internally
    ///         reserved descriptor type (e.g. the Client Characteristic
    ///         Configuration descriptor).
    /// * error Returns `TOO_MANY_RESULTS` if more results were read than can fit
    ///         in a FIDL response. Consider reading characteristics/descriptors
    ///         individually after performing discovery.
    /// * error Returns `FAILURE` if the server returns an error not specific to
    ///         a single result.
    strict ReadByType(struct {
        uuid bt.Uuid;
    }) -> (struct {
        results vector<ReadByTypeResult>:MAX_ATTRIBUTE_COUNT;
    }) error Error;

    /// Reads the value of a characteristic with the given `handle`.
    ///
    /// + request `handle` The characteristic handle to read.
    /// + request `options` Options that apply to the read.
    /// - response `value` The value of the characteristic.
    /// * error Returns `INVALID_HANDLE` if `handle` is invalid.
    /// * error Returns `INVALID_PARAMETERS` if `options` is invalid.
    /// * error Returns `READ_NOT_PERMITTED` or `INSUFFICIENT_*` if the server
    ///         rejects the read request.
    /// * error Returns `FAILURE` if the server returns an error.
    strict ReadCharacteristic(struct {
        handle Handle;
        options ReadOptions;
    }) -> (struct {
        value ReadValue;
    }) error Error;

    /// Writes `value` to the characteristic with `handle` using the provided
    /// `options`.
    ///
    /// It is not recommended to send additional writes while a write is already
    /// in progress (the server may receive simultaneous writes in any order).
    ///
    /// + request `handle` The characteristic to be written to.
    /// + request `value` The value to be written.
    /// + request `options` Options that apply to the write.
    /// - response An empty response will be sent when a success response is
    ///            received from the server (or immediately if
    ///            `options.with_response` is false)
    /// * error Returns `INVALID_HANDLE` if `handle` is invalid.
    /// * error Returns `INVALID_PARAMETERS` if `options` is invalid.
    /// * error Returns `WRITE_NOT_PERMITTED` or `INSUFFICIENT_*`if the server
    ///         rejects the write request with a reason.
    /// * error Returns `FAILURE` if the server returns an error.
    strict WriteCharacteristic(struct {
        handle Handle;
        value vector<uint8>:MAX_VALUE_LENGTH;
        options WriteOptions;
    }) -> () error Error;

    /// Reads the value of the characteristic descriptor with `handle` and
    /// returns it in the reply.
    ///
    /// + request `handle` The descriptor handle to read.
    /// + request `options` Options that apply to the read.
    /// - response `value` The value of the descriptor.
    /// * error Returns `INVALID_HANDLE` if `handle` is invalid.
    /// * error Returns `INVALID_PARAMETERS` if `options` is invalid.
    /// * error Returns `READ_NOT_PERMITTED` or `INSUFFICIENT_*` if the server
    ///         rejects the read request.
    /// * error Returns `FAILURE` if the server returns an error.
    strict ReadDescriptor(struct {
        handle Handle;
        options ReadOptions;
    }) -> (struct {
        value ReadValue;
    }) error Error;

    /// Writes `value` to the characteristic descriptor with `handle`.
    /// It is not recommended to send additional writes while a write is already
    /// in progress (the server may receive simultaneous writes in any order).
    ///
    /// + request `handle` The descriptor handle to written to.
    /// + request `value` The value to be written.
    /// + request `options` Options that apply to the write.
    /// - response An empty response will be sent when a success response is
    ///            received from the server (or immediately if
    ///            `options.with_response` is false)
    /// * error Returns `INVALID_HANDLE` if `handle` is invalid or refers to an
    ///         internally reserved descriptor type (e.g. the Client
    ///         Characteristic Configuration descriptor).
    /// * error Returns `INVALID_PARAMETERS` if `options` is invalid.
    /// * error Returns `WRITE_NOT_PERMITTED` or `INSUFFICIENT_*` if the server
    ///         rejects the write with a reason.
    /// * error Returns `FAILURE` if the server returns an error.
    strict WriteDescriptor(struct {
        handle Handle;
        value vector<uint8>:MAX_VALUE_LENGTH;
        options WriteOptions;
    }) -> () error Error;

    /// Subscribe to notifications & indications from the characteristic with
    /// the given `handle`.
    ///
    /// Either notifications or indications will be enabled depending on
    /// characteristic properties. Indications will be preferred if they are
    /// supported. This operation fails if the characteristic does not have the
    /// "notify" or "indicate" property.
    ///
    /// A write request will be issued to configure the characteristic for
    /// notifications/indications if it contains a Client Characteristic
    /// Configuration descriptor. This method fails if an error occurs while
    /// writing to the descriptor.
    ///
    /// On success, the `notifier` protocol can be used to be notified when
    /// the peer sends a notification or indication. Indications are
    /// automatically confirmed. When the protocol is dropped, the subscription
    /// may end if no other local client is receiving notifications.
    ///
    /// + request `handle` the characteristic handle.
    /// + request `notifier` the protocol used for notifications.
    /// - response An empty response will be sent immediately if registration
    ///            succeeds.
    /// * error Returns a `FAILURE` if the characteristic does not support
    ///         notifications or indications.
    /// * error Returns a `INVALID_HANDLE` if `handle` is invalid.
    /// * error Returns a `WRITE_NOT_PERMITTED`  or `INSUFFICIENT_*`for a
    ///         descriptor write error.
    strict RegisterCharacteristicNotifier(resource struct {
        handle Handle;
        notifier client_end:CharacteristicNotifier;
    }) -> () error Error;
};

closed protocol Client {
    /// Enumerates services found on the peer that this Client represents.
    ///
    /// Results can be filtered by specifying a list of UUIDs in `uuids`. This
    /// method follows the hanging get pattern. On the initial request, a
    /// complete snapshot will be returned. Subsequent calls with the same set
    /// of `uuids` receive a response only when one or more services have been
    /// added, modified, or removed from the entries reported since the most
    /// recent call. Calls with new values of `uuids` will reset the filter and
    /// receive a complete snapshot.
    ///
    /// Handles may be reused across services, so a handle may be in both
    /// `updated` and `removed`. For this reason, it is recommended to process
    /// removed services before updated services.
    ///
    /// To further interact with services, clients must obtain a RemoteService
    /// protocol by calling ConnectToService().
    ///
    /// + request `uuids` the UUID allowlist. If empty, all services will be
    ///   returned.
    /// - response `updated` the services that have been added or modified since
    ///   WatchServices() was last called. The returned ServiceInfo tables will
    ///   contain only basic information about each service and the
    ///   `characteristics` and `includes` fields will be null. If a service has
    ///   been added/modified and then removed since the last call, it will only
    ///   be present in `removed`, not `updated`.
    ///   If concluded due to a new call with a new `uuids` value, `updated`
    ///   will be empty.
    /// - response `removed` the handles of the services that have been removed
    ///   since the last call to WatchServices().
    strict WatchServices(struct {
        uuids vector<bt.Uuid>:MAX;
    }) -> (struct {
        updated vector<ServiceInfo>:MAX_SERVICE_COUNT;
        removed vector<Handle>:MAX_SERVICE_COUNT;
    });

    /// Connects the RemoteService with the given identifier. Only 1 connection
    /// per service is allowed.
    ///
    /// `service` will be closed on error, with an epitaph that provides a
    /// reason.
    /// * error Returns a `ZX_ERR_INVALID_ARGS` if `handle` is invalid.
    /// * error Returns a `ZX_ERR_NOT_FOUND` if the service is not found.
    /// * error Returns a `ZX_ERR_CONNECTION_RESET` if the service is removed.
    /// * error Returns a `ZX_ERR_NOT_CONNECTED` if the peer disconnects.
    /// * error Returns a `ZX_ERR_ALREADY_EXISTS` if the service is already connected.
    strict ConnectToService(resource struct {
        handle ServiceHandle;
        service server_end:RemoteService;
    });
};
