/******************************************************************************
 *
 *  Copyright (C) 2014  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_multi_adv_util.c
 *
 *  Description:   Multi ADV helper implementation
 *
 *******************************************************************************/

#define LOG_TAG "bt_btif_gatt"


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "btu.h"
#include "bt_target.h"

#if (BLE_INCLUDED == TRUE)

#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>

#include "bta_gatt_api.h"
#include "btif_common.h"
#include "btif_gatt_multi_adv_util.h"
#include "btif_gatt_util.h"

extern fixed_queue_t *btu_general_alarm_queue;

/*******************************************************************************
**  Static variables
********************************************************************************/
static int user_app_count = 0;
static btgatt_multi_adv_common_data *p_multi_adv_com_data_cb = NULL;

btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()
{
    int max_adv_inst = BTM_BleMaxMultiAdvInstanceCount();
    if (0 == max_adv_inst)
        max_adv_inst = 1;

    BTIF_TRACE_DEBUG("%s, Count:%d", __FUNCTION__, max_adv_inst);

    if (NULL == p_multi_adv_com_data_cb)
    {
        p_multi_adv_com_data_cb = (btgatt_multi_adv_common_data*)osi_calloc(sizeof(btgatt_multi_adv_common_data));
        /* Storing both client_if and inst_id details */
        p_multi_adv_com_data_cb->clntif_map =
            (INT8*)osi_calloc((max_adv_inst * INST_ID_IDX_MAX) * sizeof(INT8));

        p_multi_adv_com_data_cb->inst_cb = (btgatt_multi_adv_inst_cb*)
            osi_calloc((max_adv_inst + 1) * sizeof(btgatt_multi_adv_inst_cb));

        for (int i = 0; i < max_adv_inst * 2; i += 2) {
            p_multi_adv_com_data_cb->clntif_map[i] = INVALID_ADV_INST;
            p_multi_adv_com_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
        }
    }

    return p_multi_adv_com_data_cb;
}

void btif_gattc_incr_app_count(void)
{
    // TODO: Instead of using a fragile reference counter here, one could
    //       simply track the client_if instances that are in the map.
    ++user_app_count;
}

void btif_gattc_decr_app_count(void)
{
    if (user_app_count > 0)
        user_app_count--;

    if ((user_app_count == 0) && (p_multi_adv_com_data_cb != NULL)) {
       osi_free(p_multi_adv_com_data_cb->clntif_map);
       osi_free(p_multi_adv_com_data_cb->inst_cb);
       osi_free_and_reset((void **)&p_multi_adv_com_data_cb);
    }
}

int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_instid)
{
    int i=1;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    if (NULL == p_multi_adv_data_cb)
        return INVALID_ADV_INST;

    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    {
       if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
       {
          if (!gen_temp_instid)
          {
             // Write the final inst_id value obtained from stack layer
             p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
             BTIF_TRACE_DEBUG("%s -Index: %d, Found client_if: %d", __FUNCTION__,
                i, p_multi_adv_data_cb->clntif_map[i + i]);
             break;
          }
          else
          {
              //Store the passed in inst_id value
             if (inst_id != INVALID_ADV_INST)
                 p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
             else
                 p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);

             BTIF_TRACE_DEBUG("%s - Index:%d,Found client_if: %d", __FUNCTION__,
                i, p_multi_adv_data_cb->clntif_map[i + i]);
             break;
          }
       }
    }

    if (i <  BTM_BleMaxMultiAdvInstanceCount())
        return i;

    // If client ID if is not found, then write both values
    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    {
        if (INVALID_ADV_INST == p_multi_adv_data_cb->clntif_map[i + i])
        {
            p_multi_adv_data_cb->clntif_map[i + i] = client_if;
            if (inst_id != INVALID_ADV_INST)
               p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
            else
                p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
            BTIF_TRACE_DEBUG("%s -Not found - Index:%d, client_if: %d, Inst ID: %d",
                            __FUNCTION__,i,
                            p_multi_adv_data_cb->clntif_map[i + i],
                            p_multi_adv_data_cb->clntif_map[i + (i + 1)]);
            break;
        }
    }

    if (i <  BTM_BleMaxMultiAdvInstanceCount())
        return i;
    return INVALID_ADV_INST;
}

int btif_multi_adv_instid_for_clientif(int client_if)
{
    int i=1, ret = INVALID_ADV_INST;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();

    if (NULL == p_multi_adv_data_cb)
        return INVALID_ADV_INST;

    // Retrieve the existing inst_id for the client_if value
    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    {
       if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
       {
           BTIF_TRACE_DEBUG("%s - Client if found", __FUNCTION__, client_if);
           ret = p_multi_adv_data_cb->clntif_map[i + (i + 1)];
       }
    }

    return ret;
}

int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index)
{
    int i=1;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();

    if (NULL == p_multi_adv_data_cb)
        return INVALID_ADV_INST;

    // Retrieve the array index for the inst_id value
    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    {
       if (value == p_multi_adv_data_cb->clntif_map[i + (i + clnt_inst_index)])
           break;
    }

    if (i <  BTM_BleMaxMultiAdvInstanceCount())
    {
        BTIF_TRACE_DEBUG("%s, %d",__FUNCTION__,i);
        return i;
    }

    BTIF_TRACE_DEBUG("%s Invalid instance",__FUNCTION__);
    return INVALID_ADV_INST;
}

void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
                bool include_name, bool include_txpower, int min_interval, int max_interval,
                int appearance, int manufacturer_len, char* manufacturer_data,
                int service_data_len, char* service_data, int service_uuid_len,
                char* service_uuid, btif_adv_data_t *p_multi_adv_inst)
{
    memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));

    p_multi_adv_inst->client_if = (uint8_t) client_if;
    p_multi_adv_inst->set_scan_rsp = set_scan_rsp;
    p_multi_adv_inst->include_name = include_name;
    p_multi_adv_inst->include_txpower = include_txpower;
    p_multi_adv_inst->min_interval = min_interval;
    p_multi_adv_inst->max_interval = max_interval;
    p_multi_adv_inst->appearance = appearance;

    if (manufacturer_len > 0)
    {
        if (manufacturer_len > MAX_SIZE_MANUFACTURER_DATA)
            manufacturer_len = MAX_SIZE_MANUFACTURER_DATA;

        p_multi_adv_inst->manufacturer_len = manufacturer_len;
        memcpy(p_multi_adv_inst->p_manufacturer_data, manufacturer_data, manufacturer_len);
    }

    if (service_data_len > 0)
    {
        if (service_data_len > MAX_SIZE_PROPRIETARY_ELEMENT)
            service_data_len = MAX_SIZE_PROPRIETARY_ELEMENT;

        p_multi_adv_inst->service_data_len = service_data_len;
        memcpy(p_multi_adv_inst->p_service_data, service_data, service_data_len);
    }

    if (service_uuid_len > 0)
    {
        if (service_uuid_len > MAX_SIZE_SERVICE_DATA)
            service_uuid_len = MAX_SIZE_SERVICE_DATA;

        p_multi_adv_inst->service_uuid_len = service_uuid_len;
        memcpy(p_multi_adv_inst->p_service_uuid, service_uuid, service_uuid_len);
    }
}

BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
                               BOOLEAN bInstData) {
    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    if (NULL == p_multi_adv_data_cb || cbindex < 0)
       return false;

    BTIF_TRACE_DEBUG("%s", __func__);

    memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0,
           sizeof(p_multi_adv_data_cb->inst_cb[cbindex].data));
    p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;

    if (!p_adv_data->set_scan_rsp)
    {
         p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
         p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_GENERAL;
         if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s)
             p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_LIMITED;
         if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_type == BTA_BLE_NON_CONNECT_EVT)
             p_multi_adv_data_cb->inst_cb[cbindex].data.flag &=
                    ~(BTA_DM_LIMITED_DISC | BTA_DM_GENERAL_DISC);
         if (p_multi_adv_data_cb->inst_cb[cbindex].data.flag == 0)
            p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;
    }

    if (p_adv_data->include_name)
        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;

    if (p_adv_data->include_txpower)
        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_TX_PWR;

    if (false == bInstData && p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
        p_adv_data->max_interval > p_adv_data->min_interval)
    {
        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_INT_RANGE;
        p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
                                        p_adv_data->min_interval;
        p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
                                        p_adv_data->max_interval;
    }
    else
    if (true == bInstData)
    {
        if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min > 0 &&
            p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max > 0 &&
            p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max >
            p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min)
        {
              p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
              p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min;
              p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
              p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max;
        }

        if (p_adv_data->include_txpower)
        {
            p_multi_adv_data_cb->inst_cb[cbindex].data.tx_power =
                p_multi_adv_data_cb->inst_cb[cbindex].param.tx_power;
        }
    }

    if (p_adv_data->appearance != 0)
    {
        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_APPEARANCE;
        p_multi_adv_data_cb->inst_cb[cbindex].data.appearance = p_adv_data->appearance;
    }

    if (p_adv_data->manufacturer_len > 0 &&
        p_adv_data->manufacturer_len < MAX_SIZE_MANUFACTURER_DATA)
    {
      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
      p_multi_adv_data_cb->inst_cb[cbindex].data.manu.len =
          p_adv_data->manufacturer_len;
      memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].data.manu.val,
             p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
    }

    if (p_adv_data->service_data_len > 0 &&
        p_adv_data->service_data_len < MAX_SIZE_PROPRIETARY_ELEMENT)
    {
      BTIF_TRACE_DEBUG("%s - In service_data", __func__);
      tBTA_BLE_PROPRIETARY *p_prop = &p_multi_adv_data_cb->inst_cb[cbindex].data.proprietary;
      p_prop->num_elem = 1;

      tBTA_BLE_PROP_ELEM *p_elem = &p_prop->elem[0];
      p_elem->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
      p_elem->len = p_adv_data->service_data_len;
      memcpy(p_elem->val, p_adv_data->p_service_data,
             p_adv_data->service_data_len);

      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
    }

    if (p_adv_data->service_uuid_len)
    {
        UINT16 *p_uuid_out16 = NULL;
        UINT32 *p_uuid_out32 = NULL;
        for (int position = 0; position < p_adv_data->service_uuid_len; position += LEN_UUID_128)
        {
             bt_uuid_t uuid;
             memset(&uuid, 0, sizeof(uuid));
             memcpy(&uuid.uu, p_adv_data->p_service_uuid + position, LEN_UUID_128);

             tBT_UUID bt_uuid;
             memset(&bt_uuid, 0, sizeof(bt_uuid));
             btif_to_bta_uuid(&bt_uuid, &uuid);

             switch(bt_uuid.len)
             {
                case (LEN_UUID_16):
                {
                  if (p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service == 0)
                  {
                      p_multi_adv_data_cb->inst_cb[cbindex].data.services.list_cmpl = FALSE;
                      p_uuid_out16 = p_multi_adv_data_cb->inst_cb[cbindex].data.services.uuid;
                  }

                  if (p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service < MAX_16BIT_SERVICES)
                  {
                     BTIF_TRACE_DEBUG("%s - In 16-UUID_data", __func__);
                     p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE;
                     ++p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service;
                     *p_uuid_out16++ = bt_uuid.uu.uuid16;
                  }
                  break;
                }

                case (LEN_UUID_32):
                {
                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service == 0)
                   {
                      p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.list_cmpl = FALSE;
                      p_uuid_out32 = p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.uuid;
                   }

                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service < MAX_32BIT_SERVICES)
                   {
                      BTIF_TRACE_DEBUG("%s - In 32-UUID_data", __func__);
                      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE_32;
                      ++p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service;
                      *p_uuid_out32++ = bt_uuid.uu.uuid32;
                   }
                   break;
                }

                case (LEN_UUID_128):
                {
                   /* Currently, only one 128-bit UUID is supported */
                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.services_128b.num_service == 0)
                   {
                     BTIF_TRACE_DEBUG("%s - In 128-UUID_data", __FUNCTION__);
                     p_multi_adv_data_cb->inst_cb[cbindex].mask |=
                         BTM_BLE_AD_BIT_SERVICE_128;
                     memcpy(p_multi_adv_data_cb->inst_cb[cbindex]
                                .data.services_128b.uuid128,
                            bt_uuid.uu.uuid128, LEN_UUID_128);
                     BTIF_TRACE_DEBUG(
                         "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x",
                         bt_uuid.uu.uuid128[0], bt_uuid.uu.uuid128[1],
                         bt_uuid.uu.uuid128[2], bt_uuid.uu.uuid128[3],
                         bt_uuid.uu.uuid128[4], bt_uuid.uu.uuid128[5],
                         bt_uuid.uu.uuid128[6], bt_uuid.uu.uuid128[7],
                         bt_uuid.uu.uuid128[8], bt_uuid.uu.uuid128[9],
                         bt_uuid.uu.uuid128[10], bt_uuid.uu.uuid128[11],
                         bt_uuid.uu.uuid128[12], bt_uuid.uu.uuid128[13],
                         bt_uuid.uu.uuid128[14], bt_uuid.uu.uuid128[15]);
                     ++p_multi_adv_data_cb->inst_cb[cbindex]
                           .data.services_128b.num_service;
                     p_multi_adv_data_cb->inst_cb[cbindex]
                         .data.services_128b.list_cmpl = TRUE;
                   }
                   break;
                }

                default:
                     break;
             }
        }
    }

     return true;
}

void btif_gattc_clear_clientif(int client_if, BOOLEAN stop_timer)
{
    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    if (NULL == p_multi_adv_data_cb)
        return;

    // Clear both the inst_id and client_if values
    for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount()*2; i+=2)
    {
        if (client_if == p_multi_adv_data_cb->clntif_map[i])
        {
            btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1], stop_timer);
            if (stop_timer)
            {
                p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
                p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
                BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if);
            }
            break;
        }
    }
}

void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer)
{
    // Check for invalid instance id
    if (inst_id < 0 || inst_id >= BTM_BleMaxMultiAdvInstanceCount())
        return;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    if (NULL == p_multi_adv_data_cb)
        return;

    int cbindex = (STD_ADV_INSTID == inst_id) ?
        STD_ADV_INSTID : btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
    if (cbindex < 0) return;

    BTIF_TRACE_DEBUG("%s: inst_id %d, cbindex %d", __func__, inst_id, cbindex);
    btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex], stop_timer);
}

void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb,
                                             BOOLEAN stop_timer)
{
    if (p_multi_inst_cb == NULL)
        return;

    // Discoverability timer cleanup
    if (stop_timer)
    {
        alarm_free(p_multi_inst_cb->multi_adv_timer);
        p_multi_inst_cb->multi_adv_timer = NULL;
    }

    memset(&p_multi_inst_cb->data, 0, sizeof(p_multi_inst_cb->data));
}

void btif_multi_adv_timer_ctrl(int client_if, alarm_callback_t cb)
{
    int inst_id = btif_multi_adv_instid_for_clientif(client_if);
    if (inst_id == INVALID_ADV_INST)
        return;

    int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
    if (cbindex == INVALID_ADV_INST)
        return;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    if (p_multi_adv_data_cb == NULL)
        return;

    btgatt_multi_adv_inst_cb *inst_cb = &p_multi_adv_data_cb->inst_cb[cbindex];
    if (cb == NULL)
    {
        alarm_free(inst_cb->multi_adv_timer);
        inst_cb->multi_adv_timer = NULL;
    } else {
        if (inst_cb->timeout_s != 0)
        {
            alarm_free(inst_cb->multi_adv_timer);
            inst_cb->multi_adv_timer = alarm_new("btif_gatt.multi_adv_timer");
            alarm_set_on_queue(inst_cb->multi_adv_timer,
                               inst_cb->timeout_s * 1000,
                               cb, INT_TO_PTR(client_if),
                               btu_general_alarm_queue);
        }
    }
}

#endif
