// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// The <code>chrome.bluetoothLowEnergy</code> API is used to communicate with
// Bluetooth Smart (Low Energy) devices using the
// <a href="https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx">
// Generic Attribute Profile (GATT)</a>.
namespace bluetoothLowEnergy {
  // Values representing the possible properties of a characteristic.
  enum CharacteristicProperty {broadcast, read, writeWithoutResponse, write,
                               notify, indicate, authenticatedSignedWrites,
                               extendedProperties, reliableWrite,
                               writableAuxiliaries};

  // Represents a peripheral's Bluetooth GATT Service, a collection of
  // characteristics and relationships to other services that encapsulate
  // the behavior of part of a device.
  dictionary Service {
    // The UUID of the service, e.g. 0000180d-0000-1000-8000-00805f9b34fb.
    DOMString uuid;

    // Indicates whether the type of this service is primary or secondary.
    boolean isPrimary;

    // Indicates whether this service represents a local service hosted by the
    // application and available to other peripherals, or a remote service
    // hosted and received from a remote peripheral.
    [nodoc] boolean isLocal;

    // Returns the identifier assigned to this service. Use the instance ID to
    // distinguish between services from a peripheral with the same UUID and
    // to make function calls that take in a service identifier. Present, if
    // this instance represents a remote service.
    DOMString? instanceId;

    // The device address of the remote peripheral that the GATT service belongs
    // to. Present, if this instance represents a remote service.
    DOMString? deviceAddress;
  };

  // Represents a GATT characteristic, which is a basic data element that
  // provides further information about a peripheral's service.
  dictionary Characteristic {
    // The UUID of the characteristic, e.g.
    // 00002a37-0000-1000-8000-00805f9b34fb.
    DOMString uuid;

    // Indicates whether this characteristic represents a local characteristic
    // hosted by the application and available to other peripherals, or a remote
    // characteristic hosted and received from a remote peripheral.
    [nodoc] boolean isLocal;

    // The GATT service this characteristic belongs to.
    Service service;

    // The properties of this characteristic.
    CharacteristicProperty[] properties;

    // Returns the identifier assigned to this characteristic. Use the instance
    // ID to distinguish between characteristics from a peripheral with the same
    // UUID and to make function calls that take in a characteristic identifier.
    // Present, if this instance represents a remote characteristic.
    DOMString? instanceId;

    // The currently cached characteristic value. This value gets updated when
    // the value of the characteristic is read or updated via a notification
    // or indication.
    ArrayBuffer? value;
  };

  // Represents a GATT characteristic descriptor, which provides further
  // information about a characteristic's value.
  dictionary Descriptor {
    // The UUID of the characteristic descriptor, e.g.
    // 00002902-0000-1000-8000-00805f9b34fb.
    DOMString uuid;

    // Indicates whether this descriptor represents a local descriptor
    // hosted by the application and available to other peripherals, or a remote
    // descriptor hosted and received from a remote peripheral.
    [nodoc] boolean isLocal;

    // The GATT characteristic this descriptor belongs to.
    Characteristic characteristic;

    // Returns the identifier assigned to this descriptor. Use the instance ID
    // to distinguish between descriptors from a peripheral with the same UUID
    // and to make function calls that take in a descriptor identifier. Present,
    // if this instance represents a remote characteristic.
    DOMString? instanceId;

    // The currently cached descriptor value. This value gets updated when
    // the value of the descriptor is read.
    ArrayBuffer? value;
  };

  // The connection properties specified during a call to $(ref:connect).
  dictionary ConnectProperties {
    // Flag indicating whether a connection to the device is left open when the
    // event page of the application is unloaded (see <a
    // href="http://developer.chrome.com/apps/app_lifecycle.html">Manage App
    // Lifecycle</a>). The default value is <code>false.</code>
    boolean persistent;
  };

  // Optional characteristic notification session properties specified during a
  // call to $(ref:startCharacteristicNotifications).
  dictionary NotificationProperties {
    // Flag indicating whether the app should receive notifications when the
    // event page of the application is unloaded (see <a
    // href="http://developer.chrome.com/apps/app_lifecycle.html">Manage App
    // Lifecycle</a>). The default value is <code>false</code>.
    boolean persistent;
  };

  callback CharacteristicCallback = void(Characteristic result);
  callback CharacteristicsCallback = void(Characteristic[] result);
  callback DescriptorCallback = void(Descriptor result);
  callback DescriptorsCallback = void(Descriptor[] result);
  callback ResultCallback = void();
  callback ServiceCallback = void(Service result);
  callback ServicesCallback = void(Service[] result);

  // These functions all report failures via chrome.runtime.lastError.
  interface Functions {
    // Establishes a connection between the application and the device with the
    // given address. A device may be already connected and its GATT services
    // available without calling <code>connect</code>, however, an app that
    // wants to access GATT services of a device should call this function to
    // make sure that a connection to the device is maintained. If the device
    // is not connected, all GATT services of the device will be discovered
    // after a successful call to <code>connect</code>.
    // |deviceAddress| : The Bluetooth address of the remote device to which a
    // GATT connection should be opened.
    // |properties| : Connection properties (optional).
    // |callback| : Called when the connect request has completed.
    static void connect(DOMString deviceAddress,
                        optional ConnectProperties properties,
                        ResultCallback callback);

    // Closes the app's connection to the device with the given address. Note
    // that this will not always destroy the physical link itself, since there
    // may be other apps with open connections.
    // |deviceAddress| : The Bluetooth address of the remote device.
    // |callback| : Called when the disconnect request has completed.
    static void disconnect(DOMString deviceAddress,
                           optional ResultCallback callback);

    // Get the GATT service with the given instance ID.
    // |serviceId| : The instance ID of the requested GATT service.
    // |callback| : Called with the requested Service object.
    static void getService(DOMString serviceId, ServiceCallback callback);

    // Get all the GATT services that were discovered on the remote device with
    // the given device address.
    // |deviceAddress| : The Bluetooth address of the remote device whose GATT
    // services should be returned.
    // |callback| : Called with the list of requested Service objects.
    static void getServices(DOMString deviceAddress, ServicesCallback callback);

    // Get the GATT characteristic with the given instance ID that belongs to
    // the given GATT service, if the characteristic exists.
    // |characteristicId| : The instance ID of the requested GATT
    // characteristic.
    // |callback| : Called with the requested Characteristic object.
    static void getCharacteristic(DOMString characteristicId,
                                  CharacteristicCallback callback);

    // Get a list of all discovered GATT characteristics that belong to the
    // given service.
    // |serviceId| : The instance ID of the GATT service whose characteristics
    // should be returned.
    // |callback| : Called with the list of characteristics that belong to the
    // given service.
    static void getCharacteristics(DOMString serviceId,
                                   CharacteristicsCallback callback);

    // Get a list of GATT services that are included by the given service.
    // |serviceId| : The instance ID of the GATT service whose included
    // services should be returned.
    // |callback| : Called with the list of GATT services included from the
    // given service.
    static void getIncludedServices(DOMString serviceId,
                                    ServicesCallback callback);

    // Get the GATT characteristic descriptor with the given instance ID.
    // |descriptorId| : The instance ID of the requested GATT characteristic
    // descriptor.
    // |callback| : Called with the requested Descriptor object.
    static void getDescriptor(DOMString descriptorId,
                              DescriptorCallback callback);

    // Get a list of GATT characteristic descriptors that belong to the given
    // characteristic.
    // |characteristicId| : The instance ID of the GATT characteristic whose
    // descriptors should be returned.
    // |callback| : Called with the list of descriptors that belong to the given
    // characteristic.
    static void getDescriptors(DOMString characteristicId,
                               DescriptorsCallback callback);

    // Retrieve the value of a specified characteristic from a remote
    // peripheral.
    // |characteristicId| : The instance ID of the GATT characteristic whose
    // value should be read from the remote device.
    // |callback| : Called with the Characteristic object whose value was
    // requested. The <code>value</code> field of the returned Characteristic
    // object contains the result of the read request.
    static void readCharacteristicValue(DOMString characteristicId,
                                        CharacteristicCallback callback);

    // Write the value of a specified characteristic from a remote peripheral.
    // |characteristicId| : The instance ID of the GATT characteristic whose
    // value should be written to.
    // |value| : The value that should be sent to the remote characteristic as
    // part of the write request.
    // |callback| : Called when the write request has completed.
    static void writeCharacteristicValue(DOMString characteristicId,
                                         ArrayBuffer value,
                                         ResultCallback callback);

    // Enable value notifications/indications from the specified characteristic.
    // Once enabled, an application can listen to notifications using the
    // $(ref:onCharacteristicValueChanged) event.
    // |characteristicId| : The instance ID of the GATT characteristic that
    // notifications should be enabled on.
    // |properties| : Notification session properties (optional).
    // |callback| : Called when the request has completed.
    static void startCharacteristicNotifications(
        DOMString characteristicId,
        optional NotificationProperties properties,
        ResultCallback callback);

    // Disable value notifications/indications from the specified
    // characteristic. After a successful call, the application will stop
    // receiving notifications/indications from this characteristic.
    // |characteristicId| : The instance ID of the GATT characteristic on which
    // this app's notification session should be stopped.
    // |callback| : Called when the request has completed (optional).
    static void stopCharacteristicNotifications(
        DOMString characteristicId,
        optional ResultCallback callback);

    // Retrieve the value of a specified characteristic descriptor from a remote
    // peripheral.
    // |descriptorId| : The instance ID of the GATT characteristic descriptor
    // whose value should be read from the remote device.
    // |callback| : Called with the Descriptor object whose value was requested.
    // The <code>value</code> field of the returned Descriptor object contains
    // the result of the read request.
    static void readDescriptorValue(DOMString descriptorId,
                                    DescriptorCallback callback);

    // Write the value of a specified characteristic descriptor from a remote
    // peripheral.
    // |descriptorId| : The instance ID of the GATT characteristic descriptor
    // whose value should be written to.
    // |value| : The value that should be sent to the remote descriptor as part
    // of the write request.
    // |callback| : Called when the write request has completed.
    static void writeDescriptorValue(DOMString descriptorId,
                                     ArrayBuffer value,
                                     ResultCallback callback);
  };

  interface Events {
    // Fired whan a new GATT service has been discovered on a remote device.
    // |service| : The GATT service that was added.
    static void onServiceAdded(Service service);

    // Fired when the state of a remote GATT service changes. This involves any
    // characteristics and/or descriptors that get added or removed from the
    // service, as well as "ServiceChanged" notifications from the remote
    // device.
    // |service| : The GATT service whose state has changed.
    static void onServiceChanged(Service service);

    // Fired when a GATT service that was previously discovered on a remote
    // device has been removed.
    // |service| : The GATT service that was removed.
    static void onServiceRemoved(Service service);

    // Fired when the value of a remote GATT characteristic changes, either as
    // a result of a read request, or a value change notification/indication
    // This event will only be sent if the app has enabled notifications by
    // calling $(ref:startCharacteristicNotifications).
    // |characteristic| : The GATT characteristic whose value has changed.
    static void onCharacteristicValueChanged(Characteristic characteristic);

    // Fired when the value of a remote GATT characteristic descriptor changes,
    // usually as a result of a read request. This event exists
    // mostly for convenience and will always be sent after a successful
    // call to $(ref:readDescriptorValue).
    // |descriptor| : The GATT characteristic descriptor whose value has
    // changed.
    static void onDescriptorValueChanged(Descriptor descriptor);
  };
};
