Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b360fd8 authored by Chris Elliott's avatar Chris Elliott Committed by Android (Google) Code Review
Browse files

Merge "A2DP SRC offload support" into cw-e-dev

parents da29cb5a 05bb7152
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -48,12 +48,14 @@ typedef enum {
    A2DP_CTRL_CMD_STOP,
    A2DP_CTRL_CMD_SUSPEND,
    A2DP_CTRL_GET_AUDIO_CONFIG,
    A2DP_CTRL_CMD_OFFLOAD_START,
} tA2DP_CTRL_CMD;

typedef enum {
    A2DP_CTRL_ACK_SUCCESS,
    A2DP_CTRL_ACK_FAILURE,
    A2DP_CTRL_ACK_INCALL_FAILURE /* Failure when in Call*/
    A2DP_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
    A2DP_CTRL_ACK_UNSUPPORTED
} tA2DP_CTRL_ACK;


+115 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@
#include "utl.h"
#include "l2c_api.h"
#include "l2cdefs.h"
#include "bt_utils.h"
#include "vendor.h"

#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
#include "bta_ar_api.h"
#endif
@@ -60,6 +63,9 @@
#define BTA_AV_RECONFIG_RETRY       6
#endif

/* ACL quota we are letting FW use for A2DP Offload Tx. */
#define BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA      4

static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);

/* state machine states */
@@ -140,6 +146,8 @@ const tBTA_AV_SACT bta_av_a2d_action[] =
    bta_av_role_res,        /* BTA_AV_ROLE_RES */
    bta_av_delay_co,        /* BTA_AV_DELAY_CO */
    bta_av_open_at_inc,     /* BTA_AV_OPEN_AT_INC */
    bta_av_offload_req,     /* BTA_AV_OFFLOAD_REQ */
    bta_av_offload_rsp,     /* BTA_AV_OFFLOAD_RSP */
    NULL
};

@@ -1076,6 +1084,14 @@ void bta_av_cleanup(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
    p_scb->wait = 0;
    p_scb->num_disc_snks = 0;
    bta_sys_stop_timer(&p_scb->timer);

    vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
    if (p_scb->offload_start_pending) {
        tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
        (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
    }
    p_scb->offload_start_pending = FALSE;

    if (p_scb->deregistring)
    {
        /* remove stream */
@@ -1381,6 +1397,7 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
    bta_av_conn_chg((tBTA_AV_DATA *) &msg);
    /* set the congestion flag, so AV would not send media packets by accident */
    p_scb->cong = TRUE;
    p_scb->offload_start_pending = FALSE;


    p_scb->stream_mtu = p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
@@ -2061,6 +2078,13 @@ void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)

    if (p_scb->co_started)
    {
        vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
        if (p_scb->offload_start_pending) {
            tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
            (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
        }
        p_scb->offload_start_pending = FALSE;

        bta_av_stream_chg(p_scb, FALSE);
        p_scb->co_started = FALSE;

@@ -2653,6 +2677,13 @@ void bta_av_suspend_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
    /* in case that we received suspend_ind, we may need to call co_stop here */
    if(p_scb->co_started)
    {
        vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
        if (p_scb->offload_start_pending) {
            tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
            (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
        }
        p_scb->offload_start_pending = FALSE;

        bta_av_stream_chg(p_scb, FALSE);

        {
@@ -3101,4 +3132,88 @@ void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
    }
}

/*******************************************************************************
**
** Function         bta_av_offload_req
**
** Description      This function is called if application requests offload of
**                  a2dp audio.
**
** Returns          void
**
*******************************************************************************/
void bta_av_offload_req(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
{
    tBTA_AV_STATUS status = BTA_AV_FAIL_RESOURCES;
    UINT16 mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);

    APPL_TRACE_DEBUG("%s stream %s, audio channels open %d", __func__,
                     p_scb->started ? "STARTED" : "STOPPED", bta_av_cb.audio_open_cnt);

    /* Check if stream has already been started. */
    /* Support offload if only one audio source stream is open. */
    if (p_scb->started != TRUE) {
        status = BTA_AV_FAIL_STREAM;

    } else if (bta_av_cb.audio_open_cnt == 1 &&
               p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC &&
               p_scb->chnl == BTA_AV_CHNL_AUDIO) {

        bt_vendor_op_a2dp_offload_t a2dp_offload_start;

        if (L2CA_GetConnectionConfig(p_scb->l2c_cid, &a2dp_offload_start.acl_data_size,
                                     &a2dp_offload_start.remote_cid, &a2dp_offload_start.lm_handle)) {

            APPL_TRACE_DEBUG("%s l2cmtu %d lcid 0x%02X rcid 0x%02X lm_handle 0x%02X", __func__,
                             a2dp_offload_start.acl_data_size, p_scb->l2c_cid,
                             a2dp_offload_start.remote_cid, a2dp_offload_start.lm_handle);

            a2dp_offload_start.bta_av_handle = p_scb->hndl;
            a2dp_offload_start.xmit_quota = BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA;
            a2dp_offload_start.stream_mtu = (mtu < p_scb->stream_mtu) ? mtu : p_scb->stream_mtu;
            a2dp_offload_start.local_cid = p_scb->l2c_cid;
            a2dp_offload_start.is_flushable = TRUE;
            a2dp_offload_start.stream_source = ((UINT32)(p_scb->cfg.codec_info[1] | p_scb->cfg.codec_info[2]));

            memcpy(a2dp_offload_start.codec_info, p_scb->cfg.codec_info,
                   sizeof(a2dp_offload_start.codec_info));

            if (!vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_START, &a2dp_offload_start)) {
                status = BTA_AV_SUCCESS;
                p_scb->offload_start_pending = TRUE;
            }
        }
    }

    if (status != BTA_AV_SUCCESS)
        (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
}

/*******************************************************************************
**
** Function         bta_av_offload_rsp
**
** Description      This function is called when the vendor lib responds to
**                  BT_VND_OP_A2DP_OFFLOAD_START.
**
** Returns          void
**
*******************************************************************************/
void bta_av_offload_rsp(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
{
    tBTA_AV_STATUS status = p_data->api_status_rsp.status;

    APPL_TRACE_DEBUG("%s stream %s status %s", __func__,
                     p_scb->started ? "STARTED" : "STOPPED",
                     status ? "FAIL" : "SUCCESS");

    /* Check if stream has already been started. */
    if (status == BTA_AV_SUCCESS && p_scb->started != TRUE) {
        status = BTA_AV_FAIL_STREAM;
    }

    p_scb->offload_start_pending = FALSE;
    (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
}

#endif /* BTA_AV_INCLUDED */
+41 −0
Original line number Diff line number Diff line
@@ -244,6 +244,47 @@ void BTA_AvStart(void)
    }
}

/*******************************************************************************
**
** Function         BTA_AvOffloadStart
**
** Description      Start a2dp audio offloading.
**
** Returns          void
**
*******************************************************************************/
void BTA_AvOffloadStart(tBTA_AV_HNDL hndl)
{
    BT_HDR  *p_buf;
    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_buf->event = BTA_AV_API_OFFLOAD_START_EVT;
        p_buf->layer_specific = hndl;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AvOffloadStartRsp
**
** Description      Response from vendor lib for A2DP Offload Start request.
**
** Returns          void
**
*******************************************************************************/
void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status)
{
    tBTA_AV_API_STATUS_RSP *p_buf;
    if ((p_buf = (tBTA_AV_API_STATUS_RSP *) GKI_getbuf(sizeof(tBTA_AV_API_STATUS_RSP))) != NULL)
    {
        p_buf->hdr.event = BTA_AV_API_OFFLOAD_START_RSP_EVT;
        p_buf->hdr.layer_specific = hndl;
        p_buf->status = status;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AvEnable_Sink
+15 −0
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ enum
    BTA_AV_ROLE_CHANGE_EVT,
    BTA_AV_AVDT_DELAY_RPT_EVT,
    BTA_AV_ACP_CONNECT_EVT,
    BTA_AV_API_OFFLOAD_START_EVT,
    BTA_AV_API_OFFLOAD_START_RSP_EVT,

    /* these events are handled outside of the state machine */
    BTA_AV_API_ENABLE_EVT,
@@ -379,6 +381,14 @@ typedef struct
    UINT16              avdt_version;   /* AVDTP protocol version */
} tBTA_AV_SDP_RES;

/* data type for BTA_AV_API_OFFLOAD_RSP_EVT */
typedef struct
{
    BT_HDR              hdr;
    tBTA_AV_STATUS      status;
} tBTA_AV_API_STATUS_RSP;


/* type for SEP control block */
typedef struct
{
@@ -422,6 +432,7 @@ typedef union
    tBTA_AV_ROLE_RES        role_res;
    tBTA_AV_SDP_RES         sdp_res;
    tBTA_AV_API_META_RSP    api_meta_rsp;
    tBTA_AV_API_STATUS_RSP  api_status_rsp;
} tBTA_AV_DATA;

typedef void (tBTA_AV_VDP_DATA_ACT)(void *p_scb);
@@ -515,6 +526,7 @@ typedef struct
    UINT8               q_tag;          /* identify the associated q_info union member */
    BOOLEAN             no_rtp_hdr;     /* TRUE if add no RTP header*/
    UINT16              uuid_int;       /*intended UUID of Initiator to connect to */
    BOOLEAN             offload_start_pending;
} tBTA_AV_SCB;

#define BTA_AV_RC_ROLE_MASK     0x10
@@ -723,6 +735,9 @@ extern void bta_av_switch_role (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_delay_co (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_offload_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_offload_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);


/* ssm action functions - vdp specific */
extern void bta_av_do_disc_vdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
+20 −6
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@ enum
    BTA_AV_ROLE_RES,
    BTA_AV_DELAY_CO,
    BTA_AV_OPEN_AT_INC,
    BTA_AV_OFFLOAD_REQ,
    BTA_AV_OFFLOAD_RSP,
    BTA_AV_NUM_SACTIONS
};

@@ -145,7 +147,9 @@ static const UINT8 bta_av_sst_init[][BTA_AV_NUM_COLS] =
/* AVDT_DISCONNECT_EVT */   {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* AVDT_DELAY_RPT_EVT */    {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST }
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_INIT_SST }
};

/* state table for incoming state */
@@ -185,7 +189,9 @@ static const UINT8 bta_av_sst_incoming[][BTA_AV_NUM_COLS] =
/* AVDT_DISCONNECT_EVT */   {BTA_AV_CCO_CLOSE,      BTA_AV_CLEANUP,        BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
/* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST }
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST }
};

/* state table for opening state */
@@ -225,7 +231,9 @@ static const UINT8 bta_av_sst_opening[][BTA_AV_NUM_COLS] =
/* AVDT_DISCONNECT_EVT */   {BTA_AV_CONN_FAILED,    BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/        {BTA_AV_ROLE_RES,       BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
/* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPENING_SST }
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_OPENING_SST }
};

/* state table for open state */
@@ -265,7 +273,9 @@ static const UINT8 bta_av_sst_open[][BTA_AV_NUM_COLS] =
/* AVDT_DISCONNECT_EVT */   {BTA_AV_STR_CLOSED,     BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/        {BTA_AV_ROLE_RES,       BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
/* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPEN_SST }
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_OPEN_SST }
};

/* state table for reconfig state */
@@ -305,7 +315,9 @@ static const UINT8 bta_av_sst_rcfg[][BTA_AV_NUM_COLS] =
/* AVDT_DISCONNECT_EVT */   {BTA_AV_RCFG_DISCNTD,   BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
/* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
/* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_RCFG_SST }
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_RCFG_SST }
};

/* state table for closing state */
@@ -345,7 +357,9 @@ static const UINT8 bta_av_sst_closing[][BTA_AV_NUM_COLS] =
/* AVDT_DISCONNECT_EVT */   {BTA_AV_STR_CLOSED,     BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
/* AVDT_DELAY_RPT_EVT */    {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST }
/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST }
};

/* type for state table */
Loading