From f16fa26ac0721e9c9bcaf68879da09d9e86f5a6c Mon Sep 17 00:00:00 2001 From: AnubhavGupta Date: Thu, 28 Apr 2016 11:54:30 +0530 Subject: [PATCH] A2DP Sink: Changes to support A2DP Sink in N MCL - changes to enable A2DP Sink in N MCL. Change-Id: I281f435ce5c55a2e2440f124e034cf478e7624e7 --- Android.mk | 1 + bta/av/bta_av_act.c | 121 +++++++++++++++++++++++++------------------------ btif/include/btif_av.h | 1 + btif/src/btif_av.c | 24 ++++------ btif/src/btif_rc.c | 116 ++++++++++++----------------------------------- include/bt_target.h | 2 +- 6 files changed, 104 insertions(+), 161 deletions(-) diff --git a/Android.mk b/Android.mk index dc3c98131..6ff9c31d7 100644 --- a/Android.mk +++ b/Android.mk @@ -21,6 +21,7 @@ endif ifneq ($(TARGET_BUILD_VARIANT),user) bluetooth_CFLAGS += -DBLUEDROID_DEBUG +bluetooth_CFLAGS += -DUSE_AUDIO_TRACK endif bluetooth_CFLAGS += -DEXPORT_SYMBOL="__attribute__((visibility(\"default\")))" diff --git a/bta/av/bta_av_act.c b/bta/av/bta_av_act.c index a2bd4899b..88b135292 100644 --- a/bta/av/bta_av_act.c +++ b/bta/av/bta_av_act.c @@ -572,12 +572,12 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 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); @@ -1757,61 +1757,64 @@ tBTA_AV_FEAT bta_avk_check_peer_features (UINT16 service_uuid) { 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; @@ -1872,9 +1875,9 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data) 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 diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h index e78a1282b..99040eeea 100644 --- a/btif/include/btif_av.h +++ b/btif/include/btif_av.h @@ -32,6 +32,7 @@ #include "btif_sm.h" #include "bta_av_api.h" +#define BTIF_RC_HANDLE_NONE 0xFF /******************************************************************************* ** Type definitions for callback functions diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c index 41d4e4c1e..cc0f4cf30 100644 --- a/btif/src/btif_av.c +++ b/btif/src/btif_av.c @@ -144,7 +144,7 @@ static void btif_av_event_free_data(btif_sm_event_t event, void *p_data); *************************************************************************/ 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; @@ -236,7 +236,7 @@ static void btif_initiate_av_open_timer_timeout(UNUSED_ATTR void *data) 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; } @@ -437,10 +437,9 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data) 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); } @@ -551,7 +550,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data * 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; @@ -567,10 +566,9 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data 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); } @@ -1251,12 +1249,10 @@ bt_status_t btif_av_init(int service_id) 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(); } diff --git a/btif/src/btif_rc.c b/btif/src/btif_rc.c index 28c75459e..ec9f7425f 100644 --- a/btif/src/btif_rc.c +++ b/btif/src/btif_rc.c @@ -265,7 +265,6 @@ static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_G 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); @@ -435,6 +434,9 @@ void rc_cleanup_sent_cmd (void *p_data) 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))) @@ -449,18 +451,19 @@ void handle_rc_ctrl_features(BD_ADDR bd_addr) 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); @@ -542,13 +545,6 @@ void handle_rc_features(BD_ADDR bd_addr) } #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; - } } /*************************************************************************** @@ -1153,9 +1149,13 @@ BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr) ** 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; } /*************************************************************************** @@ -1612,6 +1612,8 @@ static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks ) 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; @@ -2017,7 +2019,8 @@ bool iterate_supported_event_list_for_timeout(void *data, void *cb_data) 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, @@ -2357,6 +2360,11 @@ static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_G 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) { @@ -2563,6 +2571,8 @@ static void handle_notification_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_REG { 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; @@ -2654,6 +2664,8 @@ static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_AP } else { + /* Complete RC procedure from here */ + rc_ctrl_procedure_complete(); BTIF_TRACE_ERROR("%s No Player application settings found", __FUNCTION__); } @@ -2734,21 +2746,7 @@ static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP } 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); } } @@ -3561,62 +3559,6 @@ static bt_status_t change_player_app_setting(bt_bdaddr_t *bd_addr, uint8_t num_a 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; -} /*************************************************************************** ** diff --git a/include/bt_target.h b/include/bt_target.h index e30d65a56..af40ba6fd 100644 --- a/include/bt_target.h +++ b/include/bt_target.h @@ -92,7 +92,7 @@ #endif #ifndef BTA_AV_SINK_INCLUDED -#define BTA_AV_SINK_INCLUDED FALSE +#define BTA_AV_SINK_INCLUDED TRUE #endif #ifndef BTA_DISABLE_DELAY -- 2.11.0