diff options
author | Abhijit Adsule <abhijit@motorola.com> | 2015-05-19 02:44:26 -0500 |
---|---|---|
committer | Chris Elliott <chriselliott@google.com> | 2015-12-01 11:27:40 -0800 |
commit | 6ff83ab9dd38bdefc5d252325f0cfbd3f1754d78 (patch) | |
tree | 0b1a746ceca1947e9fcd1e272bbbe541470dccbb | |
parent | bedd6143818b91e47b44e4fe67835594d10b62e1 (diff) | |
download | android_system_bt-6ff83ab9dd38bdefc5d252325f0cfbd3f1754d78.tar.gz android_system_bt-6ff83ab9dd38bdefc5d252325f0cfbd3f1754d78.tar.bz2 android_system_bt-6ff83ab9dd38bdefc5d252325f0cfbd3f1754d78.zip |
A2DP SRC offload support
bluedroid changes to support A2DP SRC offload to BT FW.
add functionality to relay a2dp offload requests and responses
between AudioHAL & the BT vendor library.
Change-Id: Ie4e5992c48e95b0efb372a405e8537e4fd3ea071
Signed-off-by: Sridhar Vashist <svashist@motorola.com>
Conflicts:
audio_a2dp_hw/audio_a2dp_hw.h
bta/Android.mk
bta/av/bta_av_aact.c
btif/include/btif_media.h
btif/src/btif_av.c
btif/src/btif_media_task.c
hci/Android.mk
hci/src/vendor.c
include/bt_target.h
stack/include/l2c_api.h
-rw-r--r-- | audio_a2dp_hw/audio_a2dp_hw.h | 4 | ||||
-rw-r--r-- | bta/av/bta_av_aact.c | 115 | ||||
-rw-r--r-- | bta/av/bta_av_api.c | 41 | ||||
-rw-r--r-- | bta/av/bta_av_int.h | 15 | ||||
-rw-r--r-- | bta/av/bta_av_ssm.c | 26 | ||||
-rw-r--r-- | bta/include/bta_api.h | 1 | ||||
-rw-r--r-- | bta/include/bta_av_api.h | 32 | ||||
-rw-r--r-- | btif/include/btif_av.h | 1 | ||||
-rw-r--r-- | btif/include/btif_media.h | 2 | ||||
-rw-r--r-- | btif/src/btif_av.c | 31 | ||||
-rw-r--r-- | btif/src/btif_media_task.c | 46 | ||||
-rw-r--r-- | hci/Android.mk | 1 | ||||
-rw-r--r-- | hci/include/bt_vendor_lib.h | 48 | ||||
-rw-r--r-- | hci/include/vendor.h | 5 | ||||
-rw-r--r-- | hci/src/vendor.c | 17 | ||||
-rw-r--r-- | include/bt_target.h | 12 | ||||
-rw-r--r-- | stack/include/l2c_api.h | 12 | ||||
-rw-r--r-- | stack/include/uipc_msg.h | 568 | ||||
-rw-r--r-- | stack/l2cap/l2c_api.c | 31 |
19 files changed, 423 insertions, 585 deletions
diff --git a/audio_a2dp_hw/audio_a2dp_hw.h b/audio_a2dp_hw/audio_a2dp_hw.h index 1e9464c39..901fafb59 100644 --- a/audio_a2dp_hw/audio_a2dp_hw.h +++ b/audio_a2dp_hw/audio_a2dp_hw.h @@ -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; diff --git a/bta/av/bta_av_aact.c b/bta/av/bta_av_aact.c index 73fe92372..0748b987d 100644 --- a/bta/av/bta_av_aact.c +++ b/bta/av/bta_av_aact.c @@ -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 */ diff --git a/bta/av/bta_av_api.c b/bta/av/bta_av_api.c index ecc05e1bc..417e976c9 100644 --- a/bta/av/bta_av_api.c +++ b/bta/av/bta_av_api.c @@ -246,6 +246,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 ** ** Description Enable/Disable A2DP Sink.. diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h index 6764e941d..bc3240cb3 100644 --- a/bta/av/bta_av_int.h +++ b/bta/av/bta_av_int.h @@ -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); diff --git a/bta/av/bta_av_ssm.c b/bta/av/bta_av_ssm.c index 64ee42a41..495660390 100644 --- a/bta/av/bta_av_ssm.c +++ b/bta/av/bta_av_ssm.c @@ -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 */ diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h index 648d118a6..298bc94e4 100644 --- a/bta/include/bta_api.h +++ b/bta/include/bta_api.h @@ -28,7 +28,6 @@ #include "bt_target.h" #include "bt_types.h" #include "btm_api.h" -#include "uipc_msg.h" #if BLE_INCLUDED == TRUE #include "btm_ble_api.h" diff --git a/bta/include/bta_av_api.h b/bta/include/bta_av_api.h index e0e356f75..8b92d30d4 100644 --- a/bta/include/bta_av_api.h +++ b/bta/include/bta_av_api.h @@ -249,10 +249,11 @@ typedef UINT8 tBTA_AV_ERR; #define BTA_AV_META_MSG_EVT 17 /* metadata messages */ #define BTA_AV_REJECT_EVT 18 /* incoming connection rejected */ #define BTA_AV_RC_FEAT_EVT 19 /* remote control channel peer supported features update */ -#define BTA_AV_MEDIA_SINK_CFG_EVT 20 /* command to configure codec */ +#define BTA_AV_MEDIA_SINK_CFG_EVT 20 /* command to configure codec */ #define BTA_AV_MEDIA_DATA_EVT 21 /* sending data to Media Task */ +#define BTA_AV_OFFLOAD_START_RSP_EVT 22 /* a2dp offload start response */ /* Max BTA event */ -#define BTA_AV_MAX_EVT 22 +#define BTA_AV_MAX_EVT 23 typedef UINT8 tBTA_AV_EVT; @@ -448,6 +449,7 @@ typedef union tBTA_AV_META_MSG meta_msg; tBTA_AV_REJECT reject; tBTA_AV_RC_FEAT rc_feat; + tBTA_AV_STATUS status; } tBTA_AV; /* union of data associated with AV Media callback */ @@ -784,6 +786,32 @@ void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, *******************************************************************************/ void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt); +/******************************************************************************* +** +** Function BTA_AvOffloadStart +** +** Description Request Starting of A2DP Offload. +** This function is used to start A2DP offload if vendor lib has +** the feature enabled. +** +** Returns void +** +*******************************************************************************/ +void BTA_AvOffloadStart(tBTA_AV_HNDL hndl); + +/******************************************************************************* +** +** Function BTA_AvOffloadStartRsp +** +** Description Response from vendor library indicating response for +** OffloadStart. +** +** Returns void +** +*******************************************************************************/ +void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status); + + #ifdef __cplusplus } #endif diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h index cedc1b7fe..4b116eeb2 100644 --- a/btif/include/btif_av.h +++ b/btif/include/btif_av.h @@ -45,6 +45,7 @@ typedef enum { BTIF_AV_STOP_STREAM_REQ_EVT, BTIF_AV_SUSPEND_STREAM_REQ_EVT, BTIF_AV_SINK_CONFIG_REQ_EVT, + BTIF_AV_OFFLOAD_START_REQ_EVT, } btif_av_sm_event_t; diff --git a/btif/include/btif_media.h b/btif/include/btif_media.h index 2ec19cbdf..01fdf7372 100644 --- a/btif/include/btif_media.h +++ b/btif/include/btif_media.h @@ -274,6 +274,8 @@ void btif_a2dp_set_tx_flush(BOOLEAN enable); void btif_a2dp_set_rx_flush(BOOLEAN enable); void btif_media_check_iop_exceptions(UINT8 *peer_bda); void btif_reset_decoder(UINT8 *p_av); +void btif_a2dp_on_offload_started(tBTA_AV_STATUS status); + int btif_a2dp_get_track_frequency(UINT8 frequency); int btif_a2dp_get_track_channel_count(UINT8 channeltype); diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c index 5715748fc..0d87c5750 100644 --- a/btif/src/btif_av.c +++ b/btif/src/btif_av.c @@ -194,6 +194,7 @@ const char *dump_av_sm_event_name(btif_av_sm_event_t event) CASE_RETURN_STR(BTA_AV_META_MSG_EVT) CASE_RETURN_STR(BTA_AV_REJECT_EVT) CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT) + CASE_RETURN_STR(BTA_AV_OFFLOAD_START_RSP_EVT) CASE_RETURN_STR(BTIF_SM_ENTER_EVT) CASE_RETURN_STR(BTIF_SM_EXIT_EVT) CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT) @@ -202,6 +203,7 @@ const char *dump_av_sm_event_name(btif_av_sm_event_t event) CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT) CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT) CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT) + CASE_RETURN_STR(BTIF_AV_OFFLOAD_START_REQ_EVT) default: return "UNKNOWN_EVENT"; } } @@ -351,6 +353,11 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data) btif_rc_handler(event, p_data); break; + case BTIF_AV_OFFLOAD_START_REQ_EVT: + BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE"); + btif_a2dp_on_offload_started(BTA_AV_FAIL); + break; + default: BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__, dump_av_sm_event_name(event)); @@ -483,6 +490,11 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data break; } + case BTIF_AV_OFFLOAD_START_REQ_EVT: + btif_a2dp_on_offload_started(BTA_AV_FAIL); + BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING"); + break; + CHECK_RC_EVENT(event, p_data); default: @@ -557,6 +569,11 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data btif_rc_handler(event, (tBTA_AV*)p_data); break; + case BTIF_AV_OFFLOAD_START_REQ_EVT: + btif_a2dp_on_offload_started(BTA_AV_FAIL); + BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing"); + break; + default: BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__, dump_av_sm_event_name(event)); @@ -713,6 +730,11 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) btif_queue_advance(); break; + case BTIF_AV_OFFLOAD_START_REQ_EVT: + btif_a2dp_on_offload_started(BTA_AV_FAIL); + BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened"); + break; + CHECK_RC_EVENT(event, p_data); default: @@ -879,6 +901,15 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); break; + case BTIF_AV_OFFLOAD_START_REQ_EVT: + BTA_AvOffloadStart(btif_av_cb.bta_handle); + break; + + case BTA_AV_OFFLOAD_START_RSP_EVT: + + btif_a2dp_on_offload_started(p_av->status); + break; + CHECK_RC_EVENT(event, p_data); default: diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c index b6f3f0cce..5e64290a7 100644 --- a/btif/src/btif_media_task.c +++ b/btif/src/btif_media_task.c @@ -40,6 +40,8 @@ #include <sys/time.h> #include <errno.h> +#define LOG_TAG "BTIF-MEDIA" + #include "bt_target.h" #include "osi/include/fixed_queue.h" #include "gki.h" @@ -372,6 +374,8 @@ static const char* dump_a2dp_ctrl_event(UINT8 event) CASE_RETURN_STR(A2DP_CTRL_CMD_START) CASE_RETURN_STR(A2DP_CTRL_CMD_STOP) CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND) + CASE_RETURN_STR(A2DP_CTRL_CMD_OFFLOAD_START) + default: return "UNKNOWN MSG ID"; } @@ -531,6 +535,10 @@ static void btif_recv_ctrl_data(void) break; } + case A2DP_CTRL_CMD_OFFLOAD_START: + btif_dispatch_sm_event(BTIF_AV_OFFLOAD_START_REQ_EVT, NULL, 0); + break; + default: APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd); a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE); @@ -801,9 +809,9 @@ void btif_a2dp_setup_codec(void) GKI_disable(); /* for now hardcode 44.1 khz 16 bit stereo PCM format */ - media_feeding.cfg.pcm.sampling_freq = 44100; - media_feeding.cfg.pcm.bit_per_sample = 16; - media_feeding.cfg.pcm.num_channel = 2; + media_feeding.cfg.pcm.sampling_freq = BTIF_A2DP_SRC_SAMPLING_RATE; + media_feeding.cfg.pcm.bit_per_sample = BTIF_A2DP_SRC_BIT_DEPTH; + media_feeding.cfg.pcm.num_channel = BTIF_A2DP_SRC_NUM_CHANNELS; media_feeding.format = BTIF_AV_CODEC_PCM; if (bta_av_co_audio_set_codec(&media_feeding, &status)) @@ -1080,6 +1088,38 @@ void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av) btif_media_task_stop_aa_req(); } + +/***************************************************************************** +** +** Function btif_a2dp_on_offload_started +** +** Description +** +** Returns +** +*******************************************************************************/ +void btif_a2dp_on_offload_started(tBTA_AV_STATUS status) +{ + tA2DP_CTRL_ACK ack; + APPL_TRACE_EVENT("%s status %d", __func__, status); + + switch (status) { + case BTA_AV_SUCCESS: + ack = A2DP_CTRL_ACK_SUCCESS; + break; + + case BTA_AV_FAIL_RESOURCES: + APPL_TRACE_ERROR("%s FAILED UNSUPPORTED", __func__); + ack = A2DP_CTRL_ACK_UNSUPPORTED; + break; + default: + APPL_TRACE_ERROR("%s FAILED", __func__); + ack = A2DP_CTRL_ACK_FAILURE; + break; + } + a2dp_cmd_acknowledge(ack); +} + /* when true media task discards any rx frames */ void btif_a2dp_set_rx_flush(BOOLEAN enable) { diff --git a/hci/Android.mk b/hci/Android.mk index 72dda1dba..33d8a02bf 100644 --- a/hci/Android.mk +++ b/hci/Android.mk @@ -35,6 +35,7 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../osi/include \ $(LOCAL_PATH)/../stack/include \ $(LOCAL_PATH)/../utils/include \ + $(LOCAL_PATH)/../bta/include \ $(bdroid_C_INCLUDES) LOCAL_MODULE := libbt-hci diff --git a/hci/include/bt_vendor_lib.h b/hci/include/bt_vendor_lib.h index 65d448bf4..b4396ea61 100644 --- a/hci/include/bt_vendor_lib.h +++ b/hci/include/bt_vendor_lib.h @@ -167,6 +167,35 @@ typedef enum { * specific epilog process once it has been done. */ BT_VND_OP_EPILOG, + +/* [operation] + * Call to the vendor module so that it can perform all vendor-specific + * operations to start offloading a2dp media encode & tx. + * [input param] + * pointer to bt_vendor_op_a2dp_offload_start_t containing elements + * required for VND FW to setup a2dp offload. + * [return] + * 0 - default, dont care. + * [callback] + * Must call a2dp_offload_start_cb to notify the stack of the + * completion of vendor specific setup process once it has been done. + */ + BT_VND_OP_A2DP_OFFLOAD_START, + +/* [operation] + * Call to the vendor module so that it can perform all vendor-specific + * operations to suspend offloading a2dp media encode & tx. + * [input param] + * pointer to bt_vendor_op_a2dp_offload_t containing elements + * required for VND FW to setup a2dp offload. + * [return] + * 0 - default, dont care. + * [callback] + * Must call a2dp_offload_cb to notify the stack of the + * completion of vendor specific setup process once it has been done. + */ + BT_VND_OP_A2DP_OFFLOAD_STOP, + } bt_vendor_opcode_t; /** Power on/off control states */ @@ -287,6 +316,8 @@ typedef void (*tINT_CMD_CBACK)(void *p_mem); */ typedef uint8_t (*cmd_xmit_cb)(uint16_t opcode, void *p_buf, tINT_CMD_CBACK p_cback); +typedef void (*cfg_a2dp_cb)(bt_vendor_op_result_t result, bt_vendor_opcode_t op, uint8_t bta_av_handle); + typedef struct { /** set to sizeof(bt_vendor_callbacks_t) */ size_t size; @@ -319,8 +350,25 @@ typedef struct { /* notifies caller completion of epilog process */ cfg_result_cb epilog_cb; + + /* notifies status of a2dp offload cmd's */ + cfg_a2dp_cb a2dp_offload_cb; } bt_vendor_callbacks_t; +/** A2DP offload request */ +typedef struct { + uint8_t bta_av_handle; /* BTA_AV Handle for callbacks */ + uint16_t xmit_quota; /* Total ACL quota for light stack */ + uint16_t acl_data_size; /* Max ACL data size across HCI transport */ + uint16_t stream_mtu; + uint16_t local_cid; + uint16_t remote_cid; + uint16_t lm_handle; + uint8_t is_flushable; /* TRUE if flushable channel */ + uint32_t stream_source; + uint8_t codec_info[10]; /* Codec capabilities array */ +} bt_vendor_op_a2dp_offload_t; + /* * Bluetooth Host/Controller VENDOR Interface */ diff --git a/hci/include/vendor.h b/hci/include/vendor.h index 3181e6221..e147b230d 100644 --- a/hci/include/vendor.h +++ b/hci/include/vendor.h @@ -39,7 +39,10 @@ typedef enum { VENDOR_CONFIGURE_FIRMWARE = BT_VND_OP_FW_CFG, VENDOR_CONFIGURE_SCO = BT_VND_OP_SCO_CFG, VENDOR_SET_LPM_MODE = BT_VND_OP_LPM_SET_MODE, - VENDOR_DO_EPILOG = BT_VND_OP_EPILOG + VENDOR_DO_EPILOG = BT_VND_OP_EPILOG, + VENDOR_A2DP_OFFLOAD_START = BT_VND_OP_A2DP_OFFLOAD_START, + VENDOR_A2DP_OFFLOAD_STOP = BT_VND_OP_A2DP_OFFLOAD_STOP, + VENDOR_LAST_OP } vendor_async_opcode_t; typedef void (*vendor_cb)(bool success); diff --git a/hci/src/vendor.c b/hci/src/vendor.c index 2e220e4a7..21153c0cc 100644 --- a/hci/src/vendor.c +++ b/hci/src/vendor.c @@ -23,11 +23,11 @@ #include "buffer_allocator.h" #include "bt_vendor_lib.h" +#include "bta_av_api.h" #include "osi/include/osi.h" #include "osi/include/log.h" #include "vendor.h" -#define LAST_VENDOR_OPCODE_VALUE VENDOR_DO_EPILOG static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so"; static const char *VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE"; @@ -35,7 +35,7 @@ static const char *VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE" static const vendor_t interface; static const allocator_t *buffer_allocator; static const hci_t *hci; -static vendor_cb callbacks[LAST_VENDOR_OPCODE_VALUE + 1]; +static vendor_cb callbacks[VENDOR_LAST_OP]; static void *lib_handle; static bt_vendor_interface_t *lib_interface; @@ -186,6 +186,16 @@ static void epilog_cb(bt_vendor_op_result_t result) { callback(result == BT_VND_OP_RESULT_SUCCESS); } +// Called back from vendor library when the a2dp offload machine has to report status of +// an a2dp offload command. +static void a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op, uint8_t bta_av_handle) { + tBTA_AV_STATUS status = (result == BT_VND_OP_RESULT_SUCCESS) ? BTA_AV_SUCCESS : BTA_AV_FAIL_RESOURCES; + + if (op == BT_VND_OP_A2DP_OFFLOAD_START) { + BTA_AvOffloadStartRsp(bta_av_handle, status); + } +} + static const bt_vendor_callbacks_t lib_callbacks = { sizeof(lib_callbacks), firmware_config_cb, @@ -195,7 +205,8 @@ static const bt_vendor_callbacks_t lib_callbacks = { buffer_alloc_cb, buffer_free_cb, transmit_cb, - epilog_cb + epilog_cb, + a2dp_offload_cb }; static const vendor_t interface = { diff --git a/include/bt_target.h b/include/bt_target.h index f712d2c1a..f78c9517d 100644 --- a/include/bt_target.h +++ b/include/bt_target.h @@ -140,6 +140,18 @@ #define BTA_AV_CO_CP_SCMS_T FALSE #endif +#ifndef BTIF_A2DP_SRC_SAMPLING_RATE +#define BTIF_A2DP_SRC_SAMPLING_RATE 44100 +#endif + +#ifndef BTIF_A2DP_SRC_BIT_DEPTH +#define BTIF_A2DP_SRC_BIT_DEPTH 16 +#endif + +#ifndef BTIF_A2DP_SRC_NUM_CHANNELS +#define BTIF_A2DP_SRC_NUM_CHANNELS 2 +#endif + /* This feature is used to eanble interleaved scan*/ #ifndef BTA_HOST_INTERLEAVE_SEARCH #define BTA_HOST_INTERLEAVE_SEARCH FALSE diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h index 837dbc852..fc34f3f3e 100644 --- a/stack/include/l2c_api.h +++ b/stack/include/l2c_api.h @@ -1067,6 +1067,18 @@ extern BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid, tL2CAP_CFG_INFO **pp_our_cfg, tL2CAP_CH_CFG_BITS *p_our_cfg_bits, tL2CAP_CFG_INFO **pp_peer_cfg, tL2CAP_CH_CFG_BITS *p_peer_cfg_bits); +/******************************************************************************* +** +** Function L2CA_GetConnectionConfig +** +** Description This function polulates the mtu, remote cid & lm_handle for +** a given local L2CAP channel +** +** Returns TRUE if successful +** +*******************************************************************************/ +extern BOOLEAN L2CA_GetConnectionConfig(UINT16 lcid, UINT16 *mtu, UINT16 *rcid, UINT16 *handle); + #if (BLE_INCLUDED == TRUE) /******************************************************************************* ** diff --git a/stack/include/uipc_msg.h b/stack/include/uipc_msg.h deleted file mode 100644 index 53cdccfc8..000000000 --- a/stack/include/uipc_msg.h +++ /dev/null @@ -1,568 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1999-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 sync message over UIPC - * - ******************************************************************************/ - -#ifndef UIPC_MSG_H -#define UIPC_MSG_H - -#include "bt_types.h" - -/****************************************************************************/ -/* UIPC version number: 1.0 */ -/****************************************************************************/ -#define UIPC_VERSION_MAJOR 0x0001 -#define UIPC_VERSION_MINOR 0x0000 - - -/******************************** - - UIPC Management Messages - -********************************/ - -/* tUIPC_STATUS codes*/ -enum -{ - UIPC_STATUS_SUCCESS, - UIPC_STATUS_FAIL -}; -typedef UINT8 tUIPC_STATUS; - -/* op_code */ -#define UIPC_OPEN_REQ 0x00 -#define UIPC_OPEN_RSP 0x01 -#define UIPC_CLOSE_REQ 0x02 -#define UIPC_CLOSE_RSP 0x03 - -/* Structure of UIPC_OPEN_REQ message */ -typedef struct -{ - UINT8 opcode; /* UIPC_OPEN_REQ */ -} tUIPC_OPEN_REQ; -#define UIPC_OPEN_REQ_MSGLEN (1) - -/* Structure of UIPC_OPEN_RSP message */ -typedef struct -{ - UINT8 opcode; /* UIPC_OPEN_RESP */ - tUIPC_STATUS status; /* UIPC_STATUS */ - UINT16 version_major; /* UIPC_VERSION_MAJOR */ - UINT16 version_minor; /* UIPC_VERSION_MINOR */ - UINT8 num_streams; /* Number of simultaneous streams supported by the light stack */ -} tUIPC_OPEN_RSP; -#define UIPC_OPEN_RSP_MSGLEN (7) - -/* Structure of UIPC_CLOSE_REQ message */ -typedef struct t_uipc_close_req -{ - UINT8 opcode; /* UIPC_CLOSE_REQ */ -} tUIPC_CLOSE_REQ; -#define UIPC_CLOSE_REQ_MSGLEN (1) - -/* Structure of UIPC_CLOSE_RSP message, only for BTC, full stack may ignore it */ -typedef struct t_uipc_close_rsp -{ - UINT8 opcode; /* UIPC_CLOSE_RSP */ -} tUIPC_CLOSE_RSP; -#define UIPC_CLOSE_RSP_MSGLEN (1) - -/* UIPC management message structures */ -typedef union -{ - UINT8 opcode; - tUIPC_OPEN_REQ open_req; - tUIPC_OPEN_RSP open_resp; - tUIPC_CLOSE_REQ close_req; -} tUIPC_MSG; - -#define UIPC_MGMT_MSG_MAXLEN (sizeof(tUIPC_MSG)) - -#define IPC_LOG_MSG_LEN 100 -typedef struct t_uipc_log_msg -{ - UINT32 trace_set_mask; - UINT8 msg[IPC_LOG_MSG_LEN]; -} tUIPC_LOG_MSG; -#define UIPC_LOG_MSGLEN (IPC_LOG_MSG_LEN + 4) - -typedef struct -{ - UINT8 opcode; /* A2DP_START_REQ */ - UINT16 lcid; - UINT16 curr_mtu; -}tA2DP_START_REQ; - -typedef struct -{ - UINT8 opcode; /* A2DP_STOP_REQ */ - UINT16 lcid; -}tA2DP_STOP_REQ; - -typedef struct -{ - UINT8 opcode; /* A2DP_SUSPEND_REQ */ - UINT16 lcid; -}tA2DP_SUSPEND_REQ; - -typedef struct -{ - UINT8 opcode; /* A2DP_CLEANUP_REQ */ - UINT16 lcid; - UINT16 curr_mtu; -} tA2DP_CLEANUP_REQ; - -typedef struct -{ - UINT8 opcode; /* A2DP_START_RESP, A2DP_STOP_RESP, A2DP_CLEANUP_RESP, A2DP_SUSPEND_RESP */ - UINT16 lcid; -}tA2DP_GENERIC_RESP; - -#define AUDIO_CODEC_NONE 0x0000 -#define AUDIO_CODEC_SBC_ENC 0x0001 -#define AUDIO_CODEC_SBC_DEC 0x0002 -#define AUDIO_CODEC_MP3_ENC 0x0004 -#define AUDIO_CODEC_MP3_DEC 0x0008 -#define AUDIO_CODEC_AAC_ENC 0x0010 -#define AUDIO_CODEC_AAC_DEC 0x0020 -#define AUDIO_CODEC_AAC_PLUS_ENC 0x0040 -#define AUDIO_CODEC_AAC_PLUS_DEC 0x0080 -#define AUDIO_CODEC_MP2_ENC 0x0100 -#define AUDIO_CODEC_MP2_DEC 0x0200 -#define AUDIO_CODEC_MP2_5_ENC 0x0400 -#define AUDIO_CODEC_MP2_5_DEC 0x0800 - -typedef UINT16 tAUDIO_CODEC_TYPE; - -/* SBC CODEC Parameters */ - -#define CODEC_INFO_SBC_SF_16K 0x00 -#define CODEC_INFO_SBC_SF_32K 0x01 -#define CODEC_INFO_SBC_SF_44K 0x02 -#define CODEC_INFO_SBC_SF_48K 0x03 - -#define CODEC_INFO_SBC_BLOCK_4 0x00 -#define CODEC_INFO_SBC_BLOCK_8 0x01 -#define CODEC_INFO_SBC_BLOCK_12 0x02 -#define CODEC_INFO_SBC_BLOCK_16 0x03 - -#define CODEC_INFO_SBC_CH_MONO 0x00 -#define CODEC_INFO_SBC_CH_DUAL 0x01 -#define CODEC_INFO_SBC_CH_STEREO 0x02 -#define CODEC_INFO_SBC_CH_JS 0x03 - -#define CODEC_INFO_SBC_ALLOC_LOUDNESS 0x00 -#define CODEC_INFO_SBC_ALLOC_SNR 0x01 - -#define CODEC_INFO_SBC_SUBBAND_4 0x00 -#define CODEC_INFO_SBC_SUBBAND_8 0x01 - -/* MPEG audio version ID */ -#define CODEC_INFO_MP25_ID 0x00 -#define CODEC_INFO_RESERVE 0x01 -#define CODEC_INFO_MP2_ID 0x02 -#define CODEC_INFO_MP3_ID 0x03 - -#define CODEC_INFO_MP3_PROTECTION_ON 0x00 -#define CODEC_INFO_MP3_PROTECTION_OFF 0x01 - -#define CODEC_INFO_MP3_BR_IDX_FREE 0x00 -#define CODEC_INFO_MP3_BR_IDX_32K 0x01 -#define CODEC_INFO_MP3_BR_IDX_40K 0x02 -#define CODEC_INFO_MP3_BR_IDX_48K 0x03 -#define CODEC_INFO_MP3_BR_IDX_56K 0x04 -#define CODEC_INFO_MP3_BR_IDX_64K 0x05 -#define CODEC_INFO_MP3_BR_IDX_80K 0x06 -#define CODEC_INFO_MP3_BR_IDX_96K 0x07 -#define CODEC_INFO_MP3_BR_IDX_112K 0x08 -#define CODEC_INFO_MP3_BR_IDX_128K 0x09 -#define CODEC_INFO_MP3_BR_IDX_160K 0x0A -#define CODEC_INFO_MP3_BR_IDX_192K 0x0B -#define CODEC_INFO_MP3_BR_IDX_224K 0x0C -#define CODEC_INFO_MP3_BR_IDX_256K 0x0D -#define CODEC_INFO_MP3_BR_IDX_320K 0x0E - -#define CODEC_INFO_MP3_SF_44K 0x00 -#define CODEC_INFO_MP3_SF_48K 0x01 -#define CODEC_INFO_MP3_SF_32K 0x02 - -#define CODEC_INFO_MP3_MODE_STEREO 0x00 -#define CODEC_INFO_MP3_MODE_JS 0x01 -#define CODEC_INFO_MP3_MODE_DUAL 0x02 -#define CODEC_INFO_MP3_MODE_SINGLE 0x03 - -/* layer 3, type of joint stereo coding method (intensity and ms) */ -#define CODEC_INFO_MP3_MODE_EXT_OFF_OFF 0x00 -#define CODEC_INFO_MP3_MODE_EXT_ON_OFF 0x01 -#define CODEC_INFO_MP3_MODE_EXT_OFF_ON 0x02 -#define CODEC_INFO_MP3_MODE_EXT_ON_ON 0x03 - - -#define CODEC_INFO_MP2_PROTECTION_ON 0x00 -#define CODEC_INFO_MP2_PROTECTION_OFF 0x01 - -#define CODEC_INFO_MP2_BR_IDX_FREE 0x00 -#define CODEC_INFO_MP2_BR_IDX_8K 0x01 -#define CODEC_INFO_MP2_BR_IDX_16K 0x02 -#define CODEC_INFO_MP2_BR_IDX_24K 0x03 -#define CODEC_INFO_MP2_BR_IDX_32K 0x04 -#define CODEC_INFO_MP2_BR_IDX_40K 0x05 -#define CODEC_INFO_MP2_BR_IDX_48K 0x06 -#define CODEC_INFO_MP2_BR_IDX_56K 0x07 -#define CODEC_INFO_MP2_BR_IDX_64K 0x08 -#define CODEC_INFO_MP2_BR_IDX_80K 0x09 -#define CODEC_INFO_MP2_BR_IDX_96K 0x0A -#define CODEC_INFO_MP2_BR_IDX_112K 0x0B -#define CODEC_INFO_MP2_BR_IDX_128K 0x0C -#define CODEC_INFO_MP2_BR_IDX_144K 0x0D -#define CODEC_INFO_MP2_BR_IDX_160K 0x0E - -#define CODEC_INFO_MP2_SF_22K 0x00 -#define CODEC_INFO_MP2_SF_24K 0x01 -#define CODEC_INFO_MP2_SF_16K 0x02 - -#define CODEC_INFO_MP2_MODE_STEREO 0x00 -#define CODEC_INFO_MP2_MODE_JS 0x01 -#define CODEC_INFO_MP2_MODE_DUAL 0x02 -#define CODEC_INFO_MP2_MODE_SINGLE 0x03 - -/* layer 3, type of joint stereo coding method (intensity and ms) */ -#define CODEC_INFO_MP2_MODE_EXT_OFF_OFF 0x00 -#define CODEC_INFO_MP2_MODE_EXT_ON_OFF 0x01 -#define CODEC_INFO_MP2_MODE_EXT_OFF_ON 0x02 -#define CODEC_INFO_MP2_MODE_EXT_ON_ON 0x03 - -#define CODEC_INFO_MP2_SAMPLE_PER_FRAME 576 - -/* mpeg 2.5 layer 3 decoder */ - -#define CODEC_INFO_MP25_PROTECTION_ON 0x00 -#define CODEC_INFO_MP25_PROTECTION_OFF 0x01 - -#define CODEC_INFO_MP25_BR_IDX_FREE 0x00 -#define CODEC_INFO_MP25_BR_IDX_8K 0x01 -#define CODEC_INFO_MP25_BR_IDX_16K 0x02 -#define CODEC_INFO_MP25_BR_IDX_24K 0x03 -#define CODEC_INFO_MP25_BR_IDX_32K 0x04 -#define CODEC_INFO_MP25_BR_IDX_40K 0x05 -#define CODEC_INFO_MP25_BR_IDX_48K 0x06 -#define CODEC_INFO_MP25_BR_IDX_56K 0x07 -#define CODEC_INFO_MP25_BR_IDX_64K 0x08 -#define CODEC_INFO_MP25_BR_IDX_80K 0x09 -#define CODEC_INFO_MP25_BR_IDX_96K 0x0A -#define CODEC_INFO_MP25_BR_IDX_112K 0x0B -#define CODEC_INFO_MP25_BR_IDX_128K 0x0C -#define CODEC_INFO_MP25_BR_IDX_144K 0x0D -#define CODEC_INFO_MP25_BR_IDX_160K 0x0E - -#define CODEC_INFO_MP25_SF_11K 0x00 -#define CODEC_INFO_MP25_SF_12K 0x01 -#define CODEC_INFO_MP25_SF_8K 0x02 - -#define CODEC_INFO_MP25_MODE_STEREO 0x00 -#define CODEC_INFO_MP25_MODE_JS 0x01 -#define CODEC_INFO_MP25_MODE_DUAL 0x02 -#define CODEC_INFO_MP25_MODE_SINGLE 0x03 - -/* layer 3, type of joint stereo coding method (intensity and ms) */ -#define CODEC_INFO_MP25_MODE_EXT_OFF_OFF 0x00 -#define CODEC_INFO_MP25_MODE_EXT_ON_OFF 0x01 -#define CODEC_INFO_MP25_MODE_EXT_OFF_ON 0x02 -#define CODEC_INFO_MP25_MODE_EXT_ON_ON 0x03 - -#define CODEC_INFO_MP25_SAMPLE_PER_FRAME 576 - -/* AAC/AAC+ CODEC Parameters */ -#define CODEC_INFO_AAC_SF_IDX_96K 0x0 -#define CODEC_INFO_AAC_SF_IDX_88K 0x1 -#define CODEC_INFO_AAC_SF_IDX_64K 0x2 -#define CODEC_INFO_AAC_SF_IDX_48K 0x3 -#define CODEC_INFO_AAC_SF_IDX_44K 0x4 -#define CODEC_INFO_AAC_SF_IDX_32K 0x5 -#define CODEC_INFO_AAC_SF_IDX_24K 0x6 -#define CODEC_INFO_AAC_SF_IDX_22K 0x7 -#define CODEC_INFO_AAC_SF_IDX_16K 0x8 -#define CODEC_INFO_AAC_SF_IDX_12K 0x9 -#define CODEC_INFO_AAC_SF_IDX_11K 0xA -#define CODEC_INFO_AAC_SF_IDX_08K 0xB -#define CODEC_INFO_AAC_SF_IDX_RESERVE 0xC - -#define CODEC_INFO_AAC_BR_RATE_48K 288000 -#define CODEC_INFO_AAC_BR_RATE_44K 264600 -#define CODEC_INFO_AAC_BR_RATE_32K 192000 - - -#define CODEC_INFO_AAC_1_CH 1 /*center front speaker */ -#define CODEC_INFO_AAC_2_CH 2 /*left, right front speaker */ -#define CODEC_INFO_AAC_3_CH 3 /*center front speaker, left right front speaker */ -#define CODEC_INFO_AAC_4_CH 4 /*center/rear front speaker, left/right front speaker */ -#define CODEC_INFO_AAC_5_CH 5 /*center, left, right front speaker, left/right surround */ -#define CODEC_INFO_AAC_6_CH 6 /*center, left, right front speaker, left/right surround, LFE */ -#define CODEC_INFO_AAC_7_CH 7 /*(left, right)center/left,right front speaker, left/right surround, LFE */ - - -typedef struct -{ - UINT8 sampling_freq; - UINT8 channel_mode; - UINT8 block_length; - UINT8 num_subbands; - UINT8 alloc_method; - UINT8 bitpool_size; /* 2 - 250 */ -} tCODEC_INFO_SBC; - -typedef struct -{ - UINT8 ch_mode; - UINT8 sampling_freq; - UINT8 bitrate_index; /* 0 - 14 */ -} tCODEC_INFO_MP3; - -typedef struct -{ - UINT8 ch_mode; - UINT8 sampling_freq; - UINT8 bitrate_index; /* 0 - 14 */ -} tCODEC_INFO_MP2; - - -typedef struct -{ - UINT8 ch_mode; - UINT8 sampling_freq; - UINT8 bitrate_index; /* 0 - 14 */ -} tCODEC_INFO_MP2_5; - -typedef struct -{ - UINT16 sampling_freq; - UINT8 channel_mode; /* 0x02:mono, 0x01:dual */ - UINT32 bitrate; /* 0 - 320K */ - UINT32 sbr_profile; /* 1: ON, 0: OFF */ -} tCODEC_INFO_AAC; - -typedef union -{ - tCODEC_INFO_SBC sbc; - tCODEC_INFO_MP3 mp3; - tCODEC_INFO_MP2 mp2; - tCODEC_INFO_MP2_5 mp2_5; - tCODEC_INFO_AAC aac; -} tCODEC_INFO; - -typedef struct -{ - UINT8 opcode; /* AUDIO_CODEC_CONFIG_REQ */ - tAUDIO_CODEC_TYPE codec_type; - tCODEC_INFO codec_info; -} tAUDIO_CODEC_CONFIG_REQ; - -#define AUDIO_CONFIG_SUCCESS 0x00 -#define AUDIO_CONFIG_NOT_SUPPORTED 0x01 -#define AUDIO_CONFIG_FAIL_OUT_OF_MEMORY 0x02 -#define AUDIO_CONFIG_FAIL_CODEC_USED 0x03 -#define AUDIO_CONFIG_FAIL_ROUTE 0x04 -typedef UINT8 tAUDIO_CONFIG_STATUS; - -typedef struct -{ - UINT8 opcode; /* AUDIO_CODEC_CONFIG_RESP */ - tAUDIO_CONFIG_STATUS status; -} tAUDIO_CODEC_CONFIG_RESP; - -typedef struct -{ - UINT8 opcode; /* AUDIO_CODEC_SET_BITRATE_REQ */ - tAUDIO_CODEC_TYPE codec_type; - union - { - UINT8 sbc; - UINT8 mp3; - UINT32 aac; - } codec_bitrate; -} tAUDIO_CODEC_SET_BITRATE_REQ; - -#define AUDIO_ROUTE_SRC_FMRX 0x00 -#define AUDIO_ROUTE_SRC_I2S 0x01 -#define AUDIO_ROUTE_SRC_ADC 0x02 -#define AUDIO_ROUTE_SRC_HOST 0x03 -#define AUDIO_ROUTE_SRC_PTU 0x04 -#define AUDIO_ROUTE_SRC_BTSNK 0x05 -#define AUDIO_ROUTE_SRC_NONE 0x80 -#define MAX_AUDIO_ROUTE_SRC 6 -typedef UINT8 tAUDIO_ROUTE_SRC; - -#define AUDIO_ROUTE_MIX_NONE 0x00 -#define AUDIO_ROUTE_MIX_HOST 0x01 -#define AUDIO_ROUTE_MIX_PCM 0x02 -#define AUDIO_ROUTE_MIX_CHIRP 0x03 -#define AUDIO_ROUTE_MIX_I2S 0x04 -#define AUDIO_ROUTE_MIX_ADC 0x05 -#define AUDIO_ROUTE_MIX_RESERVED 0x06 -#define MAX_AUDIO_ROUTE_MIX 7 -typedef UINT8 tAUDIO_ROUTE_MIX; - -#define AUDIO_ROUTE_OUT_NONE 0x0000 -#define AUDIO_ROUTE_OUT_BTA2DP 0x0001 -#define AUDIO_ROUTE_OUT_FMTX 0x0002 -#define AUDIO_ROUTE_OUT_BTSCO 0x0004 -#define AUDIO_ROUTE_OUT_HOST 0x0008 -#define AUDIO_ROUTE_OUT_DAC 0x0010 -#define AUDIO_ROUTE_OUT_I2S 0x0020 -#define AUDIO_ROUTE_OUT_BTA2DP_DAC 0x0040 -#define AUDIO_ROUTE_OUT_BTA2DP_I2S 0x0080 -#define AUDIO_ROUTE_OUT_BTSCO_DAC 0x0100 -#define AUDIO_ROUTE_OUT_BTSCO_I2S 0x0200 -#define AUDIO_ROUTE_OUT_HOST_BTA2DP 0x0400 -#define AUDIO_ROUTE_OUT_HOST_BTSCO 0x0800 -#define AUDIO_ROUTE_OUT_HOST_DAC 0x1000 -#define AUDIO_ROUTE_OUT_HOST_I2S 0x2000 -#define AUDIO_ROUTE_OUT_DAC_I2S 0x4000 -#define AUDIO_ROUTE_OUT_RESERVED_2 0x8000 - -#define MAX_AUDIO_SINGLE_ROUTE_OUT 6 -#define MAX_AUDIO_MULTI_ROUTE_OUT 16 -typedef UINT16 tAUDIO_MULTI_ROUTE_OUT; -typedef UINT8 tAUDIO_ROUTE_OUT; - -#define AUDIO_ROUTE_SF_8K 0x00 -#define AUDIO_ROUTE_SF_16K 0x01 -#define AUDIO_ROUTE_SF_32K 0x02 -#define AUDIO_ROUTE_SF_44_1K 0x03 -#define AUDIO_ROUTE_SF_48K 0x04 -#define AUDIO_ROUTE_SF_11K 0x05 -#define AUDIO_ROUTE_SF_12K 0x06 -#define AUDIO_ROUTE_SF_22K 0x07 -#define AUDIO_ROUTE_SF_24K 0x08 -#define AUDIO_ROUTE_SF_NA 0xFF -typedef UINT8 tAUDIO_ROUTE_SF; - -#define AUDIO_ROUTE_EQ_BASS_BOOST 0x00 -#define AUDIO_ROUTE_EQ_CLASSIC 0x01 -#define AUDIO_ROUTE_EQ_JAZZ 0x02 -#define AUDIO_ROUTE_EQ_LIVE 0x03 -#define AUDIO_ROUTE_EQ_NORMAL 0x04 -#define AUDIO_ROUTE_EQ_ROCK 0x05 -#define AUDIO_ROUTE_EQ_BYPASS 0x06 - -#define AUDIO_ROUTE_DIGITAL_VOLUME_CONTROL 0x07 - -#define AUDIO_ROUTE_EQ_CONFIG_GAIN 0xFF /* Custion Gain Config */ -typedef UINT8 tAUDIO_ROUTE_EQ; - -typedef struct -{ - UINT8 opcode; /* AUDIO_ROUTE_CONFIG_REQ */ - tAUDIO_ROUTE_SRC src; - tAUDIO_ROUTE_SF src_sf; - tAUDIO_ROUTE_OUT out; - tAUDIO_ROUTE_SF out_codec_sf; - tAUDIO_ROUTE_SF out_i2s_sf; - tAUDIO_ROUTE_EQ eq_mode; -} tAUDIO_ROUTE_CONFIG_REQ; - -typedef struct -{ - UINT8 opcode; /* AUDIO_ROUTE_CONFIG_RESP */ - tAUDIO_CONFIG_STATUS status; -} tAUDIO_ROUTE_CONFIG_RESP; - -typedef struct -{ - UINT16 amp[2]; /* left/right 15 bit amplitude value */ - UINT16 tone[2]; /* left/right 12 bit frequency 0 - 4096Hz */ - UINT16 mark[2]; /* left/right 16 bit mark time 0 - 65535ms */ - UINT16 space[2]; /* left/right 16 bit space time 0 - 65535ms */ -} tCHIRP_CONFIG; - -typedef struct -{ - UINT8 pri_l; /* Primary Left scale : 0 ~ 255 */ - UINT8 mix_l; /* Mixing Left scale : 0 ~ 255 */ - UINT8 pri_r; /* Primary Right scale : 0 ~ 255 */ - UINT8 mix_r; /* Mixing Right scale : 0 ~ 255 */ -} tMIX_SCALE_CONFIG; - -/* For custon equalizer gain configuration */ -typedef struct -{ - UINT32 audio_l_g0; /* IIR biquad filter left ch gain 0 */ - UINT32 audio_l_g1; /* IIR biquad filter left ch gain 1 */ - UINT32 audio_l_g2; /* IIR biquad filter left ch gain 2 */ - UINT32 audio_l_g3; /* IIR biquad filter left ch gain 3 */ - UINT32 audio_l_g4; /* IIR biquad filter left ch gain 4 */ - UINT32 audio_l_gl; /* IIR biquad filter left ch global gain */ - UINT32 audio_r_g0; /* IIR biquad filter left ch gain 0 */ - UINT32 audio_r_g1; /* IIR biquad filter left ch gain 1 */ - UINT32 audio_r_g2; /* IIR biquad filter left ch gain 2 */ - UINT32 audio_r_g3; /* IIR biquad filter left ch gain 3 */ - UINT32 audio_r_g4; /* IIR biquad filter left ch gain 4 */ - UINT32 audio_r_gl; /* IIR biquad filter left ch global gain */ -} tEQ_GAIN_CONFIG; - -typedef struct -{ - UINT8 opcode; /* AUDIO_MIX_CONFIG_REQ */ - tAUDIO_ROUTE_MIX mix_src; - tAUDIO_ROUTE_SF mix_src_sf; - tMIX_SCALE_CONFIG mix_scale; - tCHIRP_CONFIG chirp_config; -} tAUDIO_MIX_CONFIG_REQ; - -typedef struct -{ - UINT8 opcode; /* AUDIO_MIX_CONFIG_RESP */ - tAUDIO_CONFIG_STATUS status; -} tAUDIO_MIX_CONFIG_RESP; - - -typedef struct -{ - UINT8 opcode; /* AUDIO_BURST_FRAMES_IND */ - UINT32 burst_size; /* in bytes */ -} tAUDIO_BURST_FRAMES_IND; - -typedef struct -{ - UINT8 opcode; /* AUDIO_BURST_END_IND */ -} tAUDIO_BURST_END_IND; - -typedef struct -{ - UINT8 opcode; /* AUDIO_CODEC_FLUSH_REQ */ -} tAUDIO_CODEC_FLUSH_REQ; - -typedef struct -{ - UINT8 opcode; /* AUDIO_EQ_MODE_CONFIG_REQ */ - tAUDIO_ROUTE_EQ eq_mode; - tEQ_GAIN_CONFIG filter_gain; /* Valid only when eq_mode is 0xFF */ -} tAUDIO_EQ_MODE_CONFIG_REQ; - -typedef struct -{ - UINT8 opcode; /* AUDIO_SCALE_CONFIG_REQ */ - tMIX_SCALE_CONFIG mix_scale; -} tAUDIO_SCALE_CONFIG_REQ; - -#endif /* UIPC_MSG_H */ - diff --git a/stack/l2cap/l2c_api.c b/stack/l2cap/l2c_api.c index e01a261e5..c1ca120b8 100644 --- a/stack/l2cap/l2c_api.c +++ b/stack/l2cap/l2c_api.c @@ -1772,6 +1772,37 @@ BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid, /******************************************************************************* ** +** Function L2CA_GetConnectionConfig +** +** Description This function returns configurations of L2CAP channel +** pp_l2c_ccb : pointer to this channels L2CAP ccb data. +** +** Returns TRUE if successful +** +*******************************************************************************/ +BOOLEAN L2CA_GetConnectionConfig(UINT16 lcid, UINT16 *mtu, UINT16 *rcid, UINT16 *handle) +{ + tL2C_CCB *p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);; + + L2CAP_TRACE_API ("%s CID: 0x%04x", __func__, lcid); + + if (p_ccb) + { + *mtu = L2CAP_MTU_SIZE; + if (p_ccb->our_cfg.mtu_present) + *mtu = p_ccb->our_cfg.mtu; + + *rcid = p_ccb->remote_cid; + *handle= p_ccb->p_lcb->handle; + return TRUE; + } + + L2CAP_TRACE_ERROR ("%s No CCB for CID:0x%04x", __func__, lcid); + return FALSE; +} + +/******************************************************************************* +** ** Function L2CA_RegForNoCPEvt ** ** Description Register callback for Number of Completed Packets event. |