summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKausik Sinnaswamy <kausik@broadcom.com>2012-03-09 10:54:02 -0800
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:13 -0700
commit837acf40a4968449f044cfd3cd15f7f120617eb5 (patch)
treed2e71deec39c3a5e2e9651726662748fdf6440ac
parent5140bed9a19aadca962184ebc9ed823d5d7cb745 (diff)
downloadexternal_bluetooth_bluedroid-837acf40a4968449f044cfd3cd15f7f120617eb5.zip
external_bluetooth_bluedroid-837acf40a4968449f044cfd3cd15f7f120617eb5.tar.gz
external_bluetooth_bluedroid-837acf40a4968449f044cfd3cd15f7f120617eb5.tar.bz2
Added support to handle AVRCP 1.0 and incoming A2DP connections
Change-Id: I7863920895aa9fd77eccee4083319701bcbf4300
-rw-r--r--bta/av/bta_av_act.c79
-rw-r--r--bta/av/bta_av_int.h1
-rw-r--r--btif/co/bta_av_co.c9
-rw-r--r--btif/include/uinput.h611
-rw-r--r--btif/src/btif_av.c137
-rw-r--r--btif/src/btif_rc.c435
-rw-r--r--include/buildcfg_crespo.h2
-rw-r--r--include/buildcfg_maguro.h2
-rw-r--r--main/Android.mk3
9 files changed, 1237 insertions, 42 deletions
diff --git a/bta/av/bta_av_act.c b/bta/av/bta_av_act.c
index e501e52..9fafd76 100644
--- a/bta/av/bta_av_act.c
+++ b/bta/av/bta_av_act.c
@@ -87,7 +87,8 @@ void bta_av_del_rc(tBTA_AV_RCB *p_rcb)
p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
if(p_scb)
{
- APPL_TRACE_DEBUG3("bta_av_del_rc shdl:%d, srch:%d rc_handle:%d", p_rcb->shdl, p_scb->rc_handle, p_rcb->handle);
+ APPL_TRACE_DEBUG3("bta_av_del_rc shdl:%d, srch:%d rc_handle:%d", p_rcb->shdl,
+ p_scb->rc_handle, p_rcb->handle);
if(p_scb->rc_handle == p_rcb->handle)
p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
/* just in case the RC timer is active
@@ -317,7 +318,7 @@ UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx)
ccb.company_id = p_bta_av_cfg->company_id;
ccb.conn = role;
/* note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL */
- ccb.control = p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | AVRC_CT_PASSIVE);
+ ccb.control = p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | AVRC_CT_PASSIVE);
if (AVRC_Open(&rc_handle, &ccb, bda) != AVRC_SUCCESS)
@@ -497,7 +498,8 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0)
{
- /* rc is opened on the RC only ACP channel, but is for a specific SCB -> need to switch RCBs */
+ /* rc is opened on the RC only ACP channel, but is for a specific
+ * SCB -> need to switch RCBs */
p_rcb = bta_av_get_rcb_by_shdl(shdl);
if (p_rcb)
{
@@ -507,7 +509,8 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
p_cb->rcb[i].lidx = tmp;
p_cb->rc_acp_handle = p_rcb->handle;
p_cb->rc_acp_idx = (p_rcb - p_cb->rcb) + 1;
- APPL_TRACE_DEBUG2("switching RCB rc_acp_handle:%d idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
+ APPL_TRACE_DEBUG2("switching RCB rc_acp_handle:%d idx:%d",
+ p_cb->rc_acp_handle, p_cb->rc_acp_idx);
}
}
@@ -538,7 +541,8 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
rc_open.peer_features = p_cb->rcb[i].peer_features;
rc_open.status = BTA_AV_SUCCESS;
- APPL_TRACE_DEBUG2("local features:x%x peer_features:x%x", p_cb->features, rc_open.peer_features);
+ APPL_TRACE_DEBUG2("local features:x%x peer_features:x%x", p_cb->features,
+ rc_open.peer_features);
if(rc_open.peer_features == 0)
{
/* we have not done SDP on peer RC capabilities.
@@ -549,8 +553,8 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
(*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);
#if (AVRC_ADV_CTRL_INCLUDED == TRUE && AVCT_BROWSE_INCLUDED == TRUE)
- /* if local initiated AVRCP connection and both peer and locals device support browsing channel,
- * open the browsing channel now */
+ /* if local initiated AVRCP connection and both peer and locals device support
+ * browsing channel, open the browsing channel now */
if ((p_cb->features & BTA_AV_FEAT_BROWSE) && (rc_open.peer_features & BTA_AV_FEAT_BROWSE) &&
((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT))
{
@@ -652,7 +656,8 @@ void bta_av_rc_meta_rsp(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
(!p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCCT)) )
{
p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
- AVRC_MsgReq(p_rcb->handle, p_data->api_meta_rsp.label, p_data->api_meta_rsp.rsp_code, p_data->api_meta_rsp.p_pkt);
+ AVRC_MsgReq(p_rcb->handle, p_data->api_meta_rsp.label, p_data->api_meta_rsp.rsp_code,
+ p_data->api_meta_rsp.p_pkt);
free = FALSE;
}
}
@@ -798,13 +803,15 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE *p_rc_rsp, tBTA_AV_RC_MSG *p_ms
{
*p_ctype = AVRC_RSP_IMPL_STBL;
p_rc_rsp->get_caps.count = p_bta_av_cfg->num_co_ids;
- memcpy(p_rc_rsp->get_caps.param.company_id, p_bta_av_cfg->p_meta_co_ids, (p_bta_av_cfg->num_co_ids << 2));
+ memcpy(p_rc_rsp->get_caps.param.company_id, p_bta_av_cfg->p_meta_co_ids,
+ (p_bta_av_cfg->num_co_ids << 2));
}
else if (u8 == AVRC_CAP_EVENTS_SUPPORTED)
{
*p_ctype = AVRC_RSP_IMPL_STBL;
p_rc_rsp->get_caps.count = p_bta_av_cfg->num_evt_ids;
- memcpy(p_rc_rsp->get_caps.param.event_id, p_bta_av_cfg->p_meta_evt_ids, p_bta_av_cfg->num_evt_ids);
+ memcpy(p_rc_rsp->get_caps.param.event_id, p_bta_av_cfg->p_meta_evt_ids,
+ p_bta_av_cfg->num_evt_ids);
}
else
{
@@ -864,7 +871,9 @@ void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_NOT_IMPL;
#if (AVRC_METADATA_INCLUDED == TRUE)
if (p_cb->features & BTA_AV_FEAT_METADATA)
- p_data->rc_msg.msg.hdr.ctype = bta_av_group_navi_supported(p_data->rc_msg.msg.pass.pass_len, p_data->rc_msg.msg.pass.p_pass_data);
+ p_data->rc_msg.msg.hdr.ctype =
+ bta_av_group_navi_supported(p_data->rc_msg.msg.pass.pass_len,
+ p_data->rc_msg.msg.pass.p_pass_data);
#endif
}
else
@@ -1081,7 +1090,8 @@ void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started)
tBTA_AV_SCB *p_scbi;
started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
- APPL_TRACE_DEBUG3 ("bta_av_stream_chg started:%d started_msk:x%x chnl:x%x", started, started_msk, p_scb->chnl);
+ APPL_TRACE_DEBUG3 ("bta_av_stream_chg started:%d started_msk:x%x chnl:x%x", started,
+ started_msk, p_scb->chnl);
if (BTA_AV_CHNL_AUDIO == p_scb->chnl)
p_streams = &bta_av_cb.audio_streams;
else
@@ -1114,7 +1124,8 @@ void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started)
for (; i<BTA_AV_NUM_STRS; i++)
{
p_scbi = bta_av_cb.p_scb[i];
- if ( p_scbi && (bta_av_cb.audio_streams & BTA_AV_HNDL_TO_MSK(i)) /* scb is used and started */
+ /* scb is used and started */
+ if ( p_scbi && (bta_av_cb.audio_streams & BTA_AV_HNDL_TO_MSK(i))
&& bdcmp(p_scbi->peer_addr, p_scb->peer_addr) == 0)
{
no_streams = FALSE;
@@ -1125,7 +1136,8 @@ void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started)
}
}
- APPL_TRACE_DEBUG4 ("no_streams:%d i:%d, audio_streams:x%x, video_streams:x%x", no_streams, i, bta_av_cb.audio_streams, bta_av_cb.video_streams);
+ APPL_TRACE_DEBUG4 ("no_streams:%d i:%d, audio_streams:x%x, video_streams:x%x", no_streams, i,
+ bta_av_cb.audio_streams, bta_av_cb.video_streams);
if (no_streams)
{
/* Let L2CAP know this channel is processed with low priority */
@@ -1178,7 +1190,9 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
if (bta_av_cb.rcb[i].lidx == p_lcb->lidx)
{
bta_av_cb.rcb[i].shdl = index + 1;
- APPL_TRACE_DEBUG5("conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i, bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
+ APPL_TRACE_DEBUG5("conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
+ bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
+ bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
break;
}
}
@@ -1206,13 +1220,17 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
if(p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE && p_cb->rc_acp_idx)
{
p_lcb_rc = &p_cb->lcb[BTA_AV_NUM_LINKS];
- APPL_TRACE_DEBUG1("rc_acp is connected && conn_chg on same addr p_lcb_rc->conn_msk:x%x", p_lcb_rc->conn_msk);
+ APPL_TRACE_DEBUG1("rc_acp is connected && conn_chg on same addr p_lcb_rc->conn_msk:x%x",
+ p_lcb_rc->conn_msk);
/* check if the RC is connected to the scb addr */
APPL_TRACE_DEBUG6 ("p_lcb_rc->addr: %02x:%02x:%02x:%02x:%02x:%02x",
- p_lcb_rc->addr[0], p_lcb_rc->addr[1], p_lcb_rc->addr[2], p_lcb_rc->addr[3], p_lcb_rc->addr[4], p_lcb_rc->addr[5]);
+ p_lcb_rc->addr[0], p_lcb_rc->addr[1], p_lcb_rc->addr[2], p_lcb_rc->addr[3],
+ p_lcb_rc->addr[4], p_lcb_rc->addr[5]);
APPL_TRACE_DEBUG6 ("conn_chg.peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
- p_data->conn_chg.peer_addr[0], p_data->conn_chg.peer_addr[1], p_data->conn_chg.peer_addr[2],
- p_data->conn_chg.peer_addr[3], p_data->conn_chg.peer_addr[4], p_data->conn_chg.peer_addr[5]);
+ p_data->conn_chg.peer_addr[0], p_data->conn_chg.peer_addr[1],
+ p_data->conn_chg.peer_addr[2],
+ p_data->conn_chg.peer_addr[3], p_data->conn_chg.peer_addr[4],
+ p_data->conn_chg.peer_addr[5]);
if (p_lcb_rc->conn_msk && bdcmp(p_lcb_rc->addr, p_data->conn_chg.peer_addr) == 0)
{
/* AVRCP is already connected.
@@ -1222,7 +1240,8 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
p_scb->rc_handle = p_cb->rc_acp_handle;
p_rcb = &p_cb->rcb[p_cb->rc_acp_idx - 1];
p_rcb->shdl = bta_av_get_shdl(p_scb);
- APPL_TRACE_DEBUG3("update rc_acp shdl:%d/%d srch:%d", index + 1, p_rcb->shdl, p_scb->rc_handle );
+ APPL_TRACE_DEBUG3("update rc_acp shdl:%d/%d srch:%d", index + 1, p_rcb->shdl,
+ p_scb->rc_handle );
p_rcb2 = bta_av_get_rcb_by_shdl(p_rcb->shdl);
if (p_rcb2)
@@ -1230,12 +1249,15 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
/* found the RCB that was created to associated with this SCB */
p_cb->rc_acp_handle = p_rcb2->handle;
p_cb->rc_acp_idx = (p_rcb2 - p_cb->rcb) + 1;
- APPL_TRACE_DEBUG2("new rc_acp_handle:%d, idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
+ APPL_TRACE_DEBUG2("new rc_acp_handle:%d, idx:%d", p_cb->rc_acp_handle,
+ p_cb->rc_acp_idx);
p_rcb2->lidx = (BTA_AV_NUM_LINKS + 1);
- APPL_TRACE_DEBUG3("rc2 handle:%d lidx:%d/%d",p_rcb2->handle, p_rcb2->lidx, p_cb->lcb[p_rcb2->lidx-1].lidx);
+ APPL_TRACE_DEBUG3("rc2 handle:%d lidx:%d/%d",p_rcb2->handle, p_rcb2->lidx,
+ p_cb->lcb[p_rcb2->lidx-1].lidx);
}
p_rcb->lidx = p_lcb->lidx;
- APPL_TRACE_DEBUG3("rc handle:%d lidx:%d/%d",p_rcb->handle, p_rcb->lidx, p_cb->lcb[p_rcb->lidx-1].lidx);
+ APPL_TRACE_DEBUG3("rc handle:%d lidx:%d/%d",p_rcb->handle, p_rcb->lidx,
+ p_cb->lcb[p_rcb->lidx-1].lidx);
}
}
}
@@ -1276,7 +1298,9 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data)
APPL_TRACE_DEBUG1("bta_av_conn_chg shdl:%d", index + 1);
for (i=0; i<BTA_AV_NUM_RCB; i++)
{
- APPL_TRACE_DEBUG5("conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i, bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
+ APPL_TRACE_DEBUG5("conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
+ bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
+ bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
if(bta_av_cb.rcb[i].shdl == index + 1)
{
bta_av_del_rc(&bta_av_cb.rcb[i]);
@@ -1431,7 +1455,12 @@ void bta_av_sig_chg(tBTA_AV_DATA *p_data)
p_cb->p_scb[xx]->use_rc = TRUE; /* allowing RC for incoming connection */
bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_ACP_CONNECT_EVT, p_data);
- bta_sys_start_timer(&p_cb->sig_tmr, BTA_AV_SIG_TIMER_EVT, BTA_AV_SIG_TIME_VAL);
+ /* The Pending Event should be sent as soon as the L2CAP signalling channel
+ * is set up, which is NOW. Earlier this was done only after
+ * BTA_AV_SIG_TIME_VAL milliseconds.
+ * The following function shall send the event and start the recurring timer
+ */
+ bta_av_sig_timer(NULL);
/* Possible collision : need to avoid outgoing processing while the timer is running */
p_cb->p_scb[xx]->coll_mask = BTA_AV_COLL_INC_TMR;
diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h
index 9e7f510..41fb565 100644
--- a/bta/av/bta_av_int.h
+++ b/bta/av/bta_av_int.h
@@ -18,6 +18,7 @@
#include "avdt_api.h"
#include "bta_av_co.h"
+#define BTA_AV_DEBUG TRUE
/*****************************************************************************
** Constants
*****************************************************************************/
diff --git a/btif/co/bta_av_co.c b/btif/co/bta_av_co.c
index 34a9a00..1dbd940 100644
--- a/btif/co/bta_av_co.c
+++ b/btif/co/bta_av_co.c
@@ -216,7 +216,7 @@ static tBTA_AV_CO_PEER *bta_av_co_get_peer(tBTA_AV_HNDL hndl)
FUNC_TRACE();
index = BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl);
-
+ APPL_TRACE_ERROR2("%s index:%d", __FUNCTION__, index);
/* Sanity check */
if (index >= BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers))
{
@@ -1008,7 +1008,6 @@ static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT
/* Configure the codec type to look for */
codec_type = bta_av_co_cb.codec_cfg.id;
-
for (index = 0; index < p_peer->num_sup_snks; index++)
{
if (p_peer->snks[index].codec_type == codec_type)
@@ -1379,6 +1378,12 @@ void bta_av_co_init(void)
/* Reset the control block */
memset(&bta_av_co_cb, 0, sizeof(bta_av_co_cb));
+#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
+ bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_NEVER);
+#else
+ bta_av_co_cp_set_flag(BTA_AV_CP_SCMS_COPY_FREE);
+#endif
+
/* Reset the current config */
bta_av_co_audio_codec_reset();
}
diff --git a/btif/include/uinput.h b/btif/include/uinput.h
new file mode 100644
index 0000000..303f4f3
--- /dev/null
+++ b/btif/include/uinput.h
@@ -0,0 +1,611 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+/* TBD: tmp code here */
+
+#ifndef __UINPUT_H
+#define __UINPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+/* Events */
+
+#define EV_SYN 0x00
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+
+/* Synchronization events */
+
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+
+/* Keys and buttons */
+
+#define KEY_RESERVED 0
+#define KEY_ESC 1
+#define KEY_1 2
+#define KEY_2 3
+#define KEY_3 4
+#define KEY_4 5
+#define KEY_5 6
+#define KEY_6 7
+#define KEY_7 8
+#define KEY_8 9
+#define KEY_9 10
+#define KEY_0 11
+#define KEY_MINUS 12
+#define KEY_EQUAL 13
+#define KEY_BACKSPACE 14
+#define KEY_TAB 15
+#define KEY_Q 16
+#define KEY_W 17
+#define KEY_E 18
+#define KEY_R 19
+#define KEY_T 20
+#define KEY_Y 21
+#define KEY_U 22
+#define KEY_I 23
+#define KEY_O 24
+#define KEY_P 25
+#define KEY_LEFTBRACE 26
+#define KEY_RIGHTBRACE 27
+#define KEY_ENTER 28
+#define KEY_LEFTCTRL 29
+#define KEY_A 30
+#define KEY_S 31
+#define KEY_D 32
+#define KEY_F 33
+#define KEY_G 34
+#define KEY_H 35
+#define KEY_J 36
+#define KEY_K 37
+#define KEY_L 38
+#define KEY_SEMICOLON 39
+#define KEY_APOSTROPHE 40
+#define KEY_GRAVE 41
+#define KEY_LEFTSHIFT 42
+#define KEY_BACKSLASH 43
+#define KEY_Z 44
+#define KEY_X 45
+#define KEY_C 46
+#define KEY_V 47
+#define KEY_B 48
+#define KEY_N 49
+#define KEY_M 50
+#define KEY_COMMA 51
+#define KEY_DOT 52
+#define KEY_SLASH 53
+#define KEY_RIGHTSHIFT 54
+#define KEY_KPASTERISK 55
+#define KEY_LEFTALT 56
+#define KEY_SPACE 57
+#define KEY_CAPSLOCK 58
+#define KEY_F1 59
+#define KEY_F2 60
+#define KEY_F3 61
+#define KEY_F4 62
+#define KEY_F5 63
+#define KEY_F6 64
+#define KEY_F7 65
+#define KEY_F8 66
+#define KEY_F9 67
+#define KEY_F10 68
+#define KEY_NUMLOCK 69
+#define KEY_SCROLLLOCK 70
+#define KEY_KP7 71
+#define KEY_KP8 72
+#define KEY_KP9 73
+#define KEY_KPMINUS 74
+#define KEY_KP4 75
+#define KEY_KP5 76
+#define KEY_KP6 77
+#define KEY_KPPLUS 78
+#define KEY_KP1 79
+#define KEY_KP2 80
+#define KEY_KP3 81
+#define KEY_KP0 82
+#define KEY_KPDOT 83
+#define KEY_103RD 84
+#define KEY_F13 85
+#define KEY_102ND 86
+#define KEY_F11 87
+#define KEY_F12 88
+#define KEY_F14 89
+#define KEY_F15 90
+#define KEY_F16 91
+#define KEY_F17 92
+#define KEY_F18 93
+#define KEY_F19 94
+#define KEY_F20 95
+#define KEY_KPENTER 96
+#define KEY_RIGHTCTRL 97
+#define KEY_KPSLASH 98
+#define KEY_SYSRQ 99
+#define KEY_RIGHTALT 100
+#define KEY_LINEFEED 101
+#define KEY_HOME 102
+#define KEY_UP 103
+#define KEY_PAGEUP 104
+#define KEY_LEFT 105
+#define KEY_RIGHT 106
+#define KEY_END 107
+#define KEY_DOWN 108
+#define KEY_PAGEDOWN 109
+#define KEY_INSERT 110
+#define KEY_DELETE 111
+#define KEY_MACRO 112
+#define KEY_MUTE 113
+#define KEY_VOLUMEDOWN 114
+#define KEY_VOLUMEUP 115
+#define KEY_POWER 116
+#define KEY_KPEQUAL 117
+#define KEY_KPPLUSMINUS 118
+#define KEY_PAUSE 119
+#define KEY_F21 120
+#define KEY_F22 121
+#define KEY_F23 122
+#define KEY_F24 123
+#define KEY_KPCOMMA 124
+#define KEY_LEFTMETA 125
+#define KEY_RIGHTMETA 126
+#define KEY_COMPOSE 127
+
+#define KEY_STOP 128
+#define KEY_AGAIN 129
+#define KEY_PROPS 130
+#define KEY_UNDO 131
+#define KEY_FRONT 132
+#define KEY_COPY 133
+#define KEY_OPEN 134
+#define KEY_PASTE 135
+#define KEY_FIND 136
+#define KEY_CUT 137
+#define KEY_HELP 138
+#define KEY_MENU 139
+#define KEY_CALC 140
+#define KEY_SETUP 141
+#define KEY_SLEEP 142
+#define KEY_WAKEUP 143
+#define KEY_FILE 144
+#define KEY_SENDFILE 145
+#define KEY_DELETEFILE 146
+#define KEY_XFER 147
+#define KEY_PROG1 148
+#define KEY_PROG2 149
+#define KEY_WWW 150
+#define KEY_MSDOS 151
+#define KEY_COFFEE 152
+#define KEY_DIRECTION 153
+#define KEY_CYCLEWINDOWS 154
+#define KEY_MAIL 155
+#define KEY_BOOKMARKS 156
+#define KEY_COMPUTER 157
+#define KEY_BACK 158
+#define KEY_FORWARD 159
+#define KEY_CLOSECD 160
+#define KEY_EJECTCD 161
+#define KEY_EJECTCLOSECD 162
+#define KEY_NEXTSONG 163
+#define KEY_PLAYPAUSE 164
+#define KEY_PREVIOUSSONG 165
+#define KEY_STOPCD 166
+#define KEY_RECORD 167
+#define KEY_REWIND 168
+#define KEY_PHONE 169
+#define KEY_ISO 170
+#define KEY_CONFIG 171
+#define KEY_HOMEPAGE 172
+#define KEY_REFRESH 173
+#define KEY_EXIT 174
+#define KEY_MOVE 175
+#define KEY_EDIT 176
+#define KEY_SCROLLUP 177
+#define KEY_SCROLLDOWN 178
+#define KEY_KPLEFTPAREN 179
+#define KEY_KPRIGHTPAREN 180
+
+#define KEY_INTL1 181
+#define KEY_INTL2 182
+#define KEY_INTL3 183
+#define KEY_INTL4 184
+#define KEY_INTL5 185
+#define KEY_INTL6 186
+#define KEY_INTL7 187
+#define KEY_INTL8 188
+#define KEY_INTL9 189
+#define KEY_LANG1 190
+#define KEY_LANG2 191
+#define KEY_LANG3 192
+#define KEY_LANG4 193
+#define KEY_LANG5 194
+#define KEY_LANG6 195
+#define KEY_LANG7 196
+#define KEY_LANG8 197
+#define KEY_LANG9 198
+
+#define KEY_PLAYCD 200
+#define KEY_PAUSECD 201
+#define KEY_PROG3 202
+#define KEY_PROG4 203
+#define KEY_SUSPEND 205
+#define KEY_CLOSE 206
+#define KEY_PLAY 207
+
+#define KEY_UNKNOWN 220
+
+#define KEY_BRIGHTNESSDOWN 224
+#define KEY_BRIGHTNESSUP 225
+
+#define BTN_MISC 0x100
+#define BTN_0 0x100
+#define BTN_1 0x101
+#define BTN_2 0x102
+#define BTN_3 0x103
+#define BTN_4 0x104
+#define BTN_5 0x105
+#define BTN_6 0x106
+#define BTN_7 0x107
+#define BTN_8 0x108
+#define BTN_9 0x109
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+#define BTN_JOYSTICK 0x120
+#define BTN_TRIGGER 0x120
+#define BTN_THUMB 0x121
+#define BTN_THUMB2 0x122
+#define BTN_TOP 0x123
+#define BTN_TOP2 0x124
+#define BTN_PINKIE 0x125
+#define BTN_BASE 0x126
+#define BTN_BASE2 0x127
+#define BTN_BASE3 0x128
+#define BTN_BASE4 0x129
+#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
+#define BTN_DEAD 0x12f
+
+#define BTN_GAMEPAD 0x130
+#define BTN_A 0x130
+#define BTN_B 0x131
+#define BTN_C 0x132
+#define BTN_X 0x133
+#define BTN_Y 0x134
+#define BTN_Z 0x135
+#define BTN_TL 0x136
+#define BTN_TR 0x137
+#define BTN_TL2 0x138
+#define BTN_TR2 0x139
+#define BTN_SELECT 0x13a
+#define BTN_START 0x13b
+#define BTN_MODE 0x13c
+#define BTN_THUMBL 0x13d
+#define BTN_THUMBR 0x13e
+
+#define BTN_DIGI 0x140
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOOL_LENS 0x147
+#define BTN_TOUCH 0x14a
+#define BTN_STYLUS 0x14b
+#define BTN_STYLUS2 0x14c
+#define BTN_TOOL_DOUBLETAP 0x14d
+#define BTN_TOOL_TRIPLETAP 0x14e
+
+#define BTN_WHEEL 0x150
+#define BTN_GEAR_DOWN 0x150
+#define BTN_GEAR_UP 0x151
+
+#define KEY_OK 0x160
+#define KEY_SELECT 0x161
+#define KEY_GOTO 0x162
+#define KEY_CLEAR 0x163
+#define KEY_POWER2 0x164
+#define KEY_OPTION 0x165
+#define KEY_INFO 0x166
+#define KEY_TIME 0x167
+#define KEY_VENDOR 0x168
+#define KEY_ARCHIVE 0x169
+#define KEY_PROGRAM 0x16a
+#define KEY_CHANNEL 0x16b
+#define KEY_FAVORITES 0x16c
+#define KEY_EPG 0x16d
+#define KEY_PVR 0x16e
+#define KEY_MHP 0x16f
+#define KEY_LANGUAGE 0x170
+#define KEY_TITLE 0x171
+#define KEY_SUBTITLE 0x172
+#define KEY_ANGLE 0x173
+#define KEY_ZOOM 0x174
+#define KEY_MODE 0x175
+#define KEY_KEYBOARD 0x176
+#define KEY_SCREEN 0x177
+#define KEY_PC 0x178
+#define KEY_TV 0x179
+#define KEY_TV2 0x17a
+#define KEY_VCR 0x17b
+#define KEY_VCR2 0x17c
+#define KEY_SAT 0x17d
+#define KEY_SAT2 0x17e
+#define KEY_CD 0x17f
+#define KEY_TAPE 0x180
+#define KEY_RADIO 0x181
+#define KEY_TUNER 0x182
+#define KEY_PLAYER 0x183
+#define KEY_TEXT 0x184
+#define KEY_DVD 0x185
+#define KEY_AUX 0x186
+#define KEY_MP3 0x187
+#define KEY_AUDIO 0x188
+#define KEY_VIDEO 0x189
+#define KEY_DIRECTORY 0x18a
+#define KEY_LIST 0x18b
+#define KEY_MEMO 0x18c
+#define KEY_CALENDAR 0x18d
+#define KEY_RED 0x18e
+#define KEY_GREEN 0x18f
+#define KEY_YELLOW 0x190
+#define KEY_BLUE 0x191
+#define KEY_CHANNELUP 0x192
+#define KEY_CHANNELDOWN 0x193
+#define KEY_FIRST 0x194
+#define KEY_LAST 0x195
+#define KEY_AB 0x196
+#define KEY_NEXT 0x197
+#define KEY_RESTART 0x198
+#define KEY_SLOW 0x199
+#define KEY_SHUFFLE 0x19a
+#define KEY_BREAK 0x19b
+#define KEY_PREVIOUS 0x19c
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
+
+#define KEY_FRAMEBACK 0x1b2
+#define KEY_FRAMEFORWARD 0x1b3
+#define KEY_CONTEXT_MENU 0x1fb
+
+#define KEY_MAX 0x1ff
+
+/* Relative axes */
+
+#define REL_X 0x00
+#define REL_Y 0x01
+#define REL_Z 0x02
+#define REL_RX 0x03
+#define REL_RY 0x04
+#define REL_RZ 0x05
+#define REL_HWHEEL 0x06
+#define REL_DIAL 0x07
+#define REL_WHEEL 0x08
+#define REL_MISC 0x09
+#define REL_MAX 0x0f
+
+/* Absolute axes */
+
+#define ABS_X 0x00
+#define ABS_Y 0x01
+#define ABS_Z 0x02
+#define ABS_RX 0x03
+#define ABS_RY 0x04
+#define ABS_RZ 0x05
+#define ABS_THROTTLE 0x06
+#define ABS_RUDDER 0x07
+#define ABS_WHEEL 0x08
+#define ABS_GAS 0x09
+#define ABS_BRAKE 0x0a
+#define ABS_HAT0X 0x10
+#define ABS_HAT0Y 0x11
+#define ABS_HAT1X 0x12
+#define ABS_HAT1Y 0x13
+#define ABS_HAT2X 0x14
+#define ABS_HAT2Y 0x15
+#define ABS_HAT3X 0x16
+#define ABS_HAT3Y 0x17
+#define ABS_PRESSURE 0x18
+#define ABS_DISTANCE 0x19
+#define ABS_TILT_X 0x1a
+#define ABS_TILT_Y 0x1b
+#define ABS_TOOL_WIDTH 0x1c
+#define ABS_VOLUME 0x20
+#define ABS_MISC 0x28
+#define ABS_MAX 0x3f
+
+/* Switch events */
+
+#define SW_0 0x00
+#define SW_1 0x01
+#define SW_2 0x02
+#define SW_3 0x03
+#define SW_4 0x04
+#define SW_5 0x05
+#define SW_6 0x06
+#define SW_7 0x07
+#define SW_MAX 0x0f
+
+/* Misc events */
+
+#define MSC_SERIAL 0x00
+#define MSC_PULSELED 0x01
+#define MSC_GESTURE 0x02
+#define MSC_RAW 0x03
+#define MSC_SCAN 0x04
+#define MSC_MAX 0x07
+
+/* LEDs */
+
+#define LED_NUML 0x00
+#define LED_CAPSL 0x01
+#define LED_SCROLLL 0x02
+#define LED_COMPOSE 0x03
+#define LED_KANA 0x04
+#define LED_SLEEP 0x05
+#define LED_SUSPEND 0x06
+#define LED_MUTE 0x07
+#define LED_MISC 0x08
+#define LED_MAIL 0x09
+#define LED_CHARGING 0x0a
+#define LED_MAX 0x0f
+
+/* Autorepeat values */
+
+#define REP_DELAY 0x00
+#define REP_PERIOD 0x01
+#define REP_MAX 0x01
+
+/* Sounds */
+
+#define SND_CLICK 0x00
+#define SND_BELL 0x01
+#define SND_TONE 0x02
+#define SND_MAX 0x07
+
+/* Identifiers */
+
+#define ID_BUS 0
+#define ID_VENDOR 1
+#define ID_PRODUCT 2
+#define ID_VERSION 3
+
+#define BUS_PCI 0x01
+#define BUS_ISAPNP 0x02
+#define BUS_USB 0x03
+#define BUS_HIL 0x04
+#define BUS_BLUETOOTH 0x05
+
+#define BUS_ISA 0x10
+#define BUS_I8042 0x11
+#define BUS_XTKBD 0x12
+#define BUS_RS232 0x13
+#define BUS_GAMEPORT 0x14
+#define BUS_PARPORT 0x15
+#define BUS_AMIGA 0x16
+#define BUS_ADB 0x17
+#define BUS_I2C 0x18
+#define BUS_HOST 0x19
+#define BUS_GSC 0x1A
+
+/* User input interface */
+
+#define UINPUT_IOCTL_BASE 'U'
+
+#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
+#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
+
+#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
+#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
+#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
+#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
+#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
+#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
+#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
+#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
+#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
+#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
+
+#ifndef NBITS
+#define NBITS(x) ((((x) - 1) / (sizeof(long) * 8)) + 1)
+#endif
+
+#define UINPUT_MAX_NAME_SIZE 80
+
+struct uinput_id {
+ uint16_t bustype;
+ uint16_t vendor;
+ uint16_t product;
+ uint16_t version;
+};
+
+struct uinput_dev {
+ char name[UINPUT_MAX_NAME_SIZE];
+ struct uinput_id id;
+ int ff_effects_max;
+ int absmax[ABS_MAX + 1];
+ int absmin[ABS_MAX + 1];
+ int absfuzz[ABS_MAX + 1];
+ int absflat[ABS_MAX + 1];
+};
+
+struct uinput_event {
+ struct timeval time;
+ uint16_t type;
+ uint16_t code;
+ int32_t value;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UINPUT_H */
diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c
index d383926..a822c7f 100644
--- a/btif/src/btif_av.c
+++ b/btif/src/btif_av.c
@@ -62,12 +62,16 @@
#include "bta_api.h"
#include "bta_av_api.h"
#include "gki.h"
+#include "bd.h"
+#include "btu.h"
/*****************************************************************************
** Constants & Macros
******************************************************************************/
#define BTIF_AV_SERVICE_NAME "Advanced Audio"
+#define BTIF_TIMEOUT_AV_OPEN_ON_RC 2 /* 2 seconds */
+
typedef enum {
BTIF_AV_STATE_IDLE = 0x0,
BTIF_AV_STATE_OPENING,
@@ -99,6 +103,8 @@ typedef struct
static btav_callbacks_t *bt_av_callbacks = NULL;
static btif_av_cb_t btif_av_cb;
+static TIMER_LIST_ENT tle_av_open_on_rc;
+
#define CHECK_BTAV_INIT() if (bt_av_callbacks == NULL)\
{\
BTIF_TRACE_WARNING1("%s: BTAV not initialized", __FUNCTION__);\
@@ -109,6 +115,18 @@ else\
BTIF_TRACE_EVENT1("%s", __FUNCTION__);\
}
+/* Helper macro to avoid code duplication in the state machine handlers */
+#define CHECK_RC_EVENT(e, d) \
+ case BTA_AV_RC_OPEN_EVT: \
+ case BTA_AV_RC_CLOSE_EVT: \
+ case BTA_AV_REMOTE_CMD_EVT: \
+ case BTA_AV_VENDOR_CMD_EVT: \
+ case BTA_AV_META_MSG_EVT: \
+ case BTA_AV_RC_FEAT_EVT: \
+ { \
+ btif_rc_handler(e, d);\
+ }break; \
+
static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
@@ -123,6 +141,13 @@ static const btif_sm_handler_t btif_av_state_handlers[] =
};
+/*************************************************************************
+** Extern functions
+*************************************************************************/
+extern void btif_rc_init(void);
+extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
+extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
+
/*****************************************************************************
** Local helper functions
******************************************************************************/
@@ -173,6 +198,36 @@ const char *dump_av_sm_event_name(btif_av_sm_event_t event)
}
}
+
+/****************************************************************************
+** Local helper functions
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function btif_initiate_av_open_tmr_hdlr
+**
+** Description Timer to trigger AV open if the remote headset establishes
+** RC connection w/o AV connection. The timer is needed to IOP
+** with headsets that do establish AV after RC connection.
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
+{
+ BD_ADDR peer_addr;
+
+ /* is there at least one RC connection - There should be */
+ if (btif_rc_get_connected_peer(peer_addr)) {
+ BTIF_TRACE_DEBUG1("%s Issuing connect to the remote RC peer", __FUNCTION__);
+ btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (void*)&peer_addr);
+ }
+ else
+ {
+ BTIF_TRACE_ERROR1("%s No connected RC peers", __FUNCTION__);
+ }
+}
+
/*****************************************************************************
** Static functions
******************************************************************************/
@@ -210,16 +265,54 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
{
btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
} break;
-
+ case BTA_AV_PENDING_EVT:
case BTIF_AV_CONNECT_REQ_EVT:
{
+ if (event == BTIF_AV_CONNECT_REQ_EVT)
+ {
memcpy(&btif_av_cb.peer_bda, (bt_bdaddr_t*)p_data, sizeof(bt_bdaddr_t));
-
BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
TRUE, BTA_SEC_NONE);
-
+ }
+ else if (event == BTA_AV_PENDING_EVT)
+ {
+ bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
+ }
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
} break;
+ case BTA_AV_RC_OPEN_EVT:
+ {
+ /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
+ * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
+ * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
+ * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
+ * headsets, as some headsets initiate the AVRC connection first and then
+ * immediately initiate the AV connection
+ *
+ * TODO: We may need to do this only on an AVRCP Play. FixMe
+ */
+ BTIF_TRACE_DEBUG0("BTA_AV_RC_OPEN_EVT received w/o AV");
+ memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
+ tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
+ btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
+ BTIF_TIMEOUT_AV_OPEN_ON_RC);
+ btif_rc_handler(event, p_data);
+ }break;
+ case BTA_AV_REMOTE_CMD_EVT:
+ case BTA_AV_VENDOR_CMD_EVT:
+ case BTA_AV_META_MSG_EVT:
+ case BTA_AV_RC_FEAT_EVT:
+ {
+ btif_rc_handler(event, (tBTA_AV*)p_data);
+ }break;
+ case BTA_AV_RC_CLOSE_EVT:
+ {
+ if (tle_av_open_on_rc.in_use) {
+ BTIF_TRACE_DEBUG0("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
+ btu_stop_timer(&tle_av_open_on_rc);
+ }
+ btif_rc_handler(event, p_data);
+ }break;
default:
BTIF_TRACE_WARNING2("%s Unhandled event:%s", __FUNCTION__,
@@ -228,7 +321,6 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
return TRUE;
}
-
static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
{
BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event));
@@ -248,26 +340,30 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
case BTA_AV_OPEN_EVT:
{
tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
- btav_connection_state_t state = BTAV_CONNECTION_STATE_DISCONNECTED;
+ btav_connection_state_t state;
+ btif_sm_state_t av_state;
BTIF_TRACE_DEBUG1("status:%d", p_bta_data->open.status);
if (p_bta_data->open.status == BTA_AV_SUCCESS)
{
state = BTAV_CONNECTION_STATE_CONNECTED;
- /* change state to open */
- btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
+ av_state = BTIF_AV_STATE_OPENED;
}
else
{
BTIF_TRACE_WARNING1("BTA_AV_OPEN_EVT::FAILED status: %d",
p_bta_data->open.status );
- /* change state to idle */
- btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+ state = BTAV_CONNECTION_STATE_DISCONNECTED;
+ av_state = BTIF_AV_STATE_IDLE;
}
/* inform the application of the event */
CHECK_CALL_CBACK(bt_av_callbacks, connection_state_cb,
state, &(btif_av_cb.peer_bda));
+ /* change state to open/idle based on the status */
+ btif_sm_change_state(btif_av_cb.sm_handle, av_state);
} break;
+ CHECK_RC_EVENT(event, p_data);
+
default:
BTIF_TRACE_WARNING2("%s Unhandled event:%s", __FUNCTION__,
dump_av_sm_event_name(event));
@@ -284,7 +380,15 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
{
case BTIF_SM_ENTER_EVT:
- BTIF_TRACE_DEBUG0("starting av");
+ BTIF_TRACE_DEBUG0("starting av...sleeping before that");
+
+ /* Auto-starting on Open could introduce race conditions. So delaying
+ * the start.
+ *
+ * This is anyway temporary and will be removed once the START/STOP stream
+ * requests are processed.
+ */
+ GKI_delay(3000);
btif_a2dp_upon_start_req();
@@ -331,6 +435,8 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
} break;
+ CHECK_RC_EVENT(event, p_data);
+
default:
BTIF_TRACE_WARNING2("%s Unhandled event:%s", __FUNCTION__,
dump_av_sm_event_name(event));
@@ -338,7 +444,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
return TRUE;
}
-static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data)
+static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
{
BTIF_TRACE_DEBUG2("%s event:%s", __FUNCTION__, dump_av_sm_event_name(event));
@@ -364,6 +470,8 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data)
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
} break;
+ CHECK_RC_EVENT(event, p_data);
+
default:
BTIF_TRACE_WARNING2("%s Unhandled event:%s", __FUNCTION__,
dump_av_sm_event_name(event));
@@ -414,6 +522,8 @@ static bt_status_t init(btav_callbacks_t* callbacks )
bt_av_callbacks = callbacks;
btif_enable_service(BTA_A2DP_SERVICE_ID);
+ /* Initialize the AVRC CB */
+ btif_rc_init();
/* Also initialize the AV state machine */
btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
@@ -516,7 +626,10 @@ bt_status_t btif_av_execute_service(BOOLEAN b_enable)
BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR,
bte_av_callback);
#else
- BTA_AvEnable(BTA_SEC_AUTHENTICATE|BTA_SEC_AUTHORIZE, BTA_AV_FEAT_RCTG,
+ /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
+ * handle this request in order to allow incoming connections to succeed.
+ * We need to put this back once support for this is added */
+ BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_RCTG,
bte_av_callback);
#endif
BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0);
diff --git a/btif/src/btif_rc.c b/btif/src/btif_rc.c
new file mode 100644
index 0000000..04d5681
--- /dev/null
+++ b/btif/src/btif_rc.c
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
+ * OR ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Filename: btif_rc.c
+ *
+ * Description: Bluetooth AVRC implementation
+ *
+ *****************************************************************************/
+#include <hardware/bluetooth.h>
+#include <fcntl.h>
+#include "bta_api.h"
+#include "bta_av_api.h"
+#include "avrc_defs.h"
+#include "bd.h"
+#include "gki.h"
+
+#define LOG_TAG "BTIF_RC"
+#include "btif_common.h"
+
+/*****************************************************************************
+** Constants & Macros
+******************************************************************************/
+#if (!defined(AVRC_METADATA_INCLUDED) || (AVRC_METADATA_INCLUDED == FALSE))
+#define BTIF_RC_USE_UINPUT TRUE
+#include "uinput.h"
+#else
+#error "AVRCP 1.3 is not supported on Bluedroid yet."
+#endif
+
+/*****************************************************************************
+** Local type definitions
+******************************************************************************/
+typedef struct {
+ BOOLEAN rc_connected;
+ UINT8 rc_handle;
+ BD_ADDR rc_addr;
+ UINT16 rc_pending_play;
+} btif_rc_cb_t;
+
+#ifdef BTIF_RC_USE_UINPUT
+#define MAX_UINPUT_PATHS 3
+static const char* uinput_dev_path[] =
+ {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
+static int uinput_fd = -1;
+
+static int send_event (int fd, uint16_t type, uint16_t code, int32_t value);
+static void send_key (int fd, uint16_t key, int pressed);
+static int uinput_driver_check();
+static int uinput_create(char *name);
+static int init_uinput (void);
+static void close_uinput (void);
+
+static struct {
+ const char *name;
+ uint8_t avrcp;
+ uint16_t mapped_id;
+ uint8_t release_quirk;
+} key_map[] = {
+ { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 },
+ { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 },
+ { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 },
+ { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 },
+ { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
+ { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 },
+ { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FORWARD, 0 },
+ { NULL, 0, 0, 0 }
+};
+#endif /* BTIF_RC_USE_UINPUT */
+
+
+/*****************************************************************************
+** Static variables
+******************************************************************************/
+static btif_rc_cb_t btif_rc_cb;
+
+/*****************************************************************************
+** Static functions
+******************************************************************************/
+
+/*****************************************************************************
+** Externs
+******************************************************************************/
+
+/*****************************************************************************
+** Functions
+******************************************************************************/
+
+
+#ifdef BTIF_RC_USE_UINPUT
+/*****************************************************************************
+** Local uinput helper functions
+******************************************************************************/
+int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
+{
+ struct uinput_event event;
+
+ memset(&event, 0, sizeof(event));
+ event.type = type;
+ event.code = code;
+ event.value = value;
+
+ return write(fd, &event, sizeof(event));
+}
+
+void send_key (int fd, uint16_t key, int pressed)
+{
+ if (fd < 0) {
+ return;
+ }
+
+ BTIF_TRACE_DEBUG3("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
+ send_event(fd, EV_KEY, key, pressed);
+ send_event(fd, EV_SYN, SYN_REPORT, 0);
+}
+
+/************** uinput related functions **************/
+int uinput_driver_check()
+{
+ uint32_t i;
+ for (i=0; i < MAX_UINPUT_PATHS; i++)
+ {
+ if (access(uinput_dev_path[i], O_RDWR) == 0) {
+ return 0;
+ }
+ }
+ BTIF_TRACE_ERROR1("%s ERROR: uinput device is not in the system", __FUNCTION__);
+ return -1;
+}
+
+int uinput_create(char *name)
+{
+ struct uinput_dev dev;
+ int fd, err, x = 0;
+
+ for(x=0; x < MAX_UINPUT_PATHS; x++)
+ {
+ fd = open(uinput_dev_path[x], O_RDWR);
+ if (fd < 0)
+ continue;
+ break;
+ }
+ if (x == MAX_UINPUT_PATHS) {
+ BTIF_TRACE_ERROR1("%s ERROR: uinput device open failed", __FUNCTION__);
+ return -1;
+ }
+ memset(&dev, 0, sizeof(dev));
+ if (name)
+ strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE);
+
+ dev.id.bustype = BUS_BLUETOOTH;
+ dev.id.vendor = 0x0000;
+ dev.id.product = 0x0000;
+ dev.id.version = 0x0000;
+
+ if (write(fd, &dev, sizeof(dev)) < 0) {
+ BTIF_TRACE_ERROR1("%s Unable to write device information", __FUNCTION__);
+ close(fd);
+ return -1;
+ }
+
+ ioctl(fd, UI_SET_EVBIT, EV_KEY);
+ ioctl(fd, UI_SET_EVBIT, EV_REL);
+ ioctl(fd, UI_SET_EVBIT, EV_SYN);
+
+ for (x = 0; key_map[x].name != NULL; x++)
+ ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
+
+ for(x = 0; x < KEY_MAX; x++)
+ ioctl(fd, UI_SET_KEYBIT, x);
+
+ if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
+ BTIF_TRACE_ERROR1("%s Unable to create uinput device", __FUNCTION__);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int init_uinput (void)
+{
+ char *name = "AVRCP";
+
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ uinput_fd = uinput_create(name);
+ if (uinput_fd < 0) {
+ BTIF_TRACE_ERROR3("%s AVRCP: Failed to initialize uinput for %s (%d)",
+ __FUNCTION__, name, uinput_fd);
+ } else {
+ BTIF_TRACE_DEBUG3("%s AVRCP: Initialized uinput for %s (fd=%d)",
+ __FUNCTION__, name, uinput_fd);
+ }
+ return uinput_fd;
+}
+
+void close_uinput (void)
+{
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ if (uinput_fd > 0) {
+ ioctl(uinput_fd, UI_DEV_DESTROY);
+
+ close(uinput_fd);
+ uinput_fd = -1;
+ }
+}
+#endif // BTA_AVRCP_FORCE_USE_UINPUT
+
+const char *dump_rc_event_name(tBTA_AV_EVT event)
+{
+ switch(event) {
+ case BTA_AV_RC_OPEN_EVT: return "BTA_AV_RC_OPEN_EVT";
+ case BTA_AV_RC_CLOSE_EVT: return "BTA_AV_RC_CLOSE_EVT";
+ case BTA_AV_REMOTE_CMD_EVT: return "BTA_AV_REMOTE_CMD_EVT";
+ case BTA_AV_REMOTE_RSP_EVT: return "BTA_AV_REMOTE_RSP_EVT";
+ case BTA_AV_VENDOR_CMD_EVT: return "BTA_AV_VENDOR_CMD_EVT";
+ case BTA_AV_VENDOR_RSP_EVT: return "BTA_AV_VENDOR_RSP_EVT";
+ default: return "UNKNOWN_EVENT";
+ }
+}
+
+/***************************************************************************
+ * Function handle_rc_connect
+ *
+ * - Argument: tBTA_AV_RC_OPEN RC open data structure
+ *
+ * - Description: RC connection event handler
+ *
+ ***************************************************************************/
+void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
+{
+ BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
+
+#ifdef BTIF_RC_USE_UINPUT
+ init_uinput();
+#endif
+
+ memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
+ btif_rc_cb.rc_connected = TRUE;
+ btif_rc_cb.rc_handle = p_rc_open->rc_handle;
+}
+
+/***************************************************************************
+ * Function handle_rc_disconnect
+ *
+ * - Argument: tBTA_AV_RC_CLOSE RC close data structure
+ *
+ * - Description: RC disconnection event handler
+ *
+ ***************************************************************************/
+void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
+{
+ BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
+
+ btif_rc_cb.rc_handle = 0;
+ btif_rc_cb.rc_connected = FALSE;
+ memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
+#ifdef BTIF_RC_USE_UINPUT
+ close_uinput();
+#endif /* BTIF_RC_USE_UINPUT */
+}
+
+/***************************************************************************
+ * Function handle_rc_passthrough_cmd
+ *
+ * - Argument: tBTA_AV_RC rc_id remote control command ID
+ * tBTA_AV_STATE key_state status of key press
+ *
+ * - Description: Remote control command handler
+ *
+ ***************************************************************************/
+void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
+{
+ const char *status;
+ int pressed, i;
+
+ if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
+ status = "released";
+ pressed = 0;
+ } else {
+ status = "pressed";
+ pressed = 1;
+ }
+
+ for (i = 0; key_map[i].name != NULL; i++) {
+ if (p_remote_cmd->rc_id == key_map[i].avrcp) {
+ BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status);
+
+ /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
+ * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
+ * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
+ * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
+ * The fix is to generate a release right after the press and drown the 'actual'
+ * release.
+ */
+ if ((key_map[i].release_quirk == 1) && (pressed == 0))
+ {
+ BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now",
+ __FUNCTION__, key_map[i].name);
+ return;
+ }
+#ifdef BTIF_RC_USE_UINPUT
+ send_key(uinput_fd, key_map[i].mapped_id, pressed);
+#endif
+ if ((key_map[i].release_quirk == 1) && (pressed == 1))
+ {
+ GKI_delay(30); // 30ms
+ BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now",
+ __FUNCTION__, key_map[i].name);
+#ifdef BTIF_RC_USE_UINPUT
+ send_key(uinput_fd, key_map[i].mapped_id, 0);
+#endif
+ }
+ break;
+ }
+ }
+
+ if (key_map[i].name == NULL)
+ BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
+ p_remote_cmd->rc_id, status);
+}
+
+/*****************************************************************************
+**
+** Function btif_rc_init
+**
+** Description Initialize RC
+**
+** Returns Returns 0 on success, -1 otherwise
+**
+*******************************************************************************/
+int btif_rc_init()
+{
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
+
+#ifdef BTIF_RC_USE_UINPUT
+ return uinput_driver_check();
+#endif /* BTIF_RC_USE_UINPUT */
+}
+
+/***************************************************************************
+ **
+ ** Function btif_rc_handler
+ **
+ ** Description RC event handler
+ **
+ ***************************************************************************/
+void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
+{
+ BTIF_TRACE_DEBUG2 ("%s event:%s", __FUNCTION__, dump_rc_event_name(event));
+ switch (event)
+ {
+ case BTA_AV_RC_OPEN_EVT:
+ {
+ BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_open.peer_features);
+ handle_rc_connect( &(p_data->rc_open) );
+ }break;
+
+ case BTA_AV_RC_CLOSE_EVT:
+ {
+ handle_rc_disconnect( &(p_data->rc_close) );
+ }break;
+
+ case BTA_AV_REMOTE_CMD_EVT:
+ {
+ BTIF_TRACE_DEBUG2("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id,
+ p_data->remote_cmd.key_state);
+ handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
+ }break;
+ default:
+ BTIF_TRACE_DEBUG0("Unhandled RC event");
+ }
+}
+
+/***************************************************************************
+ **
+ ** Function btif_rc_get_connected_peer
+ **
+ ** Description Fetches the connected headset's BD_ADDR if any
+ **
+ ***************************************************************************/
+BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
+{
+ if (btif_rc_cb.rc_connected == TRUE) {
+ bdcpy(peer_addr, btif_rc_cb.rc_addr);
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/include/buildcfg_crespo.h b/include/buildcfg_crespo.h
index 0060149..da4d475 100644
--- a/include/buildcfg_crespo.h
+++ b/include/buildcfg_crespo.h
@@ -2,7 +2,7 @@
#define BUILDCFG_H
#define AVCT_INCLUDED TRUE
#define AVRC_INCLUDED TRUE
-#define AVRC_METADATA_INCLUDED TRUE
+#define AVRC_METADATA_INCLUDED FALSE
#define AVRC_ADV_CTRL_INCLUDED FALSE
#define AVDT_INCLUDED TRUE
#define AVDTC_INCLUDED FALSE # Makefile only
diff --git a/include/buildcfg_maguro.h b/include/buildcfg_maguro.h
index a2e0123..196c792 100644
--- a/include/buildcfg_maguro.h
+++ b/include/buildcfg_maguro.h
@@ -2,7 +2,7 @@
#define BUILDCFG_H
#define AVCT_INCLUDED TRUE
#define AVRC_INCLUDED TRUE
-#define AVRC_METADATA_INCLUDED TRUE
+#define AVRC_METADATA_INCLUDED FALSE
#define AVRC_ADV_CTRL_INCLUDED FALSE
#define AVDT_INCLUDED TRUE
#define AVDTC_INCLUDED FALSE # Makefile only
diff --git a/main/Android.mk b/main/Android.mk
index 8e78c61..e1c17bc 100644
--- a/main/Android.mk
+++ b/main/Android.mk
@@ -25,7 +25,8 @@ LOCAL_SRC_FILES += \
../btif/src/btif_util.c \
../btif/src/btif_sm.c \
../btif/src/btif_hf.c \
- ../btif/src/btif_av.c
+ ../btif/src/btif_av.c \
+ ../btif/src/btif_rc.c
# callouts
LOCAL_SRC_FILES+= \