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

type ReadByTypeResult = table {
    /// Characteristic or descriptor id.
    1: id uint64;
    /// Truncated value of characteristic or descriptor, if it was read successfully.
    2: value bytes:MAX_READ_BY_TYPE_VALUE_LENGTH;
    /// Reason the value could not be read, if reading it resulted in an error.
    3: error Error;
};

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

    /// Reads the value of the characteristic with `id` and returns it in the
    /// reply. If `status` indicates an error `value` will be empty.
    ///
    /// If the characteristic has a long value (i.e. larger than the current MTU)
    /// this method will return only the first (MTU - 1) bytes of the value. Use
    /// ReadLongCharacteristic() to read larger values or starting at a non-zero
    /// offset.
    ReadCharacteristic(struct {
        id uint64;
    }) -> (struct {
        status bt.Status;
        value bytes;
    });

    /// Reads the complete value of a characteristic with the given `id`. This
    /// procedure should be used if the characteristic is known to have a value
    /// that can not be read in a single request.
    ///
    /// Returns up to `max_bytes` octets of the characteristic value starting at
    /// the given `offset`.
    ///
    /// This may return an error if:
    ///   a. `max_bytes` is 0;
    ///   b. The `offset` is invalid;
    ///   c. The characteristic does not have a long value;
    ///   d. The server does not support the long read procedure.
    ReadLongCharacteristic(struct {
        id uint64;
        offset uint16;
        max_bytes uint16;
    }) -> (struct {
        status bt.Status;
        value bytes:MAX_VALUE_LENGTH;
    });

    /// Writes `value` to the characteristic with `id`. This operation may return
    /// an error if:
    ///   a. The size of `value` exceeds the current MTU.
    ///   b. The characteristic referred to by `id` does not have the 'write'
    ///      property.
    WriteCharacteristic(struct {
        id uint64;
        value bytes;
    }) -> (struct {
        status bt.Status;
    });

    /// Writes `value` to the characteristic with `id`, beginning at `offset` using
    /// the provided `write_options`.
    ///
    /// This procedure should be used if the value to be written is too long to
    /// fit in a single request or needs to be written at an offset. This may
    /// return an error if:
    ///   a. The `offset` is invalid;
    ///   b. The server does not support the long write procedure.
    ///
    /// Long Writes require multiple messages to the remote service and take longer
    /// to execute than Short Writes. It is not recommended to send a short write
    /// while a long write is in process to the same id and data range. The order
    /// of the responses from this function signify the order in which the remote
    /// service received them, not necessarily the order in which it is called.
    WriteLongCharacteristic(struct {
        id uint64;
        offset uint16;
        value bytes:MAX_VALUE_LENGTH;
        write_options WriteOptions;
    }) -> (struct {
        status bt.Status;
    });

    /// Writes `value` to the characteristic with `id` without soliciting an
    /// acknowledgement from the peer. This method has no response and its delivery
    /// cannot be confirmed.
    WriteCharacteristicWithoutResponse(struct {
        id uint64;
        value bytes;
    });

    /// Reads the value of the characteristic descriptor with `id` and returns it
    /// in the reply. If `status` indicates an error, `value` can be ignored.
    ///
    /// If the descriptor has a long value (i.e. larger than the current MTU)
    /// this method will return only the first (MTU - 1) bytes of the value. Use
    /// ReadLongDescriptor() to read larger values or starting at a non-zero
    /// offset.
    ReadDescriptor(struct {
        id uint64;
    }) -> (struct {
        status bt.Status;
        value bytes;
    });

    /// Reads the complete value of a characteristic descriptor with the given `id`.
    /// This procedure should be used if the descriptor is known to have a value
    /// that can not be read in a single request.
    ///
    /// Returns up to `max_bytes` octets of the characteristic value starting at
    /// the given `offset`.
    ///
    /// This may return an error if:
    ///   a. `max_bytes` is 0;
    ///   b. The `offset` is invalid;
    ///   c. The server does not support the long read procedure.
    ReadLongDescriptor(struct {
        id uint64;
        offset uint16;
        max_bytes uint16;
    }) -> (struct {
        status bt.Status;
        value bytes;
    });

    /// Writes `value` to the characteristic descriptor with `id`. This operation
    /// may return an error if:
    ///   a. The size of `value` exceeds the current MTU.
    ///   b. `id` refers to an internally reserved descriptor type (e.g. the Client
    ///      Characteristic Configuration descriptor).
    WriteDescriptor(struct {
        id uint64;
        value bytes;
    }) -> (struct {
        status bt.Status;
    });

    /// Writes `value` to the characteristic descriptor with `id`, beginning at
    /// `offset`. This procedure should be used if the value to be written is too
    /// long to fit in a single request or needs to be written at an offset. This
    /// may return an error if:
    ///   a. The `offset` is invalid;
    ///   b. The server does not support the long write procedure.
    ///   c. `id` refers to an internally reserved descriptor type (e.g. the Client
    ///      Characteristic Configuration descriptor).
    ///
    /// Long Writes require multiple messages to the remote service and take longer
    /// to execute than Short Writes. It is not recommended to send a short write
    /// while a long write is in process to the same id and data range. The order
    /// of the responses from this function signify the order in which the remote
    /// service received them, not necessarily the order in which it is called.
    WriteLongDescriptor(struct {
        id uint64;
        offset uint16;
        value bytes:MAX_VALUE_LENGTH;
    }) -> (struct {
        status bt.Status;
    });

    /// Reads characteristics and descriptors with the given `uuid`. If no values are
    /// read, `results` will be empty. If reading a value results in a permission error,
    /// the handle and error will be included in `results`.
    ///
    /// NOTE: Values in `results` will be truncated to `MAX_READ_BY_TYPE_VALUE_LENGTH`
    /// bytes. `ReadCharacteristic`, `ReadLongCharacteristic()`, `ReadDescriptor`, or
    /// `ReadLongDescriptor()` should be used to read the complete values.
    ///
    /// This method is useful for reading values before discovery has completed, thereby
    /// reducing latency.
    ReadByType(struct {
        uuid bt.Uuid;
    }) -> (struct {
        results vector<ReadByTypeResult>:MAX_READ_BY_TYPE_RESULTS;
    }) error Error;

    /// Subscribe or unsubscribe to notifications/indications from the characteristic with
    /// the given `id`. Notifications or indications will be enabled if `enable` is
    /// true or disabled if `enable` is false and they have been enabled for this
    /// client.
    ///
    /// 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 OnCharacteristicValueUpdated event will be sent whenever
    /// the peer sends a notification or indication. The local host will
    /// automically confirm indications.
    NotifyCharacteristic(struct {
        id uint64;
        enable bool;
    }) -> (struct {
        status bt.Status;
    });

    /// Events:
    /// Called when a characteristic value notification or indication is received.
    -> OnCharacteristicValueUpdated(struct {
        id uint64;
        value bytes;
    });
};

protocol Client {
    /// Enumerates services found on the peer that this Client represents. Results
    /// can be restricted by specifying a list of UUIDs in `uuids`. The returned
    /// ServiceInfo structures will contain only basic information about each
    /// service and the `characteristics` and `includes` fields will be null.
    ///
    /// To further interact with services, clients must obtain a RemoteService
    /// handle by calling ConnectToService().
    ListServices(struct {
        uuids vector<bt.UuidString>:<MAX, optional>;
    }) -> (struct {
        status bt.Status;
        services vector<ServiceInfo>:MAX_SERVICE_COUNT;
    });

    /// Connects the RemoteService with the given identifier.
    ConnectToService(resource struct {
        id uint64;
        service server_end:RemoteService;
    });
};
