// 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.
  // Characteristic permissions are inferred from these properties.
  // Please see the Bluetooth 4.x spec to see the meaning of each individual
  // property.
  enum CharacteristicProperty {
      broadcast, read, writeWithoutResponse, write, notify, indicate,
      authenticatedSignedWrites, extendedProperties, reliableWrite,
      writableAuxiliaries, encryptRead, encryptWrite, encryptAuthenticatedRead,
      encryptAuthenticatedWrite
  };

  // Values representing possible permissions for a descriptor.
  // Please see the Bluetooth 4.x spec to see the meaning of each individual
  // permission.
  enum DescriptorPermission {
      read, write, encryptedRead, encryptedWrite, encryptedAuthenticatedRead,
      encryptedAuthenticatedWrite
  };

  // Type of advertisement. If 'broadcast' is chosen, the sent advertisement
  // type will be ADV_NONCONN_IND and the device will broadcast with a random
  // MAC Address. If set to 'peripheral', the advertisement type will be
  // ADV_IND or ADV_SCAN_IND and the device will broadcast with real Bluetooth
  // Adapter's MAC Address.
  enum AdvertisementType {broadcast, peripheral};

  // Represents a bluetooth central device that is connected to the local GATT
  // server.
  dictionary Device {
    // The address of the device, in the format 'XX:XX:XX:XX:XX:XX'.
    DOMString address;

    // The human-readable name of the device.
    DOMString? name;

    // The class of the device, a bit-field defined by
    // http://www.bluetooth.org/en-us/specification/assigned-numbers/baseband.
    long? deviceClass;
  };

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

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

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

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

    // The permissions of this descriptor.
    DescriptorPermission[] permissions;

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

  // Represents an entry of the "Manufacturer Specific Data" field of Bluetooth
  // LE advertisement data.
  dictionary ManufacturerData {
    long id;
    long[] data;
  };

  // Represents an entry of the "Service Data" field of Bluetooth LE advertisement
  // data.
  dictionary ServiceData {
    DOMString uuid;
    long[] data;
  };

  // Represents a Bluetooth LE advertisement instance.
  dictionary Advertisement {
    // Type of advertisement.
    AdvertisementType type;

    // List of UUIDs to include in the "Service UUIDs" field of the Advertising
    // Data. These UUIDs can be of the 16bit, 32bit or 128 formats.
    DOMString[]? serviceUuids;

    // List of manufacturer specific data to be included in "Manufacturer Specific
    // Data" fields of the advertising data.
    ManufacturerData[]? manufacturerData;

    // List of UUIDs to include in the "Solicit UUIDs" field of the Advertising
    // Data. These UUIDs can be of the 16bit, 32bit or 128 formats.
    DOMString[]? solicitUuids;

    // List of service data to be included in "Service Data" fields of the advertising
    // data.
    ServiceData[]? serviceData;
  };

  // Represents a an attribute read/write request.
  dictionary Request {
    // Unique ID for this request. Use this ID when responding to this request.
    long requestId;
    // Device that send this request.
    Device device;
    // Value to write (if this is a write request).
    ArrayBuffer? value;
  };

  // Represents a response to an attribute read/write request.
  dictionary Response {
    // Id of the request this is a response to.
    long requestId;
    // If this is an error response, this should be true.
    boolean isError;
    // Response value. Write requests and error responses will ignore this
    // parameter.
    ArrayBuffer? value;
  };

  // Represents a notification to be sent to a remote device.
  dictionary Notification {
    // New value of the characteristic.
    ArrayBuffer value;
    // Optional flag for sending an indication instead of a notification.
    boolean? shouldIndicate;
  };

  callback CharacteristicCallback = void(Characteristic result);
  callback CreateCharacteristicCallback = void(DOMString characteristicId);
  callback CharacteristicsCallback = void(Characteristic[] result);
  callback DescriptorCallback = void(Descriptor result);
  callback CreateDescriptorCallback = void(DOMString descriptorId);
  callback DescriptorsCallback = void(Descriptor[] result);
  callback ResultCallback = void();
  callback ServiceCallback = void(Service result);
  callback CreateServiceCallback = void(DOMString serviceId);
  callback ServicesCallback = void(Service[] result);
  callback RegisterAdvertisementCallback = void (long advertisementId);

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

    // Create a locally hosted GATT service. This service can be registered
    // to be available on a local GATT server.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |service|: The service to create.
    // |callback|: Called with the created services's unique ID.
    static void createService(Service service, CreateServiceCallback 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);

    // Create a locally hosted GATT characteristic. This characteristic must
    // be hosted under a valid service. If the service ID is not valid, the
    // lastError will be set.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |characteristic|: The characteristic to create.
    // |serviceId|: ID of the service to create this characteristic for.
    // |callback|: Called with the created characteristic's unique ID.
    static void createCharacteristic(Characteristic characteristic,
                                     DOMString serviceId,
                                     CreateCharacteristicCallback 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);

    // Create a locally hosted GATT descriptor. This descriptor must
    // be hosted under a valid characteristic. If the characteristic ID is not
    // valid, the lastError will be set.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |descriptor|: The descriptor to create.
    // |characteristicId|: ID of the characteristic to create this descriptor
    // for.
    // |callback|: Called with the created descriptor's unique ID.
    static void createDescriptor(Descriptor descriptor,
                                 DOMString characteristicId,
                                 CreateDescriptorCallback 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);

    // Notify a remote device of a new value for a characteristic. If the
    // shouldIndicate flag in the notification object is true, an indication
    // will be sent instead of a notification. Note, the characteristic needs
    // to correctly set the 'notify' or 'indicate' property during creation for
    // this call to succeed.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |characteristicId|: The characteristic to send the notication for.
    // |notifcation|: The notification to send.
    // |callback|: Callback called once the notification or indication has
    // been sent successfully.
    static void notifyCharacteristicValueChanged(DOMString characteristicId,
                                                 Notification notification,
                                                 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);

    // Register the given service with the local GATT server. If the service
    // ID is invalid, the lastError will be set.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |serviceId|: Unique ID of a created service.
    // |callback|: Callback with the result of the register operation.
    static void registerService(
        DOMString serviceId, ResultCallback callback);

    // Unregister the given service with the local GATT server. If the service
    // ID is invalid, the lastError will be set.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |serviceId|: Unique ID of a current registered service.
    // |callback|: Callback with the result of the register operation.
    static void unregisterService(
        DOMString serviceId, ResultCallback callback);

    // Remove the specified service, unregistering it if it was registered.
    // If the service ID is invalid, the lastError will be set.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |serviceId|: Unique ID of a current registered service.
    // |callback|: Callback called once the service is removed.
    static void removeService(
        DOMString serviceId, optional ResultCallback callback);

    // Create an advertisement and register it for advertising. To call this
    // function, the app must have the bluetooth:low_energy and
    // bluetooth:peripheral permissions set to true. Additionally this API
    // is only available to auto launched apps in Kiosk Mode of by setting
    // the 'enable-ble-advertising-in-apps' flag.
    // See https://developer.chrome.com/apps/manifest/bluetooth
    // Note: On some hardware, central and peripheral modes at the same time is
    // supported but on hardware that doesn't support this, making this call
    // will switch the device to peripheral mode. In the case of hardware which
    // does not support both central and peripheral mode, attempting to use the
    // device in both modes will lead to undefined behavior or prevent other
    // central-role applications from behaving correctly (including the
    // discovery of Bluetooth Low Energy devices).
    // |advertisement|: The advertisement to advertise.
    // |callback|: Called once the registeration is done and we've started
    // advertising. Returns the id of the created advertisement.
    static void registerAdvertisement(
        Advertisement advertisement, RegisterAdvertisementCallback callback);

    // Unregisters an advertisement and stops its advertising. If the
    // advertisement fails to unregister the only way to stop advertising
    // might be to restart the device.
    // |advertisementId|: Id of the advertisement to unregister.
    // |callback|: Called once the advertisement is unregistered and is no
    // longer being advertised.
    static void unregisterAdvertisement(long advertisementId,
        ResultCallback callback);

    // Set's the interval betweeen two consecutive advertisements. Note:
    // This is a best effort. The actual interval may vary non-trivially
    // from the requested intervals. On some hardware, there is a minimum
    // interval of 100ms. The minimum and maximum values cannot exceed the
    // the range allowed by the Bluetooth 4.2 specification.
    // |minInterval|: Minimum interval between advertisments (in
    // milliseconds). This cannot be lower than 20ms (as per the spec).
    // |maxInterval|: Maximum interval between advertisments (in
    // milliseconds). This cannot be more than 10240ms (as per the spec).
    // |callback|: Called once the interval has been set.
    static void setAdvertisingInterval(long minInterval, long maxInterval,
        ResultCallback callback);

    // Sends a response for a characteristic or descriptor read/write
    // request.
    // This function is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |response|: The response to the request.
    static void sendRequestResponse(Response response);
  };

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

    // Fired when a connected central device requests to read the value of a
    // characteristic registered on the local GATT server. Not responding
    // to this request for a long time may lead to a disconnection.
    // This event is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |request|: Request data for this request.
    // |characteristic|: The GATT characteristic whose value is requested.
    static void onCharacteristicReadRequest(
        Request request, DOMString characteristicId);

    // Fired when a connected central device requests to write the value of a
    // characteristic registered on the local GATT server. Not responding
    // to this request for a long time may lead to a disconnection.
    // This event is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |request|: Request data for this request.
    // |characteristic|: The GATT characteristic whose value is being written.
    static void onCharacteristicWriteRequest(
        Request request, DOMString characteristicId);

    // Fired when a connected central device requests to read the value of a
    // descriptor registered on the local GATT server. Not responding to
    // this request for a long time may lead to a disconnection.
    // This event is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |request|: Request data for this request.
    // |descriptor|: The GATT descriptor whose value is requested.
    static void onDescriptorReadRequest(
        Request request, DOMString descriptorId);

    // Fired when a connected central device requests to write the value of a
    // descriptor registered on the local GATT server. Not responding to
    // this request for a long time may lead to a disconnection.
    // This event is only available if the app has both the
    // bluetooth:low_energy and the bluetooth:peripheral permissions set to
    // true. The peripheral permission may not be available to all apps.
    // |request|: Request data for this request.
    // |descriptor|: The GATT descriptor whose value is being written.
    static void onDescriptorWriteRequest(
        Request request, DOMString descriptorId);
  };
};
