/******************************************************************************
 *
 *  Copyright (C) 2002-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 module contains API of the audio/video distribution transport
 *  protocol.
 *
 ******************************************************************************/

#include <string.h>
#include "data_types.h"
#include "bt_target.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"
#include "l2c_api.h"
#include "btm_api.h"
#include "btu.h"


#if (defined BTTRC_INCLUDED && BTTRC_INCLUDED == TRUE)
#include "bttrc_str_ids.h"
#endif

/* Control block for AVDT */
#if AVDT_DYNAMIC_MEMORY == FALSE
tAVDT_CB avdt_cb;
#endif


/*******************************************************************************
**
** Function         avdt_process_timeout
**
** Description      This function is called by BTU when an AVDTP timer
**                  expires.  The function sends a timer event to the
**                  appropriate CCB or SCB state machine.
**
**                  This function is for use internal to the stack only.
**
**
** Returns          void
**
*******************************************************************************/
void avdt_process_timeout(TIMER_LIST_ENT *p_tle)
{
    UINT8   event = 0;
    UINT8   err_code = AVDT_ERR_TIMEOUT;

    switch (p_tle->event)
    {
        case BTU_TTYPE_AVDT_CCB_RET:
            event = AVDT_CCB_RET_TOUT_EVT + AVDT_CCB_MKR;
            break;

        case BTU_TTYPE_AVDT_CCB_RSP:
            event = AVDT_CCB_RSP_TOUT_EVT + AVDT_CCB_MKR;
            break;

        case BTU_TTYPE_AVDT_CCB_IDLE:
            event = AVDT_CCB_IDLE_TOUT_EVT + AVDT_CCB_MKR;
            break;

        case BTU_TTYPE_AVDT_SCB_TC:
            event = AVDT_SCB_TC_TOUT_EVT;
            break;

        default:
            break;
    }

    if (event & AVDT_CCB_MKR)
    {
        avdt_ccb_event((tAVDT_CCB *) p_tle->param, (UINT8) (event & ~AVDT_CCB_MKR),
                       (tAVDT_CCB_EVT *) &err_code);
    }
    else
    {
        avdt_scb_event((tAVDT_SCB *) p_tle->param, event, NULL);
    }
}

/*******************************************************************************
**
** Function         AVDT_Register
**
** Description      This is the system level registration function for the
**                  AVDTP protocol.  This function initializes AVDTP and
**                  prepares the protocol stack for its use.  This function
**                  must be called once by the system or platform using AVDTP
**                  before the other functions of the API an be used.
**
**
** Returns          void
**
*******************************************************************************/
void AVDT_Register(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback)
{

    BTTRC_AVDT_API0(AVDT_TRACE_API_REGISTER);

    /* register PSM with L2CAP */
    L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO *) &avdt_l2c_appl);

    /* set security level */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
        AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
        AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);

    /* do not use security on the media channel */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
        AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
        AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);

#if AVDT_REPORTING == TRUE
    /* do not use security on the reporting channel */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
        AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
        AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
#endif

    /* initialize AVDTP data structures */
    avdt_scb_init();
    avdt_ccb_init();
    avdt_ad_init();
#if defined(AVDT_INITIAL_TRACE_LEVEL)
    avdt_cb.trace_level = AVDT_INITIAL_TRACE_LEVEL;
#else
    avdt_cb.trace_level = BT_TRACE_LEVEL_NONE;
#endif

    /* copy registration struct */
    memcpy(&avdt_cb.rcb, p_reg, sizeof(tAVDT_REG));
    avdt_cb.p_conn_cback = p_cback;
}

/*******************************************************************************
**
** Function         AVDT_Deregister
**
** Description      This function is called to deregister use AVDTP protocol.
**                  It is called when AVDTP is no longer being used by any
**                  application in the system.  Before this function can be
**                  called, all streams must be removed with AVDT_RemoveStream().
**
**
** Returns          void
**
*******************************************************************************/
void AVDT_Deregister(void)
{
    BTTRC_AVDT_API0(AVDT_TRACE_API_DEREGISTER);

    /* deregister PSM with L2CAP */
    L2CA_Deregister(AVDT_PSM);
}

/*******************************************************************************
**
** Function         AVDT_CreateStream
**
** Description      Create a stream endpoint.  After a stream endpoint is
**                  created an application can initiate a connection between
**                  this endpoint and an endpoint on a peer device.  In
**                  addition, a peer device can discover, get the capabilities,
**                  and connect to this endpoint.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs)
{
    UINT16      result = AVDT_SUCCESS;
    tAVDT_SCB   *p_scb;

    BTTRC_AVDT_API0(AVDT_TRACE_API_CREATESTREAM);

    /* Verify parameters; if invalid, return failure */
    if (((p_cs->cfg.psc_mask & (~AVDT_PSC)) != 0) || (p_cs->p_ctrl_cback == NULL))
    {
        result = AVDT_BAD_PARAMS;
    }
    /* Allocate scb; if no scbs, return failure */
    else if ((p_scb = avdt_scb_alloc(p_cs)) == NULL)
    {
        result = AVDT_NO_RESOURCES;
    }
    else
    {
        *p_handle = avdt_scb_to_hdl(p_scb);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_RemoveStream
**
** Description      Remove a stream endpoint.  This function is called when
**                  the application is no longer using a stream endpoint.
**                  If this function is called when the endpoint is connected
**                  the connection is closed and then the stream endpoint
**                  is removed.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_RemoveStream(UINT8 handle)
{
    UINT16      result = AVDT_SUCCESS;
    tAVDT_SCB   *p_scb;


    BTTRC_AVDT_API0(AVDT_TRACE_API_REMOVESTREAM);

    /* look up scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    else
    {
        /* send remove event to scb */
        avdt_scb_event(p_scb, AVDT_SCB_API_REMOVE_EVT, NULL);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_DiscoverReq
**
** Description      This function initiates a connection to the AVDTP service
**                  on the peer device, if not already present, and discovers
**                  the stream endpoints on the peer device.  (Please note
**                  that AVDTP discovery is unrelated to SDP discovery).
**                  This function can be called at any time regardless of whether
**                  there is an AVDTP connection to the peer device.
**
**                  When discovery is complete, an AVDT_DISCOVER_CFM_EVT
**                  is sent to the application via its callback function.
**                  The application must not call AVDT_GetCapReq() or
**                  AVDT_DiscoverReq() again to the same device until
**                  discovery is complete.
**
**                  The memory addressed by sep_info is allocated by the
**                  application.  This memory is written to by AVDTP as part
**                  of the discovery procedure.  This memory must remain
**                  accessible until the application receives the
**                  AVDT_DISCOVER_CFM_EVT.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO *p_sep_info,
                        UINT8 max_seps, tAVDT_CTRL_CBACK *p_cback)
{
    tAVDT_CCB       *p_ccb;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_CCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_DISCOVER_REQ);

    /* find channel control block for this bd addr; if none, allocate one */
    if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
    {
        if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
        {
            /* could not allocate channel control block */
            result = AVDT_NO_RESOURCES;
        }
    }

    if (result == AVDT_SUCCESS)
    {
        /* make sure no discovery or get capabilities req already in progress */
        if (p_ccb->proc_busy)
        {
            result = AVDT_BUSY;
        }
        /* send event to ccb */
        else
        {
            evt.discover.p_sep_info = p_sep_info;
            evt.discover.num_seps = max_seps;
            evt.discover.p_cback = p_cback;
            avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_REQ_EVT, &evt);
        }
    }
    return result;
}

/*******************************************************************************
**
** Function         avdt_get_cap_req
**
** Description      internal function to serve both AVDT_GetCapReq and
**                  AVDT_GetAllCapReq
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
static UINT16 avdt_get_cap_req(BD_ADDR bd_addr, tAVDT_CCB_API_GETCAP *p_evt)
{
    tAVDT_CCB       *p_ccb = NULL;
    UINT16          result = AVDT_SUCCESS;

    /* verify SEID */
    if ((p_evt->single.seid < AVDT_SEID_MIN) || (p_evt->single.seid > AVDT_SEID_MAX))
    {
        AVDT_TRACE_ERROR1("seid: %d", p_evt->single.seid);
        result = AVDT_BAD_PARAMS;
    }
    /* find channel control block for this bd addr; if none, allocate one */
    else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
    {
        if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
        {
            /* could not allocate channel control block */
            result = AVDT_NO_RESOURCES;
        }
    }

    if (result == AVDT_SUCCESS)
    {
        /* make sure no discovery or get capabilities req already in progress */
        if (p_ccb->proc_busy)
        {
            result = AVDT_BUSY;
        }
        /* send event to ccb */
        else
        {
            avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_REQ_EVT, (tAVDT_CCB_EVT *)p_evt);
        }
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_GetCapReq
**
** Description      This function initiates a connection to the AVDTP service
**                  on the peer device, if not already present, and gets the
**                  capabilities of a stream endpoint on the peer device.
**                  This function can be called at any time regardless of
**                  whether there is an AVDTP connection to the peer device.
**
**                  When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
**                  sent to the application via its callback function.  The
**                  application must not call AVDT_GetCapReq() or
**                  AVDT_DiscoverReq() again until the procedure is complete.
**
**                  The memory pointed to by p_cfg is allocated by the
**                  application.  This memory is written to by AVDTP as part
**                  of the get capabilities procedure.  This memory must
**                  remain accessible until the application receives
**                  the AVDT_GETCAP_CFM_EVT.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_GetCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback)
{
    tAVDT_CCB_API_GETCAP    getcap;

    BTTRC_AVDT_API1(AVDT_TRACE_API_GETCAP_REQ, BTTRC_PARAM_UINT8, seid);

    getcap.single.seid = seid;
    getcap.single.sig_id = AVDT_SIG_GETCAP;
    getcap.p_cfg = p_cfg;
    getcap.p_cback = p_cback;
    return avdt_get_cap_req (bd_addr, &getcap);
}

/*******************************************************************************
**
** Function         AVDT_GetAllCapReq
**
** Description      This function initiates a connection to the AVDTP service
**                  on the peer device, if not already present, and gets the
**                  capabilities of a stream endpoint on the peer device.
**                  This function can be called at any time regardless of
**                  whether there is an AVDTP connection to the peer device.
**
**                  When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
**                  sent to the application via its callback function.  The
**                  application must not call AVDT_GetCapReq() or
**                  AVDT_DiscoverReq() again until the procedure is complete.
**
**                  The memory pointed to by p_cfg is allocated by the
**                  application.  This memory is written to by AVDTP as part
**                  of the get capabilities procedure.  This memory must
**                  remain accessible until the application receives
**                  the AVDT_GETCAP_CFM_EVT.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_GetAllCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback)
{
    tAVDT_CCB_API_GETCAP    getcap;

    BTTRC_AVDT_API1(AVDT_TRACE_API_GET_ALLCAP_REQ, BTTRC_PARAM_UINT8, seid);

    getcap.single.seid = seid;
    getcap.single.sig_id = AVDT_SIG_GET_ALLCAP;
    getcap.p_cfg = p_cfg;
    getcap.p_cback = p_cback;
    return avdt_get_cap_req (bd_addr, &getcap);
}

/*******************************************************************************
**
** Function         AVDT_DelayReport
**
** Description      This functions sends a Delay Report to the peer device
**                  that is associated with a particular SEID.
**                  This function is called by SNK device.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_DelayReport(UINT8 handle, UINT8 seid, UINT16 delay)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_SCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_DELAY_REPORT);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    else
    /* send event to scb */
    {
        evt.apidelay.hdr.seid   = seid;
        evt.apidelay.delay      = delay;
        avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt);
    }

    return result;
}

/*******************************************************************************
**
** Function         AVDT_OpenReq
**
** Description      This function initiates a connection to the AVDTP service
**                  on the peer device, if not already present, and connects
**                  to a stream endpoint on a peer device.  When the connection
**                  is completed, an AVDT_OPEN_CFM_EVT is sent to the
**                  application via the control callback function for this handle.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_OpenReq(UINT8 handle, BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg)
{
    tAVDT_CCB       *p_ccb = NULL;
    tAVDT_SCB       *p_scb = NULL;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_SCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_OPEN_REQ);


    /* verify SEID */
    if ((seid < AVDT_SEID_MIN) || (seid > AVDT_SEID_MAX))
    {
        result = AVDT_BAD_PARAMS;
    }
    /* map handle to scb */
    else if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* find channel control block for this bd addr; if none, allocate one */
    else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
    {
        if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
        {
            /* could not allocate channel control block */
            result = AVDT_NO_RESOURCES;
        }
    }

    /* send event to scb */
    if (result == AVDT_SUCCESS)
    {
        evt.msg.config_cmd.hdr.seid = seid;
        evt.msg.config_cmd.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
        evt.msg.config_cmd.int_seid = handle;
        evt.msg.config_cmd.p_cfg = p_cfg;
        avdt_scb_event(p_scb, AVDT_SCB_API_SETCONFIG_REQ_EVT, &evt);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_ConfigRsp
**
** Description      Respond to a configure request from the peer device.  This
**                  function must be called if the application receives an
**                  AVDT_CONFIG_IND_EVT through its control callback.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_ConfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, UINT8 category)
{
    tAVDT_SCB       *p_scb;
    tAVDT_SCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;
    UINT8           event_code;

    BTTRC_AVDT_API0(AVDT_TRACE_API_CONFIG_RSP);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* handle special case when this function is called but peer has not send
    ** a configuration cmd; ignore and return error result
    */
    else if (!p_scb->in_use)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* send event to scb */
    else
    {
        evt.msg.hdr.err_code = error_code;
        evt.msg.hdr.err_param = category;
        evt.msg.hdr.label = label;
        if (error_code == 0)
        {
            event_code = AVDT_SCB_API_SETCONFIG_RSP_EVT;
        }
        else
        {
            event_code = AVDT_SCB_API_SETCONFIG_REJ_EVT;
        }
        avdt_scb_event(p_scb, event_code, &evt);
    }

    return result;
}

/*******************************************************************************
**
** Function         AVDT_StartReq
**
** Description      Start one or more stream endpoints.  This initiates the
**                  transfer of media packets for the streams.  All stream
**                  endpoints must previously be opened.  When the streams
**                  are started, an AVDT_START_CFM_EVT is sent to the
**                  application via the control callback function for each stream.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_StartReq(UINT8 *p_handles, UINT8 num_handles)
{
    tAVDT_SCB       *p_scb = NULL;
    tAVDT_CCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;
    int             i;

    BTTRC_AVDT_API0(AVDT_TRACE_API_START_REQ);

    if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS))
    {
        result = AVDT_BAD_PARAMS;
    }
    else
    {
        /* verify handles */
        for (i = 0; i < num_handles; i++)
        {
            if ((p_scb = avdt_scb_by_hdl(p_handles[i])) == NULL)
            {
                result = AVDT_BAD_HANDLE;
                break;
            }
        }
    }

    if (result == AVDT_SUCCESS)
    {
        if (p_scb->p_ccb == NULL)
        {
            result = AVDT_BAD_HANDLE;
        }
        else
        {
            /* send event to ccb */
            memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
            evt.msg.multi.num_seps = num_handles;
            avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_START_REQ_EVT, &evt);
        }
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_SuspendReq
**
** Description      Suspend one or more stream endpoints. This suspends the
**                  transfer of media packets for the streams.  All stream
**                  endpoints must previously be open and started.  When the
**                  streams are suspended, an AVDT_SUSPEND_CFM_EVT is sent to
**                  the application via the control callback function for
**                  each stream.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_SuspendReq(UINT8 *p_handles, UINT8 num_handles)
{
    tAVDT_SCB       *p_scb = NULL;
    tAVDT_CCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;
    int             i;

    BTTRC_AVDT_API0(AVDT_TRACE_API_SUSPEND_REQ);

    if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS))
    {
        result = AVDT_BAD_PARAMS;
    }
    else
    {
        /* verify handles */
        for (i = 0; i < num_handles; i++)
        {
            if ((p_scb = avdt_scb_by_hdl(p_handles[i])) == NULL)
            {
                result = AVDT_BAD_HANDLE;
                break;
            }
        }
    }

    if (result == AVDT_SUCCESS)
    {
        if (p_scb->p_ccb == NULL)
        {
            result = AVDT_BAD_HANDLE;
        }
        else
        {
            /* send event to ccb */
            memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
            evt.msg.multi.num_seps = num_handles;
            avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_SUSPEND_REQ_EVT, &evt);
        }
    }

    return result;
}

/*******************************************************************************
**
** Function         AVDT_CloseReq
**
** Description      Close a stream endpoint.  This stops the transfer of media
**                  packets and closes the transport channel associated with
**                  this stream endpoint.  When the stream is closed, an
**                  AVDT_CLOSE_CFM_EVT is sent to the application via the
**                  control callback function for this handle.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_CloseReq(UINT8 handle)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_SUCCESS;

    BTTRC_AVDT_API0(AVDT_TRACE_API_CLOSE_REQ);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    else
    /* send event to scb */
    {
        avdt_scb_event(p_scb, AVDT_SCB_API_CLOSE_REQ_EVT, NULL);
    }

    return result;
}

/*******************************************************************************
**
** Function         AVDT_ReconfigReq
**
** Description      Reconfigure a stream endpoint.  This allows the application
**                  to change the codec or content protection capabilities of
**                  a stream endpoint after it has been opened.  This function
**                  can only be called if the stream is opened but not started
**                  or if the stream has been suspended.  When the procedure
**                  is completed, an AVDT_RECONFIG_CFM_EVT is sent to the
**                  application via the control callback function for this handle.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_ReconfigReq(UINT8 handle, tAVDT_CFG *p_cfg)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_SCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_RECONFIG_REQ);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* send event to scb */
    else
    {
        /* force psc_mask to zero */
        p_cfg->psc_mask = 0;

        evt.msg.reconfig_cmd.p_cfg = p_cfg;
        avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_REQ_EVT, &evt);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_ReconfigRsp
**
** Description      Respond to a reconfigure request from the peer device.
**                  This function must be called if the application receives
**                  an AVDT_RECONFIG_IND_EVT through its control callback.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_ReconfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, UINT8 category)
{
    tAVDT_SCB       *p_scb;
    tAVDT_SCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;

    BTTRC_AVDT_API0(AVDT_TRACE_API_RECONFIG_RSP);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* send event to scb */
    else
    {
        evt.msg.hdr.err_code = error_code;
        evt.msg.hdr.err_param = category;
        evt.msg.hdr.label = label;
        avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_RSP_EVT, &evt);
    }

    return result;
}

/*******************************************************************************
**
** Function         AVDT_SecurityReq
**
** Description      Send a security request to the peer device.  When the
**                  security procedure is completed, an AVDT_SECURITY_CFM_EVT
**                  is sent to the application via the control callback function
**                  for this handle.  (Please note that AVDTP security procedures
**                  are unrelated to Bluetooth link level security.)
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_SecurityReq(UINT8 handle, UINT8 *p_data, UINT16 len)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_SCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_SECURITY_REQ);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* send event to scb */
    else
    {
        evt.msg.security_rsp.p_data = p_data;
        evt.msg.security_rsp.len = len;
        avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_REQ_EVT, &evt);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_SecurityRsp
**
** Description      Respond to a security request from the peer device.
**                  This function must be called if the application receives
**                  an AVDT_SECURITY_IND_EVT through its control callback.
**                  (Please note that AVDTP security procedures are unrelated
**                  to Bluetooth link level security.)
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_SecurityRsp(UINT8 handle, UINT8 label, UINT8 error_code,
                        UINT8 *p_data, UINT16 len)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_SCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_SECURITY_RSP);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    /* send event to scb */
    else
    {
        evt.msg.security_rsp.hdr.err_code = error_code;
        evt.msg.security_rsp.hdr.label = label;
        evt.msg.security_rsp.p_data = p_data;
        evt.msg.security_rsp.len = len;
        avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_RSP_EVT, &evt);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_WriteReqOpt
**
** Description      Send a media packet to the peer device.  The stream must
**                  be started before this function is called.  Also, this
**                  function can only be called if the stream is a SRC.
**
**                  When AVDTP has sent the media packet and is ready for the
**                  next packet, an AVDT_WRITE_CFM_EVT is sent to the
**                  application via the control callback.  The application must
**                  wait for the AVDT_WRITE_CFM_EVT before it makes the next
**                  call to AVDT_WriteReq().  If the applications calls
**                  AVDT_WriteReq() before it receives the event the packet
**                  will not be sent.  The application may make its first call
**                  to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
**                  or AVDT_START_IND_EVT.
**
**                  The application passes the packet using the BT_HDR structure.
**                  This structure is described in section 2.1.  The offset
**                  field must be equal to or greater than AVDT_MEDIA_OFFSET
**                  (if NO_RTP is specified, L2CAP_MIN_OFFSET can be used).
**                  This allows enough space in the buffer for the L2CAP and
**                  AVDTP headers.
**
**                  The memory pointed to by p_pkt must be a GKI buffer
**                  allocated by the application.  This buffer will be freed
**                  by the protocol stack; the application must not free
**                  this buffer.
**
**                  The opt parameter allows passing specific options like:
**                  - NO_RTP : do not add the RTP header to buffer
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_WriteReqOpt(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt, tAVDT_DATA_OPT_MASK opt)
{
    tAVDT_SCB       *p_scb;
    tAVDT_SCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;

    BTTRC_AVDT_API0(AVDT_TRACE_API_WRITE_REQ);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    else
    {
        evt.apiwrite.p_buf = p_pkt;
        evt.apiwrite.time_stamp = time_stamp;
        evt.apiwrite.m_pt = m_pt;
        evt.apiwrite.opt = opt;
#if AVDT_MULTIPLEXING == TRUE
        GKI_init_q (&evt.apiwrite.frag_q);
#endif
        avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
    }

    return result;
}

/*******************************************************************************
**
** Function         AVDT_WriteReq
**
** Description      Send a media packet to the peer device.  The stream must
**                  be started before this function is called.  Also, this
**                  function can only be called if the stream is a SRC.
**
**                  When AVDTP has sent the media packet and is ready for the
**                  next packet, an AVDT_WRITE_CFM_EVT is sent to the
**                  application via the control callback.  The application must
**                  wait for the AVDT_WRITE_CFM_EVT before it makes the next
**                  call to AVDT_WriteReq().  If the applications calls
**                  AVDT_WriteReq() before it receives the event the packet
**                  will not be sent.  The application may make its first call
**                  to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
**                  or AVDT_START_IND_EVT.
**
**                  The application passes the packet using the BT_HDR structure.
**                  This structure is described in section 2.1.  The offset
**                  field must be equal to or greater than AVDT_MEDIA_OFFSET.
**                  This allows enough space in the buffer for the L2CAP and
**                  AVDTP headers.
**
**                  The memory pointed to by p_pkt must be a GKI buffer
**                  allocated by the application.  This buffer will be freed
**                  by the protocol stack; the application must not free
**                  this buffer.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_WriteReq(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt)
{
    return AVDT_WriteReqOpt(handle, p_pkt, time_stamp, m_pt, AVDT_DATA_OPT_NONE);
}

/*******************************************************************************
**
** Function         AVDT_ConnectReq
**
** Description      This function initiates an AVDTP signaling connection
**                  to the peer device.  When the connection is completed, an
**                  AVDT_CONNECT_IND_EVT is sent to the application via its
**                  control callback function.  If the connection attempt fails
**                  an AVDT_DISCONNECT_IND_EVT is sent.  The security mask
**                  parameter overrides the outgoing security mask set in
**                  AVDT_Register().
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_ConnectReq(BD_ADDR bd_addr, UINT8 sec_mask, tAVDT_CTRL_CBACK *p_cback)
{
    tAVDT_CCB       *p_ccb = NULL;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_CCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_CONNECT_REQ);

    /* find channel control block for this bd addr; if none, allocate one */
    if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
    {
        if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL)
        {
            /* could not allocate channel control block */
            result = AVDT_NO_RESOURCES;
        }
    }
    else if (p_ccb->ll_opened == FALSE)
    {
        AVDT_TRACE_WARNING0("AVDT_ConnectReq: CCB LL is in the middle of opening");

        /* ccb was already allocated for the incoming signalling. */
        result = AVDT_BUSY;
    }

    if (result == AVDT_SUCCESS)
    {
        /* send event to ccb */
        evt.connect.p_cback = p_cback;
        evt.connect.sec_mask = sec_mask;
        avdt_ccb_event(p_ccb, AVDT_CCB_API_CONNECT_REQ_EVT, &evt);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_DisconnectReq
**
** Description      This function disconnect an AVDTP signaling connection
**                  to the peer device.  When disconnected an
**                  AVDT_DISCONNECT_IND_EVT is sent to the application via its
**                  control callback function.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK *p_cback)
{
    tAVDT_CCB       *p_ccb = NULL;
    UINT16          result = AVDT_SUCCESS;
    tAVDT_CCB_EVT   evt;

    BTTRC_AVDT_API0(AVDT_TRACE_API_DISCONNECT_REQ);


    /* find channel control block for this bd addr; if none, error */
    if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL)
    {
        result = AVDT_BAD_PARAMS;
    }

    if (result == AVDT_SUCCESS)
    {
        /* send event to ccb */
        evt.disconnect.p_cback = p_cback;
        avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt);
    }
    return result;
}

/*******************************************************************************
**
** Function         AVDT_GetL2CapChannel
**
** Description      Get the L2CAP CID used by the handle.
**
** Returns          CID if successful, otherwise 0.
**
*******************************************************************************/
UINT16 AVDT_GetL2CapChannel(UINT8 handle)
{
    tAVDT_SCB       *p_scb;
    tAVDT_CCB       *p_ccb;
    UINT8           tcid;
    UINT16          lcid = 0;

    /* map handle to scb */
    if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
     && ((p_ccb = p_scb->p_ccb) != NULL))
    {
        /* get tcid from type, scb */
        tcid = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);

        lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
    }

    BTTRC_AVDT_API1(AVDT_TRACE_API_GET_L2CAP_CHAN, BTTRC_PARAM_UINT16, lcid);

    return (lcid);
}

/*******************************************************************************
**
** Function         AVDT_GetSignalChannel
**
** Description      Get the L2CAP CID used by the signal channel of the given handle.
**
** Returns          CID if successful, otherwise 0.
**
*******************************************************************************/
UINT16 AVDT_GetSignalChannel(UINT8 handle, BD_ADDR bd_addr)
{
    tAVDT_SCB       *p_scb;
    tAVDT_CCB       *p_ccb;
    UINT8           tcid = 0; /* tcid is always 0 for signal channel */
    UINT16          lcid = 0;

    /* map handle to scb */
    if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
     && ((p_ccb = p_scb->p_ccb) != NULL))
    {
        lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
    }
    else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) != NULL)
    {
        lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
    }

    BTTRC_AVDT_API1(AVDT_TRACE_API_GET_SIGNAL_CHAN, BTTRC_PARAM_UINT16, lcid);

    return (lcid);
}

#if AVDT_MULTIPLEXING == TRUE
/*******************************************************************************
**
** Function         AVDT_WriteDataReq
**
** Description      Send a media packet to the peer device.  The stream must
**                  be started before this function is called.  Also, this
**                  function can only be called if the stream is a SRC.
**
**                  When AVDTP has sent the media packet and is ready for the
**                  next packet, an AVDT_WRITE_CFM_EVT is sent to the
**                  application via the control callback.  The application must
**                  wait for the AVDT_WRITE_CFM_EVT before it makes the next
**                  call to AVDT_WriteDataReq().  If the applications calls
**                  AVDT_WriteDataReq() before it receives the event the packet
**                  will not be sent.  The application may make its first call
**                  to AVDT_WriteDataReq() after it receives an
**                  AVDT_START_CFM_EVT or AVDT_START_IND_EVT.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
AVDT_API extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len,
                                     UINT32 time_stamp, UINT8 m_pt, UINT8 marker)
{

    tAVDT_SCB       *p_scb;
    tAVDT_SCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;

    BTTRC_AVDT_API1(AVDT_TRACE_API_WRITE_DATA_REQ, BTTRC_PARAM_UINT32, data_len);

    do
    {
        /* check length of media frame */
        if(data_len > AVDT_MAX_MEDIA_SIZE)
        {
            result = AVDT_BAD_PARAMS;
            break;
        }
        /* map handle to scb */
        if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
        {
            result = AVDT_BAD_HANDLE;
            break;
        }
        AVDT_TRACE_WARNING1("mux_tsid_media:%d", p_scb->curr_cfg.mux_tsid_media);

        if (p_scb->p_pkt != NULL
            || p_scb->p_ccb == NULL
            || !GKI_queue_is_empty(&p_scb->frag_q)
            || p_scb->frag_off != 0
            || p_scb->curr_cfg.mux_tsid_media == 0)
        {
            result = AVDT_ERR_BAD_STATE;
            AVDT_TRACE_WARNING4("p_scb->p_pkt=%x, p_scb->p_ccb=%x, IsQueueEmpty=%x, p_scb->frag_off=%x",
                p_scb->p_pkt, p_scb->p_ccb, GKI_queue_is_empty(&p_scb->frag_q), p_scb->frag_off);
            break;
        }
        evt.apiwrite.p_buf = 0; /* it will indicate using of fragments queue frag_q */
        /* create queue of media fragments */
        GKI_init_q (&evt.apiwrite.frag_q);

        /* compose fragments from media payload and put fragments into gueue */
        avdt_scb_queue_frags(p_scb, &p_data, &data_len, &evt.apiwrite.frag_q);

        if(GKI_queue_is_empty(&evt.apiwrite.frag_q))
        {
            AVDT_TRACE_WARNING0("AVDT_WriteDataReq out of GKI buffers");
            result = AVDT_ERR_RESOURCE;
            break;
        }
        evt.apiwrite.data_len = data_len;
        evt.apiwrite.p_data = p_data;

        /* process the fragments queue */
        evt.apiwrite.time_stamp = time_stamp;
        evt.apiwrite.m_pt = m_pt | (marker<<7);
        avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
    } while (0);

#if (BT_USE_TRACES == TRUE)
    if(result != AVDT_SUCCESS)
    {
        AVDT_TRACE_WARNING1("*** AVDT_WriteDataReq failed result=%d",result);
    }
#endif
    return result;
}
#endif

#if AVDT_MULTIPLEXING == TRUE
/*******************************************************************************
**
** Function         AVDT_SetMediaBuf
**
** Description      Assigns buffer for media packets or forbids using of assigned
**                  buffer if argument p_buf is NULL. This function can only
**                  be called if the stream is a SNK.
**
**                  AVDTP uses this buffer to reassemble fragmented media packets.
**                  When AVDTP receives a complete media packet, it calls the
**                  p_media_cback assigned by AVDT_CreateStream().
**                  This function can be called during callback to assign a
**                  different buffer for next media packet or can leave the current
**                  buffer for next packet.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
AVDT_API extern UINT16 AVDT_SetMediaBuf(UINT8 handle, UINT8 *p_buf, UINT32 buf_len)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_SUCCESS;

    BTTRC_AVDT_API0(AVDT_TRACE_API_SET_MEDIABUF);

    /* map handle to scb */
    if ((p_scb = avdt_scb_by_hdl(handle)) == NULL)
    {
        result = AVDT_BAD_HANDLE;
    }
    else
    {
        if(p_buf && p_scb->cs.p_media_cback == NULL)
            result = AVDT_NO_RESOURCES;
        else
        {
            p_scb->p_media_buf = p_buf;
            p_scb->media_buf_len = buf_len;
        }
    }

    return result;
}
#endif

#if AVDT_REPORTING == TRUE
/*******************************************************************************
**
** Function         AVDT_SendReport
**
** Description
**
**
**
** Returns
**
*******************************************************************************/
UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type,
                       tAVDT_REPORT_DATA *p_data)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_BAD_PARAMS;
    BT_HDR          *p_pkt;
    tAVDT_TC_TBL    *p_tbl;
    UINT8           *p, *plen, *pm1, *p_end;
#if AVDT_MULTIPLEXING == TRUE
    UINT8           *p_al=NULL, u;
#endif
    UINT32  ssrc;
    UINT16  len;

    BTTRC_AVDT_API0(AVDT_TRACE_API_SEND_REPORT);

    /* map handle to scb && verify parameters */
    if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
     && (p_scb->p_ccb != NULL)
     && (((type == AVDT_RTCP_PT_SR) && (p_scb->cs.tsep == AVDT_TSEP_SRC)) ||
        ((type == AVDT_RTCP_PT_RR) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) ||
        (type == AVDT_RTCP_PT_SDES)) )
    {
        result = AVDT_NO_RESOURCES;

        /* build SR - assume fit in one packet */
        p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb);
        if((p_tbl->state == AVDT_AD_ST_OPEN) &&
            (p_pkt = (BT_HDR *)GKI_getbuf(p_tbl->peer_mtu)) != NULL)
        {
            p_pkt->offset = L2CAP_MIN_OFFSET;
            p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
#if AVDT_MULTIPLEXING == TRUE
            if(p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX)
            {
                /* Adaptation Layer header later */
                p_al = p;
                p += 2;
            }
#endif
            pm1 = p;
            *p++ = AVDT_MEDIA_OCTET1 | 1;
            *p++ = type;
            /* save the location for length */
            plen = p;
            p+= 2;
            ssrc = avdt_scb_gen_ssrc(p_scb);
            UINT32_TO_BE_STREAM(p, ssrc);

            switch(type)
            {
            case AVDT_RTCP_PT_SR:   /* Sender Report */
                *pm1 = AVDT_MEDIA_OCTET1;
                UINT32_TO_BE_STREAM(p, p_data->sr.ntp_sec);
                UINT32_TO_BE_STREAM(p, p_data->sr.ntp_frac);
                UINT32_TO_BE_STREAM(p, p_data->sr.rtp_time);
                UINT32_TO_BE_STREAM(p, p_data->sr.pkt_count);
                UINT32_TO_BE_STREAM(p, p_data->sr.octet_count);
                break;

            case AVDT_RTCP_PT_RR:   /* Receiver Report */
                *p++ = p_data->rr.frag_lost;
                AVDT_TRACE_API1("packet_lost: %d", p_data->rr.packet_lost);
                p_data->rr.packet_lost &= 0xFFFFFF;
                AVDT_TRACE_API1("packet_lost: %d", p_data->rr.packet_lost);
                UINT24_TO_BE_STREAM(p, p_data->rr.packet_lost);
                UINT32_TO_BE_STREAM(p, p_data->rr.seq_num_rcvd);
                UINT32_TO_BE_STREAM(p, p_data->rr.jitter);
                UINT32_TO_BE_STREAM(p, p_data->rr.lsr);
                UINT32_TO_BE_STREAM(p, p_data->rr.dlsr);
                break;

            case AVDT_RTCP_PT_SDES: /* Source Description */
                *p++ = AVDT_RTCP_SDES_CNAME;
                len = strlen((char *)p_data->cname);
                if(len > AVDT_MAX_CNAME_SIZE)
                    len = AVDT_MAX_CNAME_SIZE;
                *p++ = (UINT8)len;
                BCM_STRNCPY_S((char *)p, len+1, (char *)p_data->cname, len+1);
                p += len;
                break;
            }
            p_end = p;
            len = p - pm1 - 1;
            UINT16_TO_BE_STREAM(plen, len);

#if AVDT_MULTIPLEXING == TRUE
            if(p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX)
            {
                /* Adaptation Layer header */
                p = p_al;
                len++;
                UINT16_TO_BE_STREAM(p_al, len );
                /* TSID, no-fragment bit and coding of length(9-bit length field) */
                u = *p;
                *p = (p_scb->curr_cfg.mux_tsid_report<<3) | AVDT_ALH_LCODE_9BITM0;
                if(u)
                    *p |= AVDT_ALH_LCODE_9BITM1;
            }
#endif

            /* set the actual payload length */
            p_pkt->len = p_end - p;
            /* send the packet */
            if(L2CAP_DW_FAILED != avdt_ad_write_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, p_pkt))
                result = AVDT_SUCCESS;
        }
    }

    return result;
}
#endif

/******************************************************************************
**
** Function         AVDT_SetTraceLevel
**
** Description      Sets the trace level for AVDT. If 0xff is passed, the
**                  current trace level is returned.
**
**                  Input Parameters:
**                      new_level:  The level to set the AVDT tracing to:
**                      0xff-returns the current setting.
**                      0-turns off tracing.
**                      >= 1-Errors.
**                      >= 2-Warnings.
**                      >= 3-APIs.
**                      >= 4-Events.
**                      >= 5-Debug.
**
** Returns          The new trace level or current trace level if
**                  the input parameter is 0xff.
**
******************************************************************************/
UINT8 AVDT_SetTraceLevel (UINT8 new_level)
{
    if (new_level != 0xFF)
        avdt_cb.trace_level = new_level;

    return (avdt_cb.trace_level);
}

