/*
 * 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 receiving callbacks related to Bluetooth GATT
 * server-role operations.
 */
oneway interface IBluetoothGattServerCallback {
  /**
   * Called to report the result of a call to
   * IBluetoothGattServer.registerServer. |status| will be 0 (or
   * BLE_STATUS_SUCCESS) if the server was successfully registered. |server_if|
   * is the owning application's unique GATT server handle and can be used to
   * perform further operations on the IBluetoothGattServer interface.
   */
  void onServerRegistered(in int status, in int server_if);

  /**
   * Called to report the result of a call to IBluetoothGattServer.AddService.
   * A |status| of 0 denotes success, which means that the GATT service has
   * been published and is discoverable. In this case handles of added service,
   * it's characteristics and descriptors are filled.
   */
  void onServiceAdded(in int status, in BluetoothGattServer service_id);

  /**
   * Called when there is an incoming read request from the remote device with
   * address |device_address| for the characteristic with handle |handle|.
   * |offset| is the index of the characteristic value that
   * the remote device wants to read from. If |is_long| is true, then this
   * request is part of a Long Read procedure. An implementation should handle
   * this request by calling IBluetoothGattServer.sendResponse with the given
   * |request_id| and the appropriate characteristic value.
   *
   * If |offset| is invalid then sendResponse should be called with
   * GATT_ERROR_INVALID_OFFSET. If |is_long| is true but this characteristic is
   * not a long attribute (i.e. its value would fit within the current ATT MTU),
   * then GATT_ERROR_ATTRIBUTE_NOT_LONG should be returned.
   */
  void onCharacteristicReadRequest(in String device_address, in int request_id,
                                   in int offset, in boolean is_long,
                                   in int handle);

  /**
   * Called when there is an incoming read request from the remote device with
   * address |device_address| for the descriptor with handle |handle|.
   * |offset| is the index of the descriptor value that
   * the remote device wants to read from. If |is_long| is true, then this
   * request is part of a Long Read procedure. An implementation should handle
   * this request by calling IBluetoothGattServer.sendResponse with the given
   * |request_id| and the appropriate descriptor value.
   *
   * If |offset| is invalid then sendResponse should be called with
   * GATT_ERROR_INVALID_OFFSET. If |is_long| is true but this descriptor is
   * not a long attribute (i.e. its value would fit within the current ATT MTU),
   * then GATT_ERROR_ATTRIBUTE_NOT_LONG should be returned.
   */
  void onDescriptorReadRequest(in String device_address, in int request_id,
                               in int offset, in boolean is_long,
                               in int handle);

  /**
   * Called when there is an incoming write request from the remote device with
   * address |device_address| for the characteristic with handle |handle|
   * with the value |value|. An implementation should handle
   * this request by calling IBluetoothGattServer.sendResponse with the given
   * |request_id|. |offset| is the index of the characteristic value that the
   * remote device wants to write to, so the value should be written starting at
   * |offset|. If |need_response| is false, then this is a "Write Without
   * Response" procedure and sendResponse should not be called. If
   * |is_prepare_write| is true, then the implementation should not commit this
   * write until a call to onExecuteWriteRequest is received.
   *
   * If |offset| is invalid, then sendResponse should be called with
   * GATT_ERROR_INVALID_OFFSET.
   */
  void onCharacteristicWriteRequest(in String device_address, in int request_id,
                                    in int offset, in boolean is_prepare_write,
                                    in boolean need_response, in byte[] value,
                                    in int handle);

  /**
   * Called when there is an incoming write request from the remote device with
   * address |device_address| for the descriptor with handle |handle|
   * with the value |value|. An implementation should handle
   * this request by calling IBluetoothGattServer.sendResponse with the given
   * |request_id|. |offset| is the index of the descriptor value that the
   * remote device wants to write to, so the value should be written starting at
   * |offset|. If |need_response| is false, then this is a "Write Without
   * Response" procedure and sendResponse should not be called. If
   * |is_prepare_write| is true, then the implementation should not commit this
   * write until a call to onExecuteWriteRequest is received.
   *
   * If |offset| is invalid, then sendResponse should be called with
   * GATT_ERROR_INVALID_OFFSET.
   */
  void onDescriptorWriteRequest(in String device_address, in int request_id,
                                in int offset, in boolean is_prepare_write,
                                in boolean need_response, in byte[] value,
                                in int handle);

  /**
   * Called when there is an incoming execute-write request to commit or abort
   * previously prepared writes. If |is_execute| is true, then the
   * implementation should commit all previously prepared writes. Otherwise all
   * prepared writes should dropped (aborted). The application should report the
   * result of the execute write by calling IBluetoothGattServer.sendResponse
   * with the given |request_id|.
   */
  void onExecuteWriteRequest(in String device_address, in int request_id,
                             in boolean is_execute);

  /**
   * Reports the result of a previous call to
   * IBluetoothGattServer.sendNotification. If an indication was sent, this will
   * be called when the remote device sends a confirmation packet. Otherwise
   * this will be called as soon as the notification packet is successfully sent
   * out over the radio.
   */
  void onNotificationSent(in String device_address, in int status);
}
