/******************************************************************************
 *
 *  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 "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_EVENT2("   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_EVENT1("   GAP Discovery Complete Event(SDP Result: 0x%04x)", *((UINT16 *) p_data));
            }
            else
            {
                GAP_TRACE_EVENT0("   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_EVENT1("   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;

    GAP_TRACE_EVENT6 ("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_EVENT4 ("                             (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_EVENT2("   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)) == 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_EVENT1("   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_EVENT2("   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)) == 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
    /* 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);
    }
}
