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

/******************************************************************************
 *
 *  This file contains the LLCP Service Discovery
 *
 ******************************************************************************/

#include <string.h>
#include "gki.h"
#include "nfc_target.h"
#include "bt_types.h"
#include "llcp_api.h"
#include "llcp_int.h"
#include "llcp_defs.h"

/*******************************************************************************
**
** Function         llcp_sdp_proc_data
**
** Description      Do nothing
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_proc_data (tLLCP_SAP_CBACK_DATA *p_data)
{
    /*
    ** Do nothing
    ** llcp_sdp_proc_SNL () is called by link layer
    */
}

/*******************************************************************************
**
** Function         llcp_sdp_check_send_snl
**
** Description      Enqueue Service Name Lookup PDU into sig_xmit_q for transmitting
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_check_send_snl (void)
{
    UINT8 *p;

    if (llcp_cb.sdp_cb.p_snl)
    {
        LLCP_TRACE_DEBUG0 ("SDP: llcp_sdp_check_send_snl ()");

        llcp_cb.sdp_cb.p_snl->len     += LLCP_PDU_HEADER_SIZE;
        llcp_cb.sdp_cb.p_snl->offset  -= LLCP_PDU_HEADER_SIZE;

        p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset;
        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_SDP, LLCP_PDU_SNL_TYPE, LLCP_SAP_SDP ));

        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, llcp_cb.sdp_cb.p_snl);
        llcp_cb.sdp_cb.p_snl = NULL;
    }
    else
    {
        /* Notify DTA after sending out SNL with SDRES not to send SNLs in AGF PDU */
        if ((llcp_cb.p_dta_cback) && (llcp_cb.dta_snl_resp))
        {
            llcp_cb.dta_snl_resp = FALSE;
            (*llcp_cb.p_dta_cback) ();
        }
    }
}

/*******************************************************************************
**
** Function         llcp_sdp_add_sdreq
**
** Description      Add Service Discovery Request into SNL PDU
**
**
** Returns          void
**
*******************************************************************************/
static void llcp_sdp_add_sdreq (UINT8 tid, char *p_name)
{
    UINT8  *p;
    UINT16 name_len = (UINT16) strlen (p_name);

    p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;

    UINT8_TO_BE_STREAM (p, LLCP_SDREQ_TYPE);
    UINT8_TO_BE_STREAM (p, (1 + name_len));
    UINT8_TO_BE_STREAM (p, tid);
    ARRAY_TO_BE_STREAM (p, p_name, name_len);

    llcp_cb.sdp_cb.p_snl->len += LLCP_SDREQ_MIN_LEN + name_len;
}

/*******************************************************************************
**
** Function         llcp_sdp_send_sdreq
**
** Description      Send Service Discovery Request
**
**
** Returns          LLCP_STATUS
**
*******************************************************************************/
tLLCP_STATUS llcp_sdp_send_sdreq (UINT8 tid, char *p_name)
{
    tLLCP_STATUS status;
    UINT16       name_len;
    UINT16       available_bytes;

    LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdreq (): tid=0x%x, ServiceName=%s", tid, p_name);

    /* if there is no pending SNL */
    if (!llcp_cb.sdp_cb.p_snl)
    {
        llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

        if (llcp_cb.sdp_cb.p_snl)
        {
            llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
            llcp_cb.sdp_cb.p_snl->len    = 0;
        }
    }

    if (llcp_cb.sdp_cb.p_snl)
    {
        available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl)
                          - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset
                          - llcp_cb.sdp_cb.p_snl->len;

        name_len = (UINT16) strlen (p_name);

        /* if SDREQ parameter can be added in SNL */
        if (  (available_bytes >= LLCP_SDREQ_MIN_LEN + name_len)
            &&(llcp_cb.sdp_cb.p_snl->len + LLCP_SDREQ_MIN_LEN + name_len <= llcp_cb.lcb.effective_miu)  )
        {
            llcp_sdp_add_sdreq (tid, p_name);
            status = LLCP_STATUS_SUCCESS;
        }
        else
        {
            /* send pending SNL PDU to LM */
            llcp_sdp_check_send_snl ();

            llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

            if (llcp_cb.sdp_cb.p_snl)
            {
                llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
                llcp_cb.sdp_cb.p_snl->len    = 0;

                llcp_sdp_add_sdreq (tid, p_name);

                status = LLCP_STATUS_SUCCESS;
            }
            else
            {
                status = LLCP_STATUS_FAIL;
            }
        }
    }
    else
    {
        status = LLCP_STATUS_FAIL;
    }

    /* if LM is waiting for PDUs from upper layer */
    if (  (status == LLCP_STATUS_SUCCESS)
        &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)  )
    {
        llcp_link_check_send_data ();
    }

    return status;
}

/*******************************************************************************
**
** Function         llcp_sdp_add_sdres
**
** Description      Add Service Discovery Response into SNL PDU
**
**
** Returns          void
**
*******************************************************************************/
static void llcp_sdp_add_sdres (UINT8 tid, UINT8 sap)
{
    UINT8  *p;

    p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;

    UINT8_TO_BE_STREAM (p, LLCP_SDRES_TYPE);
    UINT8_TO_BE_STREAM (p, LLCP_SDRES_LEN);
    UINT8_TO_BE_STREAM (p, tid);
    UINT8_TO_BE_STREAM (p, sap);

    llcp_cb.sdp_cb.p_snl->len += 2 + LLCP_SDRES_LEN;   /* type and length */
}

/*******************************************************************************
**
** Function         llcp_sdp_send_sdres
**
** Description      Send Service Discovery Response
**
**
** Returns          LLCP_STATUS
**
*******************************************************************************/
static tLLCP_STATUS llcp_sdp_send_sdres (UINT8 tid, UINT8 sap)
{
    tLLCP_STATUS status;
    UINT16       available_bytes;

    LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdres (): tid=0x%x, SAP=0x%x", tid, sap);

    /* if there is no pending SNL */
    if (!llcp_cb.sdp_cb.p_snl)
    {
        llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

        if (llcp_cb.sdp_cb.p_snl)
        {
            llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
            llcp_cb.sdp_cb.p_snl->len    = 0;
        }
    }

    if (llcp_cb.sdp_cb.p_snl)
    {
        available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl)
                          - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset
                          - llcp_cb.sdp_cb.p_snl->len;

        /* if SDRES parameter can be added in SNL */
        if (  (available_bytes >= 2 + LLCP_SDRES_LEN)
            &&(llcp_cb.sdp_cb.p_snl->len + 2 + LLCP_SDRES_LEN <= llcp_cb.lcb.effective_miu)  )
        {
            llcp_sdp_add_sdres (tid, sap);
            status = LLCP_STATUS_SUCCESS;
        }
        else
        {
            /* send pending SNL PDU to LM */
            llcp_sdp_check_send_snl ();

            llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

            if (llcp_cb.sdp_cb.p_snl)
            {
                llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
                llcp_cb.sdp_cb.p_snl->len    = 0;

                llcp_sdp_add_sdres (tid, sap);

                status = LLCP_STATUS_SUCCESS;
            }
            else
            {
                status = LLCP_STATUS_FAIL;
            }
        }
    }
    else
    {
        status = LLCP_STATUS_FAIL;
    }

    /* if LM is waiting for PDUs from upper layer */
    if (  (status == LLCP_STATUS_SUCCESS)
        &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)  )
    {
        llcp_link_check_send_data ();
    }

    return status;
}

/*******************************************************************************
**
** Function         llcp_sdp_get_sap_by_name
**
** Description      Search SAP by service name
**
**
** Returns          SAP if success
**
*******************************************************************************/
UINT8 llcp_sdp_get_sap_by_name (char *p_name, UINT8 length)
{
    UINT8        sap;
    tLLCP_APP_CB *p_app_cb;

    for (sap = LLCP_SAP_SDP; sap <= LLCP_UPPER_BOUND_SDP_SAP; sap++)
    {
        p_app_cb = llcp_util_get_app_cb (sap);

        if (  (p_app_cb)
            &&(p_app_cb->p_app_cback)
            &&(strlen((char*)p_app_cb->p_service_name) == length)
            &&(!strncmp((char*)p_app_cb->p_service_name, p_name, length))  )
        {
            /* if device is under LLCP DTA testing */
            if (  (llcp_cb.p_dta_cback)
                &&(!strncmp((char*)p_app_cb->p_service_name, "urn:nfc:sn:cl-echo-in", length))  )
            {
                llcp_cb.dta_snl_resp = TRUE;
            }
            return (sap);
        }
    }
    return 0;
}

/*******************************************************************************
**
** Function         llcp_sdp_return_sap
**
** Description      Report TID and SAP to requester
**
**
** Returns          void
**
*******************************************************************************/
static void llcp_sdp_return_sap (UINT8 tid, UINT8 sap)
{
    UINT8 i;

    LLCP_TRACE_DEBUG2 ("llcp_sdp_return_sap (): tid=0x%x, SAP=0x%x", tid, sap);

    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
    {
        if (  (llcp_cb.sdp_cb.transac[i].p_cback)
            &&(llcp_cb.sdp_cb.transac[i].tid == tid)  )
        {
            (*llcp_cb.sdp_cb.transac[i].p_cback) (tid, sap);

            llcp_cb.sdp_cb.transac[i].p_cback = NULL;
        }
    }
}

/*******************************************************************************
**
** Function         llcp_sdp_proc_deactivation
**
** Description      Report SDP failure for any pending request because of deactivation
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_proc_deactivation (void)
{
    UINT8 i;

    LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_deactivation ()");

    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
    {
        if (llcp_cb.sdp_cb.transac[i].p_cback)
        {
            (*llcp_cb.sdp_cb.transac[i].p_cback) (llcp_cb.sdp_cb.transac[i].tid, 0x00);

            llcp_cb.sdp_cb.transac[i].p_cback = NULL;
        }
    }

    /* free any pending SNL PDU */
    if (llcp_cb.sdp_cb.p_snl)
    {
        GKI_freebuf (llcp_cb.sdp_cb.p_snl);
        llcp_cb.sdp_cb.p_snl = NULL;
    }

    llcp_cb.sdp_cb.next_tid = 0;
    llcp_cb.dta_snl_resp = FALSE;
}

/*******************************************************************************
**
** Function         llcp_sdp_proc_snl
**
** Description      Process SDREQ and SDRES in SNL
**
**
** Returns          LLCP_STATUS
**
*******************************************************************************/
tLLCP_STATUS llcp_sdp_proc_snl (UINT16 sdu_length, UINT8 *p)
{
    UINT8  type, length, tid, sap, *p_value;

    LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl ()");

    if ((llcp_cb.lcb.agreed_major_version < LLCP_MIN_SNL_MAJOR_VERSION)||
       ((llcp_cb.lcb.agreed_major_version == LLCP_MIN_SNL_MAJOR_VERSION)&&(llcp_cb.lcb.agreed_minor_version < LLCP_MIN_SNL_MINOR_VERSION)))
    {
        LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl(): version number less than 1.1, SNL not supported.");
        return LLCP_STATUS_FAIL;
    }
    while (sdu_length >= 2) /* at least type and length */
    {
        BE_STREAM_TO_UINT8 (type, p);
        BE_STREAM_TO_UINT8 (length, p);

        switch (type)
        {
        case LLCP_SDREQ_TYPE:
            if (  (length > 1)                /* TID and sevice name */
                &&(sdu_length >= 2 + length)  ) /* type, length, TID and service name */
            {
                p_value = p;
                BE_STREAM_TO_UINT8 (tid, p_value);
                sap = llcp_sdp_get_sap_by_name ((char*) p_value, (UINT8) (length - 1));
                llcp_sdp_send_sdres (tid, sap);
            }
            else
            {
                LLCP_TRACE_ERROR1 ("llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDREQ_TYPE", length);
            }
            break;

        case LLCP_SDRES_TYPE:
            if (  (length == LLCP_SDRES_LEN)  /* TID and SAP */
                &&(sdu_length >= 2 + length)  ) /* type, length, TID and SAP */
            {
                p_value = p;
                BE_STREAM_TO_UINT8 (tid, p_value);
                BE_STREAM_TO_UINT8 (sap, p_value);
                llcp_sdp_return_sap (tid, sap);
            }
            else
            {
                LLCP_TRACE_ERROR1 ("llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDRES_TYPE", length);
            }
            break;

        default:
            LLCP_TRACE_WARNING1 ("llcp_sdp_proc_snl (): Unknown type (0x%x) is ignored", type);
            break;
        }

        if (sdu_length >= 2 + length)   /* type, length, value */
        {
            sdu_length -= 2 + length;
            p += length;
        }
        else
        {
            break;
        }
    }

    if (sdu_length)
    {
        LLCP_TRACE_ERROR0 ("llcp_sdp_proc_snl (): Bad format of SNL");
        return LLCP_STATUS_FAIL;
    }
    else
    {
        return LLCP_STATUS_SUCCESS;
    }
}
