From 30c81fa85380a46613498aff26be8a82b6531859 Mon Sep 17 00:00:00 2001 From: Sanket Agarwal Date: Fri, 16 Sep 2016 15:41:18 -0700 Subject: [PATCH] Implement AVRCP SetAddressedPlayer Cmd Bug: b/31554234 Change-Id: I700bc1dc65f9c8c7d1e5e57c568487a53ae9fbf7 (cherry picked from commit 53ffd333c7e6db731a8db2e742dcd29d4416270c) --- btif/src/btif_rc.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++- stack/avrc/avrc_bld_ct.cc | 32 +++++++++++++- stack/avrc/avrc_pars_ct.cc | 9 ++++ 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc index 4abdfd521..ee21e4b3a 100644 --- a/btif/src/btif_rc.cc +++ b/btif/src/btif_rc.cc @@ -317,6 +317,7 @@ static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp); static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP* p_rsp); +static void handle_set_addressed_player_response(tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp); 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, @@ -4066,6 +4067,40 @@ static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, } /*************************************************************************** +** +** Function handle_set_addressed_player_response +** +** Description handles the the set addressed player response, calls +** HAL callback +** Returns None +** +***************************************************************************/ +static void handle_set_addressed_player_response(tBTA_AV_META_MSG *pmeta_msg, + tAVRC_RSP *p_rsp) { + bt_bdaddr_t rc_addr; + + btif_rc_device_cb_t* p_dev = + btif_rc_get_device_by_handle(pmeta_msg->rc_handle); + + if (p_dev == NULL) { + BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); + return; + } + + bdcpy(rc_addr.address, p_dev->rc_addr); + + if (p_rsp->status == AVRC_STS_NO_ERROR) { + HAL_CBACK(bt_rc_ctrl_callbacks, + set_addressed_player_cb, + &rc_addr, + p_rsp->status); + } else { + BTIF_TRACE_ERROR("%s: Error in get play status procedure %d", + __FUNCTION__, p_rsp->status); + } +} + +/*************************************************************************** * * Function handle_get_folder_items_response * @@ -4452,6 +4487,10 @@ static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) { handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status); break; + + case AVRC_PDU_SET_ADDRESSED_PLAYER: + handle_set_addressed_player_response(pmeta_msg, &avrc_response.rsp); + break; } } else if (AVRC_OP_BROWSE == pmeta_msg->p_msg->hdr.opcode) { BTIF_TRACE_DEBUG("%s AVRC_OP_BROWSE pdu %d", __func__, avrc_response.pdu); @@ -4996,7 +5035,67 @@ static bt_status_t set_browsed_player_cmd(bt_bdaddr_t* bd_addr, uint16_t id) { #endif } -#if (AVRC_CTRL_INCLUDED == TRUE) +/*************************************************************************** + ** + ** Function set_addressed_player_cmd + ** + ** Description Change the addressed player. + ** + ** Paramters id: The UID of player to move to + ** + ** Returns BT_STATUS_SUCCESS if command issued successfully otherwise + ** BT_STATUS_FAIL. + ** + ***************************************************************************/ +static bt_status_t set_addressed_player_cmd(bt_bdaddr_t *bd_addr, uint16_t id) +{ + BTIF_TRACE_DEBUG("%s id (%d)", __func__, id); +#if (AVRC_CTLR_INCLUDED == TRUE) + CHECK_RC_CONNECTED + CHECK_BR_CONNECTED + tAVRC_STS status = BT_STATUS_UNSUPPORTED; + rc_transaction_t *p_transaction = NULL; + + if (btif_rc_cb.br_connected) { + tAVRC_COMMAND avrc_cmd = {0}; + BT_HDR *p_msg = NULL; + + avrc_cmd.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER; + avrc_cmd.addr_player.status = AVRC_STS_NO_ERROR; + // TODO(sanketa): Improve for database aware clients. + avrc_cmd.addr_player.player_id = id; + + if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR) { + bt_status_t tran_status = get_transaction(&p_transaction); + if (BT_STATUS_SUCCESS == tran_status && p_transaction != NULL) { + BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", + __func__, p_transaction->lbl); + BTA_AvMetaCmd(btif_rc_cb.rc_handle, p_transaction->lbl, + AVRC_CMD_CTRL, p_msg); + status = BT_STATUS_SUCCESS; + } else { + osi_free(p_msg); + BTIF_TRACE_ERROR("%s: failed to obtain txn details. status: 0x%02x", + __func__, tran_status); + status = BT_STATUS_FAIL; + } + } else { + BTIF_TRACE_ERROR("%s failed to build command status %d", + __func__, status); + status = BT_STATUS_FAIL; + } + } else { + BTIF_TRACE_ERROR("%s command not supported by peer features %d", + __func__, btif_rc_cb.rc_features); + status = BT_STATUS_FAIL; + } + return status; +#else + BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __func__); + return BT_STATUS_FAIL; +#endif +} + /*************************************************************************** * * Function get_folder_items_cmd @@ -5065,7 +5164,6 @@ static bt_status_t get_folder_items_cmd(bt_bdaddr_t* bd_addr, uint8_t scope, } return (bt_status_t)status; } -#endif /*************************************************************************** * @@ -5672,6 +5770,7 @@ static const btrc_ctrl_interface_t bt_rc_ctrl_interface = { get_player_list_cmd, change_folder_path_cmd, set_browsed_player_cmd, + set_addressed_player_cmd, set_volume_rsp, volume_change_notification_rsp, cleanup_ctrl, diff --git a/stack/avrc/avrc_bld_ct.cc b/stack/avrc/avrc_bld_ct.cc index 2c3a4d82e..04ce575f3 100644 --- a/stack/avrc/avrc_bld_ct.cc +++ b/stack/avrc/avrc_bld_ct.cc @@ -442,7 +442,7 @@ static tAVRC_STS avrc_bld_change_folder_cmd(BT_HDR *p_pkt, const tAVRC_CHG_PATH_ ** ** Function avrc_bld_set_browsed_player_cmd ** -** Description This function builds the set addressed player cmd. +** Description This function builds the set browsed player cmd. ** ** Returns AVRC_STS_NO_ERROR, if the command is built successfully ** Otherwise, the error code. @@ -464,6 +464,33 @@ static tAVRC_STS avrc_bld_set_browsed_player_cmd(BT_HDR *p_pkt, const tAVRC_SET_ p_pkt->len = (p_data - p_start); return AVRC_STS_NO_ERROR; } + +/******************************************************************************* +** +** Function avrc_bld_set_addressed_player_cmd +** +** Description This function builds the set addressed player cmd. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_set_addressed_player_cmd( + BT_HDR *p_pkt, const tAVRC_SET_ADDR_PLAYER_CMD *cmd) +{ + AVRC_TRACE_API("%s", __func__); + /* get the existing length, if any, and also the num attributes */ + uint8_t *p_start = (uint8_t *)(p_pkt + 1) + p_pkt->offset; + uint8_t *p_data = p_data = p_start + 2; /* pdu + rsvd */ + + /* To change addressed player the following is the total length: + * Player ID (2) + */ + UINT16_TO_BE_STREAM(p_data, 2); /* fixed length */ + UINT16_TO_BE_STREAM(p_data, cmd->player_id); + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} #endif /******************************************************************************* @@ -627,6 +654,9 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt) case AVRC_PDU_SET_BROWSED_PLAYER: status = avrc_bld_set_browsed_player_cmd(p_pkt, &(p_cmd->br_player)); break; + case AVRC_PDU_SET_ADDRESSED_PLAYER: + status = avrc_bld_set_addressed_player_cmd(p_pkt, &(p_cmd->addr_player)); + break; #endif } diff --git a/stack/avrc/avrc_pars_ct.cc b/stack/avrc/avrc_pars_ct.cc index 40667e317..a4b98cbe5 100644 --- a/stack/avrc/avrc_pars_ct.cc +++ b/stack/avrc/avrc_pars_ct.cc @@ -619,6 +619,15 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( BE_STREAM_TO_UINT8(p_result->get_play_status.status, p); break; + case AVRC_PDU_SET_ADDRESSED_PLAYER: + if (len != 1) + { + AVRC_TRACE_ERROR("%s pdu: %d len %d", __func__, p_result->pdu, len); + return AVRC_STS_BAD_CMD; + } + BE_STREAM_TO_UINT8(p_result->rsp.status, p); + break; + default: return AVRC_STS_BAD_CMD; } -- 2.11.0