- changes to enable A2DP Sink in N MCL.
Change-Id: I281f435ce5c55a2e2440f124e034cf478e7624e7
ifneq ($(TARGET_BUILD_VARIANT),user)
bluetooth_CFLAGS += -DBLUEDROID_DEBUG
+bluetooth_CFLAGS += -DUSE_AUDIO_TRACK
endif
bluetooth_CFLAGS += -DEXPORT_SYMBOL="__attribute__((visibility(\"default\")))"
if (rc_open.peer_features == 0)
{
/* we have not done SDP on peer RC capabilities.
- * peer must have initiated the RC connection */
- if (p_cb->features & BTA_AV_FEAT_RCCT)
- rc_open.peer_features |= BTA_AV_FEAT_RCTG;
+ * peer must have initiated the RC connection
+ * We Don't have SDP records of Peer, so we by
+ * default will take values depending upon registered
+ * features */
if (p_cb->features & BTA_AV_FEAT_RCTG)
rc_open.peer_features |= BTA_AV_FEAT_RCCT;
-
bta_av_rc_disc(disc);
}
(*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);
{
tBTA_AV_FEAT peer_features = 0;
tBTA_AV_CB *p_cb = &bta_av_cb;
+ tSDP_DISC_REC *p_rec = NULL;
+ tSDP_DISC_ATTR *p_attr;
+ UINT16 peer_rc_version = 0;
+ UINT16 categories = 0;
+ BOOLEAN val;
APPL_TRACE_DEBUG("%s service_uuid:x%x", __FUNCTION__, service_uuid);
-
- /* loop through all records we found */
- tSDP_DISC_REC *p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, NULL);
- while (p_rec)
- {
- APPL_TRACE_DEBUG("%s found Service record for x%x", __FUNCTION__, service_uuid);
-
- if (( SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) != NULL)
- {
- /* find peer features */
- if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL))
- {
- peer_features |= BTA_AV_FEAT_RCCT;
- }
- if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL))
- {
- peer_features |= BTA_AV_FEAT_RCTG;
- }
- }
-
- if (( SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL)
- {
- /* get profile version (if failure, version parameter is not updated) */
- UINT16 peer_rc_version = 0;
- BOOLEAN val = SDP_FindProfileVersionInRec(
- p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
- APPL_TRACE_DEBUG("%s peer_rc_version for TG 0x%x, profile_found %d",
- __FUNCTION__, peer_rc_version, val);
-
- if (peer_rc_version >= AVRC_REV_1_3)
- peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
-
- /*
- * Though Absolute Volume came after in 1.4 and above, but there are few devices
- * in market which supports absolute Volume and they are still 1.3
- * TO avoid IOT issuses with those devices, we check for 1.3 as minimum version
- */
- if (peer_rc_version >= AVRC_REV_1_3)
- {
- /* get supported categories */
- tSDP_DISC_ATTR *p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
- if (p_attr != NULL)
- {
- UINT16 categories = p_attr->attr_value.v.u16;
- if (categories & AVRC_SUPF_CT_CAT2)
- peer_features |= (BTA_AV_FEAT_ADV_CTRL);
- if (categories & AVRC_SUPF_CT_APP_SETTINGS)
- peer_features |= (BTA_AV_FEAT_APP_SETTING);
- }
- }
+ /* get next record; if none found, we're done */
+ p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec);
+ if (p_rec != NULL)
+ {
+ APPL_TRACE_DEBUG(" %s found Service record for x%x", __FUNCTION__, service_uuid);
+ if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL)
+ peer_features |= BTA_AV_FEAT_RCCT;
+ else if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET)
+ peer_features |= BTA_AV_FEAT_RCTG;
+
+ if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL)
+ {
+ /* profile version (if failure, version parameter is not updated) */
+ val = SDP_FindProfileVersionInRec(p_rec,
+ UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
+ APPL_TRACE_DEBUG("%s rc_version for TG 0x%x, profile_found %d", __FUNCTION__,
+ peer_rc_version, val);
+
+ if (peer_rc_version < AVRC_REV_1_3)
+ return peer_features;
+
+ p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
+ if (p_attr == NULL)
+ return peer_features;
+
+ categories = p_attr->attr_value.v.u16;
+
+ if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET)
+ {
+ peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
+ /* get supported categories */
+ if (categories & AVRC_SUPF_CT_BROWSE)
+ peer_features |= BTA_AV_FEAT_BROWSE;
+ if (categories & AVRC_SUPF_CT_APP_SETTINGS)
+ peer_features |= BTA_AV_FEAT_APP_SETTING;
+ }
+ /*
+ * Absolute Volume came after in 1.4 and above.
+ * but there are few devices in market which supports.
+ * absoluteVolume and they are still 1.3 To avoid inter-operatibility issuses with.
+ * those devices, we check for 1.3 as minimum version.
+ */
+ else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL)
+ {
+ if (categories & AVRC_SUPF_CT_CAT2)
+ {
+ APPL_TRACE_DEBUG(" %s Remote supports ABS Vol", __FUNCTION__);
+ peer_features |= BTA_AV_FEAT_ADV_CTRL;
+ }
+ }
}
- /* get next record; if none found, we're done */
- p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec);
}
APPL_TRACE_DEBUG("%s peer_features:x%x", __FUNCTION__, peer_features);
return peer_features;
if (p_cb->sdp_a2d_snk_handle)
{
/* This is Sink + CT + TG(Abs Vol) */
- peer_features = bta_avk_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
- if (BTA_AV_FEAT_ADV_CTRL & bta_avk_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL))
- peer_features |= (BTA_AV_FEAT_ADV_CTRL|BTA_AV_FEAT_RCCT);
+ peer_features = bta_avk_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL);
+ peer_features |= bta_avk_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
+ APPL_TRACE_DEBUG("final rc_features %x", peer_features);
}
else
#endif
#include "btif_sm.h"
#include "bta_av_api.h"
+#define BTIF_RC_HANDLE_NONE 0xFF
/*******************************************************************************
** Type definitions for callback functions
*************************************************************************/
extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
-extern UINT8 btif_rc_get_connected_peer_handle(void);
+extern UINT8 btif_rc_get_connected_peer_handle(BD_ADDR peer_addr);
extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
extern fixed_queue_t *btu_general_alarm_queue;
if(bdcmp(btif_av_cb.peer_bda.address, peer_addr))
{
BTIF_TRACE_DEBUG("%s A2DP Connection Already UP", __FUNCTION__);
- BTA_AvCloseRc(btif_rc_get_connected_peer_handle());
+ BTA_AvCloseRc(btif_rc_get_connected_peer_handle(peer_addr));
BTIF_TRACE_WARNING("%s Disconnecting AVRCP", __FUNCTION__);
return;
}
btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
(p_bta_data->open.status == BTA_AV_SUCCESS));
}
- else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+ else if ((btif_av_cb.peer_sep == AVDT_TSEP_SRC) &&
+ (p_bta_data->open.status == BTA_AV_SUCCESS))
{
- /* if queued PLAY command, send it now */
- btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
/* Bring up AVRCP connection too */
BTA_AvOpenRc(btif_av_cb.bta_handle);
}
* A2DP conneciton failed, for any reason
*/
BTIF_TRACE_WARNING(" Disconnecting AVRCP ");
- BTA_AvCloseRc(btif_rc_get_connected_peer_handle());
+ BTA_AvCloseRc(btif_rc_get_connected_peer_handle(peer_addr));
}
state = BTAV_CONNECTION_STATE_DISCONNECTED;
av_state = BTIF_AV_STATE_IDLE;
btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
(p_bta_data->open.status == BTA_AV_SUCCESS));
}
- else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+ else if ((btif_av_cb.peer_sep == AVDT_TSEP_SRC) &&
+ (p_bta_data->open.status == BTA_AV_SUCCESS))
{
- /* if queued PLAY command, send it now */
- btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
/* Bring up AVRCP connection too */
BTA_AvOpenRc(btif_av_cb.bta_handle);
}
if (!btif_a2dp_start_media_task())
return BT_STATUS_FAIL;
- btif_enable_service(service_id);
-
/* 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);
-
+ btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers,
+ BTIF_AV_STATE_IDLE);
+ btif_enable_service(service_id);
btif_a2dp_on_init();
}
static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_ELEM_ATTRS_RSP *p_rsp);
static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp);
static bt_status_t get_play_status_cmd(void);
-static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs);
static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals);
static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value);
static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids);
void handle_rc_ctrl_features(BD_ADDR bd_addr)
{
+ BTIF_TRACE_DEBUG(" %s rc_feat_processed = %d", __FUNCTION__, btif_rc_cb.rc_features_processed);
+ if (btif_rc_cb.rc_features_processed == TRUE)
+ return;
if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
}
if ((btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)&&
- (btif_rc_cb.rc_features & BTA_AV_FEAT_VENDOR)&&
- (btif_rc_cb.rc_features_processed != TRUE))
+ (btif_rc_cb.rc_features & BTA_AV_FEAT_VENDOR))
{
rc_features |= BTRC_FEAT_METADATA;
/* Mark rc features processed to avoid repeating
* the AVRCP procedure every time on receiving this
* update.
*/
- btif_rc_cb.rc_features_processed = TRUE;
-
- if (btif_av_is_sink_enabled())
+ if ((btif_rc_cb.rc_features_processed == FALSE) &&
+ btif_av_is_sink_enabled())
+ {
+ btif_rc_cb.rc_features_processed = TRUE;
getcapabilities_cmd (AVRC_CAP_COMPANY_ID);
+ }
}
BTIF_TRACE_DEBUG("%s Update rc features to CTRL %d", __FUNCTION__, rc_features);
HAL_CBACK(bt_rc_ctrl_callbacks, getrcfeatures_cb, &rc_addr, rc_features);
}
#endif
}
- else {
- /*Disable all TG related bits if AVRCP TG feature is not enabled*/
- BTIF_TRACE_WARNING("Avrcp TG role not enabled, disabling TG specific featuremask");
- btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
- btif_rc_cb.rc_features &= ~BTA_AV_FEAT_BROWSE;
- btif_rc_cb.rc_features &= ~BTA_AV_FEAT_METADATA;
- }
}
/***************************************************************************
** Description Fetches the connected headset's handle if any
**
***************************************************************************/
-UINT8 btif_rc_get_connected_peer_handle(void)
+UINT8 btif_rc_get_connected_peer_handle(BD_ADDR peer_addr)
{
- return btif_rc_cb.rc_handle;
+ if (btif_rc_cb.rc_connected && !bdcmp(peer_addr, btif_rc_cb.rc_addr))
+ {
+ return btif_rc_cb.rc_handle;
+ }
+ return BTIF_RC_HANDLE_NONE;
}
/***************************************************************************
memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
btif_rc_cb.rc_vol_label=MAX_LABEL;
btif_rc_cb.rc_volume=MAX_VOLUME;
+ btif_rc_cb.rc_features_processed = FALSE;
+ btif_rc_cb.rc_handle = BTIF_RC_HANDLE_NONE;
lbl_init();
return result;
static void rc_notification_interim_timout (UINT8 label)
{
list_node_t *node;
-
+ if (btif_rc_cb.rc_supported_event_list == NULL)
+ return;
list_foreach(btif_rc_cb.rc_supported_event_list,
iterate_supported_event_list_for_timeout, &label);
/* Timeout happened for interim response for the registered event,
list_append(btif_rc_cb.rc_supported_event_list, p_event);
}
}
+ if (list_is_empty(btif_rc_cb.rc_supported_event_list))
+ {
+ BTIF_TRACE_EVENT(" Supported event list Empty, returning");
+ return;
+ }
p_event = list_front(btif_rc_cb.rc_supported_event_list);
if (p_event != NULL)
{
{
break;
}
+ UINT8 *p_data = p_rsp->param.track;
+ BE_STREAM_TO_UINT64(btif_rc_cb.rc_playing_uid, p_data);
get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
break;
}
else
{
+ /* Complete RC procedure from here */
+ rc_ctrl_procedure_complete();
BTIF_TRACE_ERROR("%s No Player application settings found",
__FUNCTION__);
}
}
attr_index++;
p_app_settings->ext_attr_index++;
- if (attr_index < p_app_settings->num_ext_attrs)
- {
- list_player_app_setting_value_cmd (p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id);
- }
- else
- {
- UINT8 attr[AVRC_MAX_APP_ATTR_SIZE];
- UINT8 xx;
-
- for (xx = 0; xx < p_app_settings->num_ext_attrs; xx++)
- {
- attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
- }
- get_player_app_setting_attr_text_cmd(attr, xx);
- }
+ list_player_app_setting_value_cmd (p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id);
}
}
return status;
}
-/***************************************************************************
-**
-** Function get_player_app_setting_attr_text_cmd
-**
-** Description Get text description for app attribute
-**
-** Returns void
-**
-***************************************************************************/
-static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs)
-{
- tAVRC_STS status = BT_STATUS_UNSUPPORTED;
- rc_transaction_t *p_transaction = NULL;
- int count = 0;
-#if (AVRC_CTLR_INCLUDED == TRUE)
- tAVRC_COMMAND avrc_cmd = {0};
- BT_HDR *p_msg = NULL;
- bt_status_t tran_status;
- CHECK_RC_CONNECTED
-
- BTIF_TRACE_DEBUG("%s: num attrs %d", __FUNCTION__, num_attrs);
-
- tran_status = get_transaction(&p_transaction);
- if (BT_STATUS_SUCCESS != tran_status)
- return BT_STATUS_FAIL;
-
- avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
- avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
- avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
-
- for (count = 0; count < num_attrs; count++)
- {
- avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
- }
- status = AVRC_BldCommand(&avrc_cmd, &p_msg);
- if (status == AVRC_STS_NO_ERROR)
- {
- UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
- BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
- __FUNCTION__, p_transaction->lbl);
- BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
- AVRC_CMD_STATUS, data_start, p_msg->len);
- osi_free(p_msg);
- status = BT_STATUS_SUCCESS;
- start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT, p_transaction);
- }
- else
- {
- BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
- }
- osi_free(p_msg);
-#else
- BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
-#endif
- return status;
-}
/***************************************************************************
**
#endif
#ifndef BTA_AV_SINK_INCLUDED
-#define BTA_AV_SINK_INCLUDED FALSE
+#define BTA_AV_SINK_INCLUDED TRUE
#endif
#ifndef BTA_DISABLE_DELAY