/*
 * Copyright (C) 2015, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Binder IPC interface for interacting with Bluetooth GATT server-role
 * features.
 */
interface IBluetoothGattServer {
  /**
   * Registers a client application with this interface. This creates a unique
   * GATT server instance for the application that will contain the GATT
   * services belonging to the calling application. A special interface ID will
   * be returned in a callback to the application that can be used to perform
   * GATT server operations. Returns false in case of an error.
   */
  boolean registerServer(in IBluetoothGattServerCallback callback);

  /**
   * Unregisters a previously registered server with interface ID |server_if|.
   */
  void unregisterServer(in int server_if);

  /**
   * Unregisters all previously registered servers.
   */
  void unregisterAll();

  /**
   * Adds new GATT service. This will execute synchronously, and result in
   * IBluetoothGattServerCallback.onServiceAdded.
   *
   * Returns true on success, false otherwise.
   */
  boolean AddService(int server_id, in BluetoothGattService service);

  /**
   * Sends a response to a currently pending read or write request. The request
   * will be propagated to the application via IBluetoothGattServerCallback with
   * a unique |request_id| which must be passed to this method along with the
   * |device_address| of the device that the request originated from.
   *
   * The |status| field should contain the result of the operation. In the case
   * of success, the application should pass in "0". Otherwise this should
   * contain an ATT protocol error code.
   */
  boolean sendResponse(in int server_if, in String device_address,
                       in int request_id, in int status,
                       in int offset, in byte[] value);

  /**
   * Sends a handle-value notification or indication to the device with the
   * given address for the characteristic with the given handle. |confirm|
   * should be set to true, if a handle-value indication should be sent, which
   * will remain pending until the remote device sends a handle-value
   * confirmation. Returns false if a call to this method is pending. Otherwise
   * reports the result asynchronously in
   * IBluetoothGattServerCallback.onNotificationSent.
   */
  boolean sendNotification(in int server_if, in String device_address,
                           in int handle,
                           in boolean confirm, in byte[] value);
}
