/******************************************************************************
 *
 *  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.
 *
 ******************************************************************************/

#include <string.h>
#include "bt_target.h"
#include "bt_utils.h"
#include "gap_int.h"

/*****************************************************************************/
/*                 G L O B A L      GAP       D A T A                        */
/*****************************************************************************/
#if GAP_DYNAMIC_MEMORY == FALSE
tGAP_CB  gap_cb;
#endif

/*****************************************************************************
** Callbacks passed to BTM -
**      There are different callbacks based on the control block index so that
**      more than one command can be pending at a time.
**  NOTE:  There must be 1 callback for each control block defined
**          GAP_MAX_BLOCKS
**
**          Also, the inquiry results event has its own callback; Not handled here!
******************************************************************************/
static void btm_cback(UINT16 index, void *p_data)
{
    tGAP_INFO       *p_cb;
    tGAP_INQ_CMPL    inq_cmpl;

    /* Make sure that the index is valid AND it is in use */
    if (index < GAP_MAX_BLOCKS && gap_cb.blk[index].in_use)
    {
        p_cb = &gap_cb.blk[index];

        /* If the callback is non-NULL, call it with the specified event */
        switch (p_cb->event)
        {
        case GAP_EVT_INQUIRY_COMPLETE:
            /* pass the number of results to caller */
            inq_cmpl.num_results = ((tBTM_INQUIRY_CMPL *)p_data)->num_resp;

            inq_cmpl.status = (((tBTM_INQUIRY_CMPL *)p_data)->status == BTM_SUCCESS) ? BT_PASS : GAP_ERR_PROCESSING;

            p_data = &inq_cmpl;

            GAP_TRACE_EVENT("   GAP Inquiry Complete Event (Status 0x%04x, Result(s) %d)",
                            inq_cmpl.status, inq_cmpl.num_results);
            break;

        case GAP_EVT_DISCOVERY_COMPLETE:
            if (*((UINT16 *) p_data))
            {
                GAP_TRACE_EVENT("   GAP Discovery Complete Event(SDP Result: 0x%04x)", *((UINT16 *) p_data));
            }
            else
            {
                GAP_TRACE_EVENT("   GAP Discovery Successfully Completed");
            }

            break;

        case GAP_EVT_REM_NAME_COMPLETE:
            /* override the BTM error code with a GAP error code */
            ((tGAP_REMOTE_DEV_NAME *)p_data)->status =
                    gap_convert_btm_status ((tBTM_STATUS)((tBTM_REMOTE_DEV_NAME *)p_data)->status);

            GAP_TRACE_EVENT("   GAP Remote Name Complete Event (status 0x%04x)", ((tGAP_REMOTE_DEV_NAME *)p_data)->status);

            break;
        };

        if (p_cb->gap_cback)
            p_cb->gap_cback(p_cb->event, p_data);

        /* Deallocate the control block */
        gap_free_cb(p_cb);
    }
}


/*** Callback functions for BTM_CMPL_CB ***/
void gap_btm_cback0(void *p1)
{
    btm_cback(0, p1);
}

#if GAP_MAX_BLOCKS > 1
void gap_btm_cback1(void *p1)
{
    btm_cback(1, p1);
}
#endif
#if GAP_MAX_BLOCKS > 2
void gap_btm_cback2(void *p1)
{
    btm_cback(2, p1);
}
#endif

/* There is only one instance of this because only 1 inquiry can be active at a time */
void gap_inq_results_cb(tBTM_INQ_RESULTS *p_results, UINT8 *p_eir)
{
    tGAP_INFO   *p_cb;
    UINT8        index;
    UNUSED(p_eir);

    GAP_TRACE_EVENT ("GAP Inquiry Results Callback (bdaddr [%02x%02x%02x%02x%02x%02x])",
                p_results->remote_bd_addr[0], p_results->remote_bd_addr[1],
                p_results->remote_bd_addr[2], p_results->remote_bd_addr[3],
                p_results->remote_bd_addr[4], p_results->remote_bd_addr[5]);
    GAP_TRACE_EVENT ("                             (COD [%02x%02x%02x], clkoff 0x%04x)",
                p_results->dev_class[0], p_results->dev_class[1], p_results->dev_class[2],
                p_results->clock_offset);

    /* Find the control block which has an Inquiry Active and call its results callback */
    for (index = 0, p_cb = &gap_cb.blk[0]; index < GAP_MAX_BLOCKS; index++, p_cb++)
    {
        /* Look for the control block that is using inquiry */
        if (p_cb->in_use && (p_cb->event == GAP_EVT_INQUIRY_COMPLETE))
        {
            /* Notify the higher layer if they care */
            if (p_cb->gap_inq_rslt_cback)
                p_cb->gap_inq_rslt_cback (GAP_EVT_INQUIRY_RESULTS, (tGAP_INQ_RESULTS *)p_results);
        }
    }
}


/*******************************************************************************
**
** Function         gap_find_addr_name_cb
**
** Description      Processes the remote name request event when the Find Addr by Name
**                  request is active.  The following procedure takes place:
**                  1. Check the resulting name (If return status is ok)
**                  2. If name matches requested name, we're done, call the appl's callback
**                          with the BD ADDR.
**                  3. Otherwise get the next BD ADDR out of the inquiry database and intiate
**                          another remote name request.
**                  4. If there are no more BD ADDRs, then call the appl's callback with a FAIL
**                          status.
**
** Returns          void
**
*******************************************************************************/
void gap_find_addr_name_cb (tBTM_REMOTE_DEV_NAME *p)
{
    tGAP_FINDADDR_CB        *p_cb = &gap_cb.findaddr_cb;
    tGAP_FINDADDR_RESULTS   *p_result = &p_cb->results;

    if (p_cb->in_use)
    {
        if (p->status == BTM_SUCCESS)
        {
            GAP_TRACE_EVENT("   GAP: FindAddrByName Rem Name Cmpl Evt (Status 0x%04x, Name [%s])",
                                p->status, p->remote_bd_name);

            /* See if the returned name matches the desired name; if not initiate another search */
            if (!strncmp ((char *)p_result->devname, (char *) p->remote_bd_name, strlen ((char *) p_result->devname)))
            {
                /* We found the device!  Copy it into the return structure */
                memcpy (p_result->bd_addr, p_cb->p_cur_inq->results.remote_bd_addr, BD_ADDR_LEN);
                p_result->status = BT_PASS;
            }
            else    /* The name doesn't match so initiate another search */
            {
                /* Get the device address of the next database entry */
                if ((p_cb->p_cur_inq = BTM_InqDbNext(p_cb->p_cur_inq)) != NULL)
                {
                    if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr,
                        (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
                        return;     /* This routine will get called again with the next results */
                    else
                        p_result->status = gap_convert_btm_status ((tBTM_STATUS) p->status);
                }
                else
                    p_result->status = GAP_EOINQDB;     /* No inquiry results; we're done! */
            }
        }
        else
        {
            GAP_TRACE_EVENT("   GAP: FindAddrByName Rem Name Cmpl Evt (Status 0x%04x)", p->status);
            p_result->status = gap_convert_btm_status ((tBTM_STATUS) p->status);
        }

        /* If this code is reached, the process has completed so call the appl's callback with results */
        if (p_cb->p_cback)
            p_cb->p_cback (GAP_EVT_FIND_ADDR_COMPLETE, (tGAP_FINDADDR_RESULTS *) p_result);

        /* Clear out the control block */
        p_cb->in_use = FALSE;
        p_cb->p_cback = (tGAP_CALLBACK *) NULL;
    }
}

/*******************************************************************************
**
** Function         gap_find_addr_inq_cb
**
** Description      Processes the inquiry complete event when the Find Addr by Name
**                  request is active.  This callback performs one of the two following
**                  steps:
**                      1. If the remote name is retrieved automatically, the DB is searched
**                          immediately, and the results are returned in the appls callback.
**
**                      2. If remote name is not automatic, retrieve the first BTM INQ
**                         database entry and initiate a remote name request.
**
** Returns          void
**
*******************************************************************************/
void gap_find_addr_inq_cb (tBTM_INQUIRY_CMPL *p)
{
    tGAP_FINDADDR_CB        *p_cb = &gap_cb.findaddr_cb;
    tGAP_FINDADDR_RESULTS   *p_result = &p_cb->results;

    if (p_cb->in_use)
    {

        GAP_TRACE_EVENT("   GAP: FindAddrByName Inq Cmpl Evt (Status 0x%04x, Result(s) %d)",
            p->status, p->num_resp);

        if (p->status == BTM_SUCCESS)
        {
            /* Step 1: If automatically retrieving remote names then search the local database */
            if ((p_result->status = gap_find_local_addr_by_name (p_result->devname, p_result->bd_addr)) == GAP_NO_DATA_AVAIL)
            {
                /* Step 2:  The name is not stored automatically, so a search of all devices needs to
                 *          be initiated.
                 */
                if ((p_cb->p_cur_inq = BTM_InqDbFirst()) != NULL)
                {
                    if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr,
                        (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
                        return;     /* Wait for the response in gap_find_addr_name_cb() */
                    else
                        p_result->status = gap_convert_btm_status (p->status);
                }
                else
                    p_result->status = GAP_EOINQDB;     /* No inquiry results; we're done! */
            }
        }
        else
            p_result->status = gap_convert_btm_status (p->status);

        /* If this code is reached, the process has completed so call the appl's callback with results */
        if (p_cb->p_cback)
            p_cb->p_cback (GAP_EVT_FIND_ADDR_COMPLETE, (tGAP_FINDADDR_RESULTS *) p_result);

        /* Clear out the control block */
        p_cb->in_use = FALSE;
        p_cb->p_cback = (tGAP_CALLBACK *) NULL;
    }
}

/*******************************************************************************
**
** Function         gap_find_local_addr_by_name
**
** Description      Searches through the internal inquiry database for a device
**                  that has the same name as the one passed in.  If found, the
**                  device address is filled in.
**
**                  NOTE:  It only searches up to the first BTM_MAX_REM_BD_NAME_LEN
**                          bytes because the inquiry database uses tBTM_BD_NAME.
**
** Returns          BT_PASS if the name was found and the device address is filled in
**                  GAP_EOINQDB if the name was not found in the database
**                  GAP_NO_DATA_AVAIL if the name is not saved with the inquiry
**
*******************************************************************************/
UINT16 gap_find_local_addr_by_name (const tBTM_BD_NAME devname, BD_ADDR bd_addr)
{

/* If the remote name is retrieved automatically during an inquiry search the local db */
#if (BTM_INQ_GET_REMOTE_NAME == TRUE)
    tBTM_INQ_INFO   *p_result;

    p_result = BTM_InqDbFirst();

    while (p_result)
    {
        /* Check the entry for a device name match */
        if (!strncmp ((char *)devname, (char *)p_result->remote_name, BTM_MAX_REM_BD_NAME_LEN))
        {
            memcpy (bd_addr, p_result->results.remote_bd_addr, BD_ADDR_LEN);
            return (BT_PASS);
        }
        else
            p_result = BTM_InqDbNext(p_result);
    };

    return (GAP_EOINQDB);
#else
    UNUSED(devname);
    UNUSED(bd_addr);
    /* No data available because we are not automatically saving the data */
    return (GAP_NO_DATA_AVAIL);
#endif
}


/*******************************************************************************
**
** Function         gap_allocate_cb
**
** Description      Look through the GAP Control Blocks for a free one.
**
** Returns          Pointer to the control block or NULL if not found
**
*******************************************************************************/
tGAP_INFO *gap_allocate_cb (void)
{
    tGAP_INFO     *p_cb = &gap_cb.blk[0];
    UINT8        x;

    for (x = 0; x < GAP_MAX_BLOCKS; x++, p_cb++)
    {
        if (!p_cb->in_use)
        {
            memset (p_cb, 0, sizeof (tGAP_INFO));

            p_cb->in_use = TRUE;
            p_cb->index = x;
            p_cb->p_data = (void *)NULL;
            return (p_cb);
        }
    }

    /* If here, no free control blocks found */
    return (NULL);
}


/*******************************************************************************
**
** Function         gap_free_cb
**
** Description      Release GAP control block.
**
** Returns          Pointer to the control block or NULL if not found
**
*******************************************************************************/
void gap_free_cb (tGAP_INFO *p_cb)
{
    if (p_cb)
    {
        p_cb->gap_cback = NULL;
        p_cb->in_use = FALSE;
    }
}


/*******************************************************************************
**
** Function         gap_is_service_busy
**
** Description      Look through the GAP Control Blocks that are in use
**                  and check to see if the event waiting for is the command
**                  requested.
**
** Returns          TRUE if already in use
**                  FALSE if not busy
**
*******************************************************************************/
BOOLEAN gap_is_service_busy (UINT16 request)
{
    tGAP_INFO   *p_cb = &gap_cb.blk[0];
    UINT8        x;

    for (x = 0; x < GAP_MAX_BLOCKS; x++, p_cb++)
    {
        if (p_cb->in_use && p_cb->event == request)
            return (TRUE);
    }

    /* If here, service is not busy */
    return (FALSE);
}


/*******************************************************************************
**
** Function         gap_convert_btm_status
**
** Description      Converts a BTM error status into a GAP error status
**
**
** Returns          GAP_UNKNOWN_BTM_STATUS is returned if not recognized
**
*******************************************************************************/
UINT16 gap_convert_btm_status (tBTM_STATUS btm_status)
{
    switch (btm_status)
    {
    case BTM_SUCCESS:
        return (BT_PASS);

    case BTM_CMD_STARTED:
        return (GAP_CMD_INITIATED);

    case BTM_BUSY:
        return (GAP_ERR_BUSY);

    case BTM_MODE_UNSUPPORTED:
    case BTM_ILLEGAL_VALUE:
        return (GAP_ERR_ILL_PARM);

    case BTM_WRONG_MODE:
        return (GAP_DEVICE_NOT_UP);

    case BTM_UNKNOWN_ADDR:
        return (GAP_BAD_BD_ADDR);

    case BTM_DEVICE_TIMEOUT:
        return (GAP_ERR_TIMEOUT);

    default:
        return (GAP_ERR_PROCESSING);
    }
}
