/*
 * Copyright (C) 2013 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.
 */


#ifndef ANDROID_INCLUDE_BT_GATT_SERVER_H
#define ANDROID_INCLUDE_BT_GATT_SERVER_H

#include <stdint.h>
#include <vector>

#include "bt_gatt_types.h"

__BEGIN_DECLS

/** GATT value type used in response to remote read requests */
typedef struct
{
    uint8_t           value[BTGATT_MAX_ATTR_LEN];
    uint16_t          handle;
    uint16_t          offset;
    uint16_t          len;
    uint8_t           auth_req;
} btgatt_value_t;

/** GATT remote read request response type */
typedef union
{
    btgatt_value_t attr_value;
    uint16_t            handle;
} btgatt_response_t;

/** BT-GATT Server callback structure. */

/** Callback invoked in response to register_server */
typedef void (*register_server_callback)(int status, int server_if,
                const bt_uuid_t& app_uuid);

/** Callback indicating that a remote device has connected or been disconnected */
typedef void (*connection_callback)(int conn_id, int server_if, int connected,
                                    const RawAddress& bda);

/** Callback invoked in response to create_service */
typedef void (*service_added_callback)(int status, int server_if,
                                       std::vector<btgatt_db_element_t> service);

/** Callback invoked in response to stop_service */
typedef void (*service_stopped_callback)(int status, int server_if,
                                         int srvc_handle);

/** Callback triggered when a service has been deleted */
typedef void (*service_deleted_callback)(int status, int server_if,
                                         int srvc_handle);

/**
 * Callback invoked when a remote device has requested to read a characteristic
 * or descriptor. The application must respond by calling send_response
 */
typedef void (*request_read_callback)(int conn_id, int trans_id, const RawAddress& bda,
                                      int attr_handle, int offset, bool is_long);

/**
 * Callback invoked when a remote device has requested to write to a
 * characteristic or descriptor.
 */
typedef void (*request_write_callback)(int conn_id, int trans_id, const RawAddress& bda,
                                       int attr_handle, int offset, bool need_rsp,
                                       bool is_prep, std::vector<uint8_t> value);

/** Callback invoked when a previously prepared write is to be executed */
typedef void (*request_exec_write_callback)(int conn_id, int trans_id,
                                            const RawAddress& bda, int exec_write);

/**
 * Callback triggered in response to send_response if the remote device
 * sends a confirmation.
 */
typedef void (*response_confirmation_callback)(int status, int handle);

/**
 * Callback confirming that a notification or indication has been sent
 * to a remote device.
 */
typedef void (*indication_sent_callback)(int conn_id, int status);

/**
 * Callback notifying an application that a remote device connection is currently congested
 * and cannot receive any more data. An application should avoid sending more data until
 * a further callback is received indicating the congestion status has been cleared.
 */
typedef void (*congestion_callback)(int conn_id, bool congested);

/** Callback invoked when the MTU for a given connection changes */
typedef void (*mtu_changed_callback)(int conn_id, int mtu);

/** Callback invoked when the PHY for a given connection changes */
typedef void (*phy_updated_callback)(int conn_id, uint8_t tx_phy,
                                     uint8_t rx_phy, uint8_t status);

/** Callback invoked when the connection parameters for a given connection changes */
typedef void (*conn_updated_callback)(int conn_id, uint16_t interval,
                                      uint16_t latency, uint16_t timeout,
                                      uint8_t status);
typedef struct {
    register_server_callback        register_server_cb;
    connection_callback             connection_cb;
    service_added_callback          service_added_cb;
    service_stopped_callback        service_stopped_cb;
    service_deleted_callback        service_deleted_cb;
    request_read_callback           request_read_characteristic_cb;
    request_read_callback           request_read_descriptor_cb;
    request_write_callback          request_write_characteristic_cb;
    request_write_callback          request_write_descriptor_cb;
    request_exec_write_callback     request_exec_write_cb;
    response_confirmation_callback  response_confirmation_cb;
    indication_sent_callback        indication_sent_cb;
    congestion_callback             congestion_cb;
    mtu_changed_callback            mtu_changed_cb;
    phy_updated_callback            phy_updated_cb;
    conn_updated_callback           conn_updated_cb;
} btgatt_server_callbacks_t;

/** Represents the standard BT-GATT server interface. */
typedef struct {
    /** Registers a GATT server application with the stack */
    bt_status_t (*register_server)(const bt_uuid_t& uuid);

    /** Unregister a server application from the stack */
    bt_status_t (*unregister_server)(int server_if );

    /** Create a connection to a remote peripheral */
    bt_status_t (*connect)(int server_if, const RawAddress& bd_addr,
                            bool is_direct, int transport);

    /** Disconnect an established connection or cancel a pending one */
    bt_status_t (*disconnect)(int server_if, const RawAddress& bd_addr,
                    int conn_id );

    /** Create a new service */
    bt_status_t (*add_service)(int server_if, std::vector<btgatt_db_element_t> service);

    /** Stops a local service */
    bt_status_t (*stop_service)(int server_if, int service_handle);

    /** Delete a local service */
    bt_status_t (*delete_service)(int server_if, int service_handle);

    /** Send value indication to a remote device */
    bt_status_t (*send_indication)(int server_if, int attribute_handle,
                                   int conn_id, int confirm,
                                   std::vector<uint8_t> value);

    /** Send a response to a read/write operation */
    bt_status_t (*send_response)(int conn_id, int trans_id,
                                 int status, const btgatt_response_t& response);

    bt_status_t (*set_preferred_phy)(const RawAddress& bd_addr, uint8_t tx_phy,
                                     uint8_t rx_phy, uint16_t phy_options);

    bt_status_t (*read_phy)(
        const RawAddress& bd_addr,
        base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)>
            cb);

} btgatt_server_interface_t;

__END_DECLS

#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */
