/*******************************************************************************
**
** Function         bta_av_sm_execute
**
** Description      State machine event handling function for AV
**
**
** Returns          void
**
*******************************************************************************/
void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data)
{
    tBTA_AV_ST_TBL      state_table;
    UINT8               action;

#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
    APPL_TRACE_EVENT4("AV event=0x%x(%s) state=%d(%s)",
        event, bta_av_evt_code(event), p_cb->state, bta_av_st_code(p_cb->state));
#else
    APPL_TRACE_EVENT2("AV event=0x%x state=%d", event, p_cb->state);
#endif

    /* look up the state table for the current state */
    state_table = bta_av_st_tbl[p_cb->state];

    event &= 0x00FF;

    /* set next state */
    p_cb->state = state_table[event][BTA_AV_NEXT_STATE];
    APPL_TRACE_EVENT1("next state=%d", p_cb->state);

    /* execute action functions */
    if ((action = state_table[event][BTA_AV_ACTION_COL]) != BTA_AV_IGNORE)
    {
        (*bta_av_action[action])(p_cb, p_data);
    }
}
/*******************************************************************************
**
** Function         bta_av_hdl_event
**
** Description      Advanced audio/video main event handling function.
**
**
** Returns          BOOLEAN
**
*******************************************************************************/
BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
{
    UINT16 event = p_msg->event;
    UINT16 first_event = BTA_AV_FIRST_NSM_EVT;

    if (event > BTA_AV_LAST_EVT)
    {
        return TRUE; /* to free p_msg */
    }

    if(event >= first_event)
    {
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
        APPL_TRACE_VERBOSE2("AV nsm event=0x%x(%s)", event, bta_av_evt_code(event));
#else
        APPL_TRACE_VERBOSE1("AV nsm event=0x%x", event);
#endif
        /* non state machine events */
        (*bta_av_nsm_act[event - BTA_AV_FIRST_NSM_EVT]) ((tBTA_AV_DATA *) p_msg);
#ifdef A2DP_SINK
        if (event == BTA_AV_CI_SNK_DATA_READY_EVT)
        {
            APPL_TRACE_DEBUG0("not to free p_msg, media task uses it directly to avoid memory copy");
            return FALSE;
        }
#endif
    }
    else if (event >= BTA_AV_FIRST_SM_EVT && event <= BTA_AV_LAST_SM_EVT)
    {
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
        APPL_TRACE_VERBOSE2("AV sm event=0x%x(%s)", event, bta_av_evt_code(event));
#else
        APPL_TRACE_VERBOSE1("AV sm event=0x%x", event);
#endif
        /* state machine events */
        bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA *) p_msg);
    }
    else
    {
        APPL_TRACE_VERBOSE1("handle=0x%x", p_msg->layer_specific);
        /* stream state machine events */
        bta_av_ssm_execute( bta_av_hndl_to_scb(p_msg->layer_specific),
                                p_msg->event, (tBTA_AV_DATA *) p_msg);
    }
    return TRUE;
}
/*******************************************************************************
**
** Function         bta_av_ssm_execute
**
** Description      Stream state machine event handling function for AV
**
**
** Returns          void
**
*******************************************************************************/
void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data)
{
    tBTA_AV_SST_TBL     state_table;
    UINT8               action;
    int                 i, xx;

    if(p_scb == NULL)
    {
        /* this stream is not registered */
        APPL_TRACE_EVENT("AV channel not registered");
        return;
    }

    /* In case incoming connection is for VDP, we need to swap scb.        */
    /* When ACP_CONNECT_EVT was received, we put first available scb to    */
    /* to Incoming state. Later, when STR_CONFIG_IND_EVT is coming, we     */
    /* know if it is A2DP or VDP.                                          */
    if ((p_scb->state == BTA_AV_INIT_SST) && (event == BTA_AV_STR_CONFIG_IND_EVT))
    {
        for (xx = 0; xx < BTA_AV_NUM_STRS; xx++)
        {
            if (bta_av_cb.p_scb[xx])
            {
                if (bta_av_cb.p_scb[xx]->state == BTA_AV_INCOMING_SST)
                {
                    bta_av_cb.p_scb[xx]->state = BTA_AV_INIT_SST;
                    bta_av_cb.p_scb[xx]->coll_mask = 0;
                    p_scb->state = BTA_AV_INCOMING_SST;
                    break;
                }
            }
        }
    }

if ((event != BTA_AV_STR_WRITE_CFM_EVT) && (event != BTA_AV_SRC_DATA_READY_EVT))
    {
        #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
            APPL_TRACE_IMP("AV Sevent(0x%x)=0x%x(%s) state=%d(%s)",
               p_scb->hndl, event, bta_av_evt_code(event), p_scb->state, bta_av_sst_code(p_scb->state));
        #else
            APPL_TRACE_IMP("AV Sevent=0x%x state=%d", event, p_scb->state);
        #endif
    }

    /* look up the state table for the current state */
    state_table = bta_av_sst_tbl[p_scb->state];

    event -= BTA_AV_FIRST_SSM_EVT;

    /* set next state */
    p_scb->state = state_table[event][BTA_AV_SNEXT_STATE];

    /* execute action functions */
    for(i=0; i< BTA_AV_SACTIONS; i++)
    {
        if ((action = state_table[event][i]) != BTA_AV_SIGNORE)
        {
            (*p_scb->p_act_tbl[action])(p_scb, p_data);
        }
        else
            break;
    }

}