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

    /// Called when a remote device issues a request to write the value of the
    /// characteristic or descriptor with the given identifier.
    OnWriteValue(struct {
        id uint64;
        offset uint16;
        value bytes;
    }) -> (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.
    OnWriteWithoutResponse(struct {
        id uint64;
        offset uint16;
        value bytes;
    });
};

/// 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(struct {
        characteristic_id uint64;
        peer_id bt.PeerIdString;
        value bytes;
        confirm bool;
    });
};

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