// Copyright 2017 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.gatt;

using fuchsia.bluetooth;

/// Interface for responding to requests on a local service.
protocol LocalServiceDelegate {
    /// Notifies the delegate when a remote device with `peer_id` enables or
    /// disables notifications or indications on the characteristic with the given
    /// `characteristic_id`.
    OnCharacteristicConfiguration(uint64 characteristic_id, string peer_id,
                                  bool notify, bool indicate);

    /// Called when a remote device issues a request to read the value of the
    /// of the characteristic or descriptor with given identifier. The delegate
    /// must respond to the request by returning the characteristic value. If the
    /// read request resulted in an error it should be returned in `error_code`.
    /// On success, `error_code` should be set to NO_ERROR and a `value` should be
    /// provided.
    OnReadValue(uint64 id, int32 offset) -> (bytes? value, ErrorCode status);

    /// Called when a remote device issues a request to write the value of the
    /// characteristic or descriptor with the given identifier.
    OnWriteValue(uint64 id, uint16 offset, bytes value) -> (ErrorCode status);

    /// Called when a remote device issues a request to write the value of the
    /// characteristic with the given identifier. This can be called on a
    /// characteristic with the WRITE_WITHOUT_RESPONSE property.
    OnWriteWithoutResponse(uint64 id, uint16 offset, bytes value);
};

/// Interface for communicating with a published service.
protocol LocalService {
    /// Removes the service that this interface instance corresponds to. Does
    /// nothing if the service is already removed.
    RemoveService();

    /// Sends a notification carrying the `value` of the characteristic with the
    /// given `characteristic_id` to the device with `peer_id`.
    ///
    /// If `confirm` is true, then this method sends an indication instead. If the
    /// peer fails to confirm the indication, the link between the peer and the
    /// local adapter will be closed.
    ///
    /// This method has no effect if the peer has not enabled notifications or
    /// indications on the requested characteristic.
    NotifyValue(uint64 characteristic_id, string peer_id, bytes value, bool confirm);
};

[Discoverable]
protocol Server {
    /// Publishes the given service so that it is available to all remote peers.
    /// A LocalServiceDelegate must be provided over which to receive service requests.
    ///
    /// The caller must assign distinct identifiers to the characteristics and
    /// descriptors listed in `info`. These identifiers will be used in requests
    /// sent to `delegate`.
    ///
    /// `service` can be used to interact with the pubished service. If this
    /// service cannot be published then the handle for `service` will be closed.
    ///
    /// Returns the success or failure status of the call and a unique identifier
    /// that can be used to unregister the service.
    PublishService(ServiceInfo info, LocalServiceDelegate delegate, request<LocalService> service) -> (fuchsia.bluetooth.Status status);
};
