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


/************************************************************************************
 *
 *  Filename:      btif_gatt_server.c
 *
 *  Description:   GATT server implementation
 *
 ***********************************************************************************/

#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define LOG_TAG "BtGatt.btif"

#include "btif_common.h"
#include "btif_util.h"

#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))

#include "gki.h"
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "bd.h"
#include "btif_dm.h"
#include "btif_storage.h"

#include "btif_gatt.h"
#include "btif_gatt_util.h"

/************************************************************************************
**  Constants & Macros
************************************************************************************/

#define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
    {\
        ALOGW("%s: BTGATT not initialized", __FUNCTION__);\
        return BT_STATUS_NOT_READY;\
    } else {\
        ALOGD("%s", __FUNCTION__);\
    }


typedef enum {
    BTIF_GATTS_REGISTER_APP = 2000,
    BTIF_GATTS_UNREGISTER_APP,
    BTIF_GATTS_OPEN,
    BTIF_GATTS_CLOSE,
    BTIF_GATTS_CREATE_SERVICE,
    BTIF_GATTS_ADD_INCLUDED_SERVICE,
    BTIF_GATTS_ADD_CHARACTERISTIC,
    BTIF_GATTS_ADD_DESCRIPTOR,
    BTIF_GATTS_START_SERVICE,
    BTIF_GATTS_STOP_SERVICE,
    BTIF_GATTS_DELETE_SERVICE,
    BTIF_GATTS_SEND_INDICATION,
    BTIF_GATTS_SEND_RESPONSE
} btif_gatts_event_t;

/************************************************************************************
**  Local type definitions
************************************************************************************/

typedef struct
{
    uint8_t             value[BTGATT_MAX_ATTR_LEN];
    btgatt_response_t   response;
    btgatt_srvc_id_t    srvc_id;
    bt_bdaddr_t         bd_addr;
    bt_uuid_t           uuid;
    uint32_t            trans_id;
    uint16_t            conn_id;
    uint16_t            srvc_handle;
    uint16_t            incl_handle;
    uint16_t            attr_handle;
    uint16_t            permissions;
    uint16_t            len;
    uint8_t             server_if;
    uint8_t             is_direct;
    uint8_t             num_handles;
    uint8_t             properties;
    uint8_t             transport;
    uint8_t             confirm;
    uint8_t             status;
} __attribute__((packed)) btif_gatts_cb_t;


/************************************************************************************
**  Static variables
************************************************************************************/

extern const btgatt_callbacks_t *bt_gatt_callbacks;


/************************************************************************************
**  Static functions
************************************************************************************/

static void btapp_gatts_copy_req_data(UINT16 event, char *p_dest, char *p_src)
{
    tBTA_GATTS *p_dest_data = (tBTA_GATTS*) p_dest;
    tBTA_GATTS *p_src_data = (tBTA_GATTS*) p_src;

    if (!p_src_data || !p_dest_data)
        return;

    // Copy basic structure first
    memcpy(p_dest_data, p_src_data, sizeof(tBTA_GATTS));

    // Allocate buffer for request data if necessary
    switch (event)
    {
        case BTA_GATTS_READ_EVT:
        case BTA_GATTS_WRITE_EVT:
        case BTA_GATTS_EXEC_WRITE_EVT:
        case BTA_GATTS_MTU_EVT:
            p_dest_data->req_data.p_data = GKI_getbuf(sizeof(tBTA_GATTS_REQ_DATA));
            if (p_dest_data->req_data.p_data != NULL)
            {
                memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
                    sizeof(tBTA_GATTS_REQ_DATA));
            }
            break;

        default:
            break;
    }
}

static void btapp_gatts_free_req_data(UINT16 event, tBTA_GATTS *p_data)
{
    switch (event)
    {
        case BTA_GATTS_READ_EVT:
        case BTA_GATTS_WRITE_EVT:
        case BTA_GATTS_EXEC_WRITE_EVT:
        case BTA_GATTS_MTU_EVT:
            if (p_data && p_data->req_data.p_data)
                GKI_freebuf(p_data->req_data.p_data);
            break;

        default:
            break;
    }
}

static void btapp_gatts_handle_cback(uint16_t event, char* p_param)
{
    ALOGD("%s: Event %d", __FUNCTION__, event);

    tBTA_GATTS *p_data = (tBTA_GATTS*)p_param;
    switch (event)
    {
        case BTA_GATTS_REG_EVT:
        {
            bt_uuid_t app_uuid;
            bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.uuid);
            HAL_CBACK(bt_gatt_callbacks, server->register_server_cb
                , p_data->reg_oper.status
                , p_data->reg_oper.server_if
                , &app_uuid
            );
            break;
        }

        case BTA_GATTS_DEREG_EVT:
            break;

        case BTA_GATTS_CONNECT_EVT:
        {
            bt_bdaddr_t bda;
            bdcpy(bda.address, p_data->conn.remote_bda);

            btif_gatt_check_encrypted_link(p_data->conn.remote_bda);

            HAL_CBACK(bt_gatt_callbacks, server->connection_cb,
                      p_data->conn.conn_id, p_data->conn.server_if, TRUE, &bda);
            break;
        }

        case BTA_GATTS_DISCONNECT_EVT:
        {
            bt_bdaddr_t bda;
            bdcpy(bda.address, p_data->conn.remote_bda);

            HAL_CBACK(bt_gatt_callbacks, server->connection_cb,
                      p_data->conn.conn_id, p_data->conn.server_if, FALSE, &bda);
            break;
        }

        case BTA_GATTS_CREATE_EVT:
        {
            btgatt_srvc_id_t srvc_id;
            srvc_id.is_primary = p_data->create.is_primary;
            srvc_id.id.inst_id = p_data->create.svc_instance;
            bta_to_btif_uuid(&srvc_id.id.uuid, &p_data->create.uuid);

            HAL_CBACK(bt_gatt_callbacks, server->service_added_cb,
                      p_data->create.status, p_data->create.server_if, &srvc_id,
                      p_data->create.service_id
            );
        }
        break;

        case BTA_GATTS_ADD_INCL_SRVC_EVT:
            HAL_CBACK(bt_gatt_callbacks, server->included_service_added_cb,
                      p_data->add_result.status,
                      p_data->add_result.server_if,
                      p_data->add_result.service_id,
                      p_data->add_result.attr_id);
            break;

        case BTA_GATTS_ADD_CHAR_EVT:
        {
            bt_uuid_t uuid;
            bta_to_btif_uuid(&uuid, &p_data->add_result.char_uuid);

            HAL_CBACK(bt_gatt_callbacks, server->characteristic_added_cb,
                      p_data->add_result.status,
                      p_data->add_result.server_if,
                      &uuid,
                      p_data->add_result.service_id,
                      p_data->add_result.attr_id);
            break;
        }

        case BTA_GATTS_ADD_CHAR_DESCR_EVT:
        {
            bt_uuid_t uuid;
            bta_to_btif_uuid(&uuid, &p_data->add_result.char_uuid);

            HAL_CBACK(bt_gatt_callbacks, server->descriptor_added_cb,
                      p_data->add_result.status,
                      p_data->add_result.server_if,
                      &uuid,
                      p_data->add_result.service_id,
                      p_data->add_result.attr_id);
            break;
        }

        case BTA_GATTS_START_EVT:
            HAL_CBACK(bt_gatt_callbacks, server->service_started_cb,
                      p_data->srvc_oper.status,
                      p_data->srvc_oper.server_if,
                      p_data->srvc_oper.service_id);
            break;

        case BTA_GATTS_STOP_EVT:
            HAL_CBACK(bt_gatt_callbacks, server->service_stopped_cb,
                      p_data->srvc_oper.status,
                      p_data->srvc_oper.server_if,
                      p_data->srvc_oper.service_id);
            break;

        case BTA_GATTS_DELELTE_EVT:
            HAL_CBACK(bt_gatt_callbacks, server->service_deleted_cb,
                      p_data->srvc_oper.status,
                      p_data->srvc_oper.server_if,
                      p_data->srvc_oper.service_id);
            break;

        case BTA_GATTS_READ_EVT:
        {
            bt_bdaddr_t bda;
            bdcpy(bda.address, p_data->req_data.remote_bda);

            HAL_CBACK(bt_gatt_callbacks, server->request_read_cb,
                      p_data->req_data.conn_id,p_data->req_data.trans_id, &bda,
                      p_data->req_data.p_data->read_req.handle,
                      p_data->req_data.p_data->read_req.offset,
                      p_data->req_data.p_data->read_req.is_long);
            break;
        }

        case BTA_GATTS_WRITE_EVT:
        {
            bt_bdaddr_t bda;
            bdcpy(bda.address, p_data->req_data.remote_bda);

            HAL_CBACK(bt_gatt_callbacks, server->request_write_cb,
                      p_data->req_data.conn_id,p_data->req_data.trans_id, &bda,
                      p_data->req_data.p_data->write_req.handle,
                      p_data->req_data.p_data->write_req.offset,
                      p_data->req_data.p_data->write_req.len,
                      p_data->req_data.p_data->write_req.need_rsp,
                      p_data->req_data.p_data->write_req.is_prep,
                      p_data->req_data.p_data->write_req.value);
            break;
        }

        case BTA_GATTS_EXEC_WRITE_EVT:
        {
            bt_bdaddr_t bda;
            bdcpy(bda.address, p_data->req_data.remote_bda);

            HAL_CBACK(bt_gatt_callbacks, server->request_exec_write_cb,
                      p_data->req_data.conn_id,p_data->req_data.trans_id, &bda,
                      p_data->req_data.p_data->exec_write);
            break;
        }

        case BTA_GATTS_MTU_EVT:
        case BTA_GATTS_OPEN_EVT:
        case BTA_GATTS_CANCEL_OPEN_EVT:
        case BTA_GATTS_CLOSE_EVT:
            ALOGD("%s: Empty event (%d)!", __FUNCTION__, event);
            break;

        default:
            ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event);
            break;
    }

    btapp_gatts_free_req_data(event, p_data);
}

static void btapp_gatts_cback(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
{
    bt_status_t status;
    status = btif_transfer_context(btapp_gatts_handle_cback, (uint16_t) event,
        (void*)p_data, sizeof(tBTA_GATTS), btapp_gatts_copy_req_data);
    ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}

static void btgatts_handle_event(uint16_t event, char* p_param)
{
    btif_gatts_cb_t* p_cb = (btif_gatts_cb_t*)p_param;
    if (!p_cb) return;

    ALOGD("%s: Event %d", __FUNCTION__, event);

    switch (event)
    {
        case BTIF_GATTS_REGISTER_APP:
        {
            tBT_UUID uuid;
            btif_to_bta_uuid(&uuid, &p_cb->uuid);
            BTA_GATTS_AppRegister(&uuid, btapp_gatts_cback);
            break;
        }

        case BTIF_GATTS_UNREGISTER_APP:
            BTA_GATTS_AppDeregister(p_cb->server_if);
            break;

        case BTIF_GATTS_OPEN:
            if (!p_cb->is_direct)
                BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
            BTA_GATTS_Open(p_cb->server_if, p_cb->bd_addr.address,
                           p_cb->is_direct);
            break;

        case BTIF_GATTS_CLOSE:
            // Cancel pending foreground/background connections
            BTA_GATTS_CancelOpen(p_cb->server_if, p_cb->bd_addr.address, TRUE);
            BTA_GATTS_CancelOpen(p_cb->server_if, p_cb->bd_addr.address, FALSE);

            // Close active connection
            if (p_cb->conn_id != 0)
                BTA_GATTS_Close(p_cb->conn_id);
            break;

        case BTIF_GATTS_CREATE_SERVICE:
        {
            tBTA_GATT_SRVC_ID srvc_id;
            btif_to_bta_srvc_id(&srvc_id, &p_cb->srvc_id);
            BTA_GATTS_CreateService(p_cb->server_if, &srvc_id.id.uuid,
                                    srvc_id.id.inst_id, p_cb->num_handles,
                                    srvc_id.is_primary);
            break;
        }

        case BTIF_GATTS_ADD_INCLUDED_SERVICE:
            BTA_GATTS_AddIncludeService(p_cb->srvc_handle, p_cb->incl_handle);
            break;

        case BTIF_GATTS_ADD_CHARACTERISTIC:
        {
            tBT_UUID uuid;
            btif_to_bta_uuid(&uuid, &p_cb->uuid);

            BTA_GATTS_AddCharacteristic(p_cb->srvc_handle, &uuid,
                                        p_cb->permissions, p_cb->properties);
            break;
        }

        case BTIF_GATTS_ADD_DESCRIPTOR:
        {
            tBT_UUID uuid;
            btif_to_bta_uuid(&uuid, &p_cb->uuid);

            BTA_GATTS_AddCharDescriptor(p_cb->srvc_handle, p_cb->permissions,
                                         &uuid);
            break;
        }

        case BTIF_GATTS_START_SERVICE:
            BTA_GATTS_StartService(p_cb->srvc_handle, p_cb->transport);
            break;

        case BTIF_GATTS_STOP_SERVICE:
            BTA_GATTS_StopService(p_cb->srvc_handle);
            break;

        case BTIF_GATTS_DELETE_SERVICE:
            BTA_GATTS_DeleteService(p_cb->srvc_handle);
            break;

        case BTIF_GATTS_SEND_INDICATION:
            BTA_GATTS_HandleValueIndication(p_cb->conn_id, p_cb->attr_handle,
                                        p_cb->len, p_cb->value, p_cb->confirm);
            // TODO: Might need to send an ACK if handle value indication is
            //       invoked without need for confirmation.
            break;

        case BTIF_GATTS_SEND_RESPONSE:
        {
            tBTA_GATTS_RSP rsp_struct;
            btgatt_response_t *p_rsp = &p_cb->response;
            btif_to_bta_response(&rsp_struct, p_rsp);

            BTA_GATTS_SendRsp(p_cb->conn_id, p_cb->trans_id,
                              p_cb->status, &rsp_struct);

            HAL_CBACK(bt_gatt_callbacks, server->response_confirmation_cb,
                      0, rsp_struct.attr_value.handle);
            break;
        }

        default:
            ALOGE("%s: Unknown event (%d)!", __FUNCTION__, event);
            break;
    }
}

/************************************************************************************
**  Server API Functions
************************************************************************************/

static bt_status_t btif_gatts_register_app(bt_uuid_t *uuid)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_REGISTER_APP,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_unregister_app( int server_if )
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_UNREGISTER_APP,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr, bool is_direct )
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.is_direct = is_direct ? 1 : 0;
    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_OPEN,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_close(int server_if, const bt_bdaddr_t *bd_addr, int conn_id)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.conn_id = (uint16_t) conn_id;
    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_CLOSE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_add_service(int server_if, btgatt_srvc_id_t *srvc_id,
                                          int num_handles)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.num_handles = (uint8_t) num_handles;
    memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_CREATE_SERVICE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_add_included_service(int server_if, int service_handle,
                                                   int included_handle)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.srvc_handle = (uint16_t) service_handle;
    btif_cb.incl_handle = (uint16_t) included_handle;
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_ADD_INCLUDED_SERVICE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_add_characteristic(int server_if, int service_handle,
                                                 bt_uuid_t *uuid, int properties,
                                                 int permissions)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.srvc_handle = (uint16_t) service_handle;
    btif_cb.properties = (uint8_t) properties;
    btif_cb.permissions = (uint16_t) permissions;
    memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_ADD_CHARACTERISTIC,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_add_descriptor(int server_if, int service_handle, bt_uuid_t *uuid,
                                             int permissions)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.srvc_handle = (uint16_t) service_handle;
    btif_cb.permissions = (uint16_t) permissions;
    memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_ADD_DESCRIPTOR,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_start_service(int server_if, int service_handle, int transport)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.srvc_handle = (uint16_t) service_handle;
    btif_cb.transport = (uint8_t) transport;
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_START_SERVICE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_stop_service(int server_if, int service_handle)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.srvc_handle = (uint16_t) service_handle;
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_STOP_SERVICE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_delete_service(int server_if, int service_handle)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.srvc_handle = (uint16_t) service_handle;
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_DELETE_SERVICE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_send_indication(int server_if, int attribute_handle, int conn_id,
                                              int len, int confirm, char* p_value)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.server_if = (uint8_t) server_if;
    btif_cb.conn_id = (uint16_t) conn_id;
    btif_cb.attr_handle = attribute_handle;
    btif_cb.confirm = confirm;
    btif_cb.len = len;
    memcpy(btif_cb.value, p_value, len > BTGATT_MAX_ATTR_LEN ? BTGATT_MAX_ATTR_LEN : len);
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_SEND_INDICATION,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

static bt_status_t btif_gatts_send_response(int conn_id, int trans_id,
                                            int status, btgatt_response_t *response)
{
    CHECK_BTGATT_INIT();
    btif_gatts_cb_t btif_cb;
    btif_cb.conn_id = (uint16_t) conn_id;
    btif_cb.trans_id = (uint32_t) trans_id;
    btif_cb.status = (uint8_t) status;
    memcpy(&btif_cb.response, response, sizeof(btgatt_response_t));
    return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_SEND_RESPONSE,
                                 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}

const btgatt_server_interface_t btgattServerInterface = {
    btif_gatts_register_app,
    btif_gatts_unregister_app,
    btif_gatts_open,
    btif_gatts_close,
    btif_gatts_add_service,
    btif_gatts_add_included_service,
    btif_gatts_add_characteristic,
    btif_gatts_add_descriptor,
    btif_gatts_start_service,
    btif_gatts_stop_service,
    btif_gatts_delete_service,
    btif_gatts_send_indication,
    btif_gatts_send_response
};

#endif
