// 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 as bt;

/// Interface for responding to requests on a local service.
closed 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`.
    strict OnCharacteristicConfiguration(struct {
        characteristic_id uint64;
        peer_id bt.PeerIdString;
        notify bool;
        indicate bool;
    });

    /// 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.
    strict OnReadValue(struct {
        id uint64;
        offset int32;
    }) -> (struct {
        value vector<uint8>:<MAX, optional>;
        status ErrorCode;
    });

    /// Called when a remote device issues a request to write the value of the
    /// characteristic or descriptor with the given identifier.
    strict OnWriteValue(struct {
        id uint64;
        offset uint16;
        value vector<uint8>:MAX;
    }) -> (struct {
        status ErrorCode;
    });

    /// 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.
    strict OnWriteWithoutResponse(struct {
        id uint64;
        offset uint16;
        value vector<uint8>:MAX;
    });
};

/// Interface for communicating with a published service.
closed protocol LocalService {
    /// Removes the service that this interface instance corresponds to. Does
    /// nothing if the service is already removed.
    strict 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.
    strict NotifyValue(struct {
        characteristic_id uint64;
        peer_id bt.PeerIdString;
        value vector<uint8>:MAX;
        confirm bool;
    });
};

@discoverable
closed 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.
    strict PublishService(resource struct {
        info ServiceInfo;
        delegate client_end:LocalServiceDelegate;
        service server_end:LocalService;
    }) -> (struct {
        status bt.Status;
    });
};
