// 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 vector<uint8>:MAX_READ_BY_TYPE_VALUE_LENGTH;
    /// Reason the value could not be read, if reading it resulted in an error.
    3: error Error;
};

closed protocol RemoteService {
    /// Returns the characteristics and characteristic descriptors that belong to
    /// this service.
    strict 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.
    strict ReadCharacteristic(struct {
        id uint64;
    }) -> (struct {
        status bt.Status;
        value vector<uint8>:MAX;
    });

    /// 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.
    strict ReadLongCharacteristic(struct {
        id uint64;
        offset uint16;
        max_bytes uint16;
    }) -> (struct {
        status bt.Status;
        value vector<uint8>: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.
    strict WriteCharacteristic(struct {
        id uint64;
        value vector<uint8>:MAX;
    }) -> (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.
    strict WriteLongCharacteristic(struct {
        id uint64;
        offset uint16;
        value vector<uint8>: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.
    strict WriteCharacteristicWithoutResponse(struct {
        id uint64;
        value vector<uint8>:MAX;
    });

    /// 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.
    strict ReadDescriptor(struct {
        id uint64;
    }) -> (struct {
        status bt.Status;
        value vector<uint8>:MAX;
    });

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

    /// 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).
    strict WriteDescriptor(struct {
        id uint64;
        value vector<uint8>:MAX;
    }) -> (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.
    strict WriteLongDescriptor(struct {
        id uint64;
        offset uint16;
        value vector<uint8>: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.
    strict 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.
    strict NotifyCharacteristic(struct {
        id uint64;
        enable bool;
    }) -> (struct {
        status bt.Status;
    });

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

closed 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().
    strict 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.
    strict ConnectToService(resource struct {
        id uint64;
        service server_end:RemoteService;
    });
};
