// 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.
interface 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) -> (vector<uint8>? 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, vector<uint8> 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, vector<uint8> value);
};

// Interface for communicating with a published service.
interface 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, vector<uint8> value, bool confirm);
};

[Discoverable]
interface 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);
};
