OSDN Git Service

resolve merge conflicts of 760fb7083b to master.
authorAndre Eisenbach <eisenbach@google.com>
Fri, 15 Jan 2016 20:23:15 +0000 (12:23 -0800)
committerAndre Eisenbach <eisenbach@google.com>
Fri, 15 Jan 2016 20:23:42 +0000 (12:23 -0800)
Change-Id: Ic5d10e4a80d53f916ec61e75d01a0e08df6114cf

1  2 
btif/src/btif_rc.c

@@@ -1950,2113 -1583,89 +1950,2108 @@@ static void handle_rc_metamsg_rsp(tBTA_
                                  pmeta_msg->label);
  }
  
 +#if (AVRC_CTLR_INCLUDED == TRUE)
  /***************************************************************************
  **
 -** Function         cleanup
 -**
 -** Description      Closes the AVRC interface
 +** Function         iterate_supported_event_list_for_interim_rsp
  **
 -** Returns          void
 +** Description      iterator callback function to match the event and handle
 +**                  timer cleanup
- ** Returns          true if matches with the event, flase otherwise
++** Returns          true to continue iterating, false to stop
  **
  ***************************************************************************/
 -static void cleanup()
 +bool iterate_supported_event_list_for_interim_rsp(void *data, void *cb_data)
  {
 -    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
 -    close_uinput();
 -    if (bt_rc_callbacks)
 +    UINT8 *p_event_id;
 +    btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
 +
 +    p_event_id = (UINT8*)cb_data;
 +
 +    if (p_event->event_id == *p_event_id)
      {
 -        bt_rc_callbacks = NULL;
 +        p_event->status = eINTERIM;
-         return true;
++        return false;
      }
-     return false;
 -    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
 -    lbl_destroy();
 -    BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
++    return true;
  }
  
  /***************************************************************************
  **
 -** Function         cleanup_ctrl
 -**
 -** Description      Closes the AVRC Controller interface
 +** Function         iterate_supported_event_list_for_timeout
  **
 -** Returns          void
 +** Description      Iterator callback function for timeout handling.
 +**                  As part of the failure handling, it releases the
 +**                  transaction label and removes the event from list,
 +**                  this event will not be requested again during
 +**                  the lifetime of the connection.
- ** Returns          true if matches with the event, flase otherwise
++** Returns          false to stop iterating, true to continue
  **
  ***************************************************************************/
 -static void cleanup_ctrl()
 +bool iterate_supported_event_list_for_timeout(void *data, void *cb_data)
  {
 -    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
 +    UINT8 label;
-     UINT32 cb_value;
 +    btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
  
-     cb_value = (UINT32)cb_data;
-     label = cb_value & 0xFF;
 -    if (bt_rc_ctrl_callbacks)
++    label = (*(UINT8*)cb_data) & 0xFF;
 +
 +    if (p_event->label == label)
      {
 -        bt_rc_ctrl_callbacks = NULL;
 +        list_remove(btif_rc_cb.rc_supported_event_list, p_event);
-         return true;
++        return false;
      }
-     return false;
 -    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
 -    lbl_destroy();
 -    BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
++    return true;
  }
  
 -static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
 +/***************************************************************************
 +**
 +** Function         rc_notification_interim_timout
 +**
 +** Description      Interim response timeout handler.
 +**                  Runs the iterator to check and clear the timed out event.
 +**                  Proceeds to register for the unregistered events.
 +** Returns          None
 +**
 +***************************************************************************/
 +static void rc_notification_interim_timout (UINT8 label)
  {
 -    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 -#if (AVRC_CTLR_INCLUDED == TRUE)
 -    CHECK_RC_CONNECTED
 -    rc_transaction_t *p_transaction=NULL;
 -    BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
 -                                                    key_code, key_state);
 -    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
 +    list_node_t *node;
-     UINT32 cb_data;
 +
-     cb_data = label;
-     list_foreach_ext(btif_rc_cb.rc_supported_event_list,
-                      iterate_supported_event_list_for_timeout, (void*)cb_data);
++    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,
 +     * check if there are any pending for registration
 +     */
 +    node = list_begin(btif_rc_cb.rc_supported_event_list);
 +    while (node != NULL)
      {
 -        bt_status_t tran_status = get_transaction(&p_transaction);
 -        if(BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
 -        {
 -            BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
 -                (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
 -            status =  BT_STATUS_SUCCESS;
 -            BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
 -        }
 -        else
 +        btif_rc_supported_event_t *p_event;
 +
 +        p_event = (btif_rc_supported_event_t *)list_node(node);
 +        if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
          {
 -            status =  BT_STATUS_FAIL;
 -            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
 +            register_for_event_notification(p_event);
 +            break;
          }
 +        node = list_next (node);
      }
 -    else
 -    {
 -        status =  BT_STATUS_FAIL;
 -        BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
 -    }
 -#else
 -    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 -#endif
 -    return status;
 +    /* Todo. Need to initiate application settings query if this
 +     * is the last event registration.
 +     */
  }
  
 -static const btrc_interface_t bt_rc_interface = {
 -    sizeof(bt_rc_interface),
 -    init,
 -    get_play_status_rsp,
 +/***************************************************************************
 +**
 +** Function         rc_timeout_callback
 +**
 +** Description      RC timeout callback.
 +**                  This is called from BTU context and switches to BTIF
 +**                  context to handle the timeout events
 +** Returns          None
 +**
 +***************************************************************************/
 +static void rc_timeout_callback (timer_entry_t *tle)
 +{
 +    char *p_data = (char*)tle->data;
 +
 +    tle->data = NULL;
 +    btif_transfer_context(rc_timeout_handler, 0,
 +                  p_data, sizeof(btif_rc_timer_context_t), NULL);
 +    osi_freebuf (p_data);
 +}
 +
 +/***************************************************************************
 +**
 +** Function         rc_start_play_status_timer
 +**
 +** Description      Helper function to start the timer to fetch play status.
 +** Returns          None
 +**
 +***************************************************************************/
 +void rc_start_play_status_timer ()
 +{
 +    btif_rc_timer_context_t *p_rc_timer_context;
 +    /* Start the Play status timer only if it is not started */
 +    if (btif_rc_cb.tle_rc_play_status.data == NULL)
 +    {
 +        p_rc_timer_context = (btif_rc_timer_context_t*) osi_getbuf(sizeof(btif_rc_timer_context_t));
 +        if (p_rc_timer_context != NULL)
 +        {
 +            p_rc_timer_context->timer_id = RC_TIMER_PLAY_STATUS;
 +            memset(&btif_rc_cb.tle_rc_play_status, 0, sizeof(timer_entry_t));
 +            btif_rc_cb.tle_rc_play_status.param = rc_timeout_callback;
 +            btif_rc_cb.tle_rc_play_status.data = p_rc_timer_context;
 +            btu_start_timer(&btif_rc_cb.tle_rc_play_status, BTU_TTYPE_USER_FUNC,
 +                    BTIF_TIMEOUT_RC_INTERIM_RSP);
 +        }
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         rc_stop_play_status_timer
 +**
 +** Description      Helper function to stop the play status timer.
 +** Returns          None
 +**
 +***************************************************************************/
 +void rc_stop_play_status_timer ()
 +{
 +    if (btif_rc_cb.tle_rc_play_status.data != NULL)
 +    {
 +        btu_stop_timer (&btif_rc_cb.tle_rc_play_status);
 +        osi_freebuf(btif_rc_cb.tle_rc_play_status.data);
 +        btif_rc_cb.tle_rc_play_status.data = NULL;
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         rc_timeout_handler
 +**
 +** Description      RC timeout handler (Runs in BTIF context).
 +**                  main handler for all the timers created from RC module
 +** Returns          None
 +**
 +***************************************************************************/
 +static void rc_timeout_handler (UINT16 event, char* p_data)
 +{
 +    btif_rc_timer_context_t *p_rc_timer_context;
 +    tAVRC_RESPONSE      avrc_response = {0};
 +    tBTA_AV_META_MSG    meta_msg;
 +
 +    p_rc_timer_context = (btif_rc_timer_context_t *)p_data;
 +    memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
 +    meta_msg.rc_handle = btif_rc_cb.rc_handle;
 +
 +    switch (p_rc_timer_context->timer_id)
 +    {
 +        case RC_TIMER_STATUS_CMD:
 +            switch (p_rc_timer_context->rc_status_cmd.pdu_id)
 +            {
 +                case AVRC_PDU_REGISTER_NOTIFICATION:
 +                    rc_notification_interim_timout(
 +                                    p_rc_timer_context->rc_status_cmd.label);
 +                    break;
 +
 +                case AVRC_PDU_GET_CAPABILITIES:
 +                    avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
 +                    break;
 +
 +                case AVRC_PDU_LIST_PLAYER_APP_ATTR:
 +                    avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
 +                    break;
 +
 +                case AVRC_PDU_LIST_PLAYER_APP_VALUES:
 +                    avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
 +                    break;
 +
 +                case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
 +                    avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
 +                    break;
 +
 +                case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
 +                    avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
 +                    break;
 +
 +                case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
 +                    avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
 +                    break;
 +
 +                case AVRC_PDU_GET_ELEMENT_ATTR:
 +                    avrc_response.get_elem_attrs.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_get_elem_attr_response(&meta_msg, &avrc_response.get_elem_attrs);
 +                    break;
 +
 +                case AVRC_PDU_GET_PLAY_STATUS:
 +                    avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
 +                    break;
 +            }
 +            release_transaction (p_rc_timer_context->rc_status_cmd.label);
 +            break;
 +
 +        case RC_TIMER_CONTROL_CMD:
 +            switch (p_rc_timer_context->rc_control_cmd.pdu_id)
 +            {
 +                case AVRC_PDU_SET_PLAYER_APP_VALUE:
 +                    avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
 +                    handle_set_app_attr_val_response(&meta_msg, &avrc_response.set_app_val);
 +                    break;
 +            }
 +            release_transaction (p_rc_timer_context->rc_control_cmd.label);
 +            break;
 +
 +        case RC_TIMER_PLAY_STATUS:
 +            get_play_status_cmd();
 +            rc_start_play_status_timer();
 +            break;
 +
 +        default:
 +            BTIF_TRACE_ERROR("%s Error unknown timer id %d",
 +                __FUNCTION__, p_rc_timer_context->timer_id);
 +            break;
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         register_for_event_notification
 +**
 +** Description      Helper function registering notification events
 +**                  sets an interim response timeout to handle if the remote
 +**                  does not respond.
 +** Returns          None
 +**
 +***************************************************************************/
 +static void register_for_event_notification (btif_rc_supported_event_t *p_event)
 +{
 +    bt_status_t status;
 +    rc_transaction_t *p_transaction;
 +
 +    status = get_transaction(&p_transaction);
 +    if (status == BT_STATUS_SUCCESS)
 +    {
 +        btif_rc_timer_context_t *p_rc_timer_context;
 +
 +        status = register_notification_cmd (p_transaction->lbl, p_event->event_id, 0);
 +        if (status != BT_STATUS_SUCCESS)
 +        {
 +            BTIF_TRACE_ERROR("%s Error in Notification registration %d",
 +                __FUNCTION__, status);
 +            release_transaction (p_transaction->lbl);
 +            return;
 +        }
 +        p_event->label = p_transaction->lbl;
 +        p_event->status = eREGISTERED;
 +        p_rc_timer_context = (btif_rc_timer_context_t*) osi_getbuf(sizeof(btif_rc_timer_context_t));
 +        if (p_rc_timer_context != NULL)
 +        {
 +            p_rc_timer_context->timer_id = RC_TIMER_STATUS_CMD;
 +            p_rc_timer_context->rc_status_cmd.label = p_transaction->lbl;
 +            p_rc_timer_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION;
 +            memset(&p_transaction->tle_txn, 0, sizeof(timer_entry_t));
 +            p_transaction->tle_txn.param = rc_timeout_callback;
 +            p_transaction->tle_txn.data = p_rc_timer_context;
 +            btu_start_timer(&p_transaction->tle_txn, BTU_TTYPE_USER_FUNC,
 +                    BTIF_TIMEOUT_RC_INTERIM_RSP);
 +        }
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s Error No more Transaction label %d",
 +            __FUNCTION__, status);
 +    }
 +}
 +
 +static void start_status_command_timer (UINT8 pdu_id, rc_transaction_t *p_txn)
 +{
 +    bt_status_t status;
 +    btif_rc_timer_context_t *p_rc_timer_context;
 +
 +    p_rc_timer_context = (btif_rc_timer_context_t*) osi_getbuf(sizeof(btif_rc_timer_context_t));
 +    if (p_rc_timer_context != NULL)
 +    {
 +        p_rc_timer_context->timer_id = RC_TIMER_STATUS_CMD;
 +        p_rc_timer_context->rc_status_cmd.label = p_txn->lbl;
 +        p_rc_timer_context->rc_status_cmd.pdu_id = pdu_id;
 +
 +        memset(&p_txn->tle_txn, 0, sizeof(timer_entry_t));
 +        p_txn->tle_txn.param = rc_timeout_callback;
 +        p_txn->tle_txn.data = p_rc_timer_context;
 +        btu_start_timer(&p_txn->tle_txn, BTU_TTYPE_USER_FUNC,
 +                BTIF_TIMEOUT_RC_STATUS_CMD);
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s Getbuf failed while starting command timer",
 +            __FUNCTION__);
 +    }
 +}
 +
 +static void start_control_command_timer (UINT8 pdu_id, rc_transaction_t *p_txn)
 +{
 +    bt_status_t status;
 +    btif_rc_timer_context_t *p_rc_timer_context;
 +
 +    p_rc_timer_context = (btif_rc_timer_context_t*) osi_getbuf(sizeof(btif_rc_timer_context_t));
 +    if (p_rc_timer_context != NULL)
 +    {
 +        p_rc_timer_context->timer_id = RC_TIMER_CONTROL_CMD;
 +        p_rc_timer_context->rc_control_cmd.label = p_txn->lbl;
 +        p_rc_timer_context->rc_control_cmd.pdu_id = pdu_id;
 +
 +        memset(&p_txn->tle_txn, 0, sizeof(timer_entry_t));
 +        p_txn->tle_txn.param = rc_timeout_callback;
 +        p_txn->tle_txn.data = p_rc_timer_context;
 +        btu_start_timer(&p_txn->tle_txn, BTU_TTYPE_USER_FUNC,
 +                BTIF_TIMEOUT_RC_CONTROL_CMD);
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s Getbuf failed while starting command timer",
 +            __FUNCTION__);
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_get_capability_response
 +**
 +** Description      Handles the get_cap_response to populate company id info
 +**                  and query the supported events.
 +**                  Initiates Notification registration for events supported
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp)
 +{
 +    int xx = 0;
 +
 +    /* Todo: Do we need to retry on command timeout */
 +    if (p_rsp->status != AVRC_STS_NO_ERROR)
 +    {
 +        BTIF_TRACE_ERROR("%s Error capability response 0x%02X",
 +                __FUNCTION__, p_rsp->status);
 +        return;
 +    }
 +
 +    if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED)
 +    {
 +        btif_rc_supported_event_t *p_event;
 +
 +        /* Todo: Check if list can be active when we hit here */
 +        btif_rc_cb.rc_supported_event_list = list_new(rc_supported_event_free);
 +        for (xx = 0; xx < p_rsp->count; xx++)
 +        {
 +            /* Skip registering for Play position change notification */
 +            if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE)||
 +                (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE)||
 +                (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE))
 +            {
 +                p_event = (btif_rc_supported_event_t*) osi_getbuf(sizeof(btif_rc_supported_event_t));
 +                p_event->event_id = p_rsp->param.event_id[xx];
 +                p_event->status = eNOT_REGISTERED;
 +                list_append(btif_rc_cb.rc_supported_event_list, p_event);
 +            }
 +        }
 +        p_event = list_front(btif_rc_cb.rc_supported_event_list);
 +        if (p_event != NULL)
 +        {
 +            register_for_event_notification(p_event);
 +        }
 +    }
 +    else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID)
 +    {
 +        getcapabilities_cmd (AVRC_CAP_EVENTS_SUPPORTED);
 +        BTIF_TRACE_EVENT("%s AVRC_CAP_COMPANY_ID: ", __FUNCTION__);
 +        for (xx = 0; xx < p_rsp->count; xx++)
 +        {
 +            BTIF_TRACE_EVENT("%s    : %d", __FUNCTION__, p_rsp->param.company_id[xx]);
 +        }
 +    }
 +}
 +
 +bool rc_is_track_id_valid (tAVRC_UID uid)
 +{
 +    tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 +
 +    if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0)
 +    {
 +        return false;
 +    }
 +    else
 +    {
 +        return true;
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_notification_response
 +**
 +** Description      Main handler for notification responses to registered events
 +**                  1. Register for unregistered event(in interim response path)
 +**                  2. After registering for all supported events, start
 +**                     retrieving application settings and values
 +**                  3. Reregister for events on getting changed response
 +**                  4. Run play status timer for getting position when the
 +**                     status changes to playing
 +**                  5. Get the Media details when the track change happens
 +**                     or track change interim response is received with
 +**                     valid track id
 +**                  6. HAL callback for play status change and application
 +**                     setting change
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_notification_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_REG_NOTIF_RSP *p_rsp)
 +{
 +    bt_bdaddr_t rc_addr;
 +    UINT32 attr_list[] = {
 +        AVRC_MEDIA_ATTR_ID_TITLE,
 +        AVRC_MEDIA_ATTR_ID_ARTIST,
 +        AVRC_MEDIA_ATTR_ID_ALBUM,
 +        AVRC_MEDIA_ATTR_ID_TRACK_NUM,
 +        AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
 +        AVRC_MEDIA_ATTR_ID_GENRE,
 +        AVRC_MEDIA_ATTR_ID_PLAYING_TIME
 +        };
 +
 +
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    if (pmeta_msg->code == AVRC_RSP_INTERIM)
 +    {
 +        btif_rc_supported_event_t *p_event;
 +        list_node_t *node;
 +
 +        BTIF_TRACE_DEBUG("%s Interim response : 0x%2X ", __FUNCTION__, p_rsp->event_id);
 +        switch (p_rsp->event_id)
 +        {
 +            case AVRC_EVT_PLAY_STATUS_CHANGE:
 +                /* Start timer to get play status periodically
 +                 * if the play state is playing.
 +                 */
 +                if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
 +                {
 +                    rc_start_play_status_timer();
 +                }
 +                HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
 +                    &rc_addr, p_rsp->param.play_status);
 +                break;
 +
 +            case AVRC_EVT_TRACK_CHANGE:
 +                if (rc_is_track_id_valid (p_rsp->param.track) != true)
 +                {
 +                    break;
 +                }
 +                else
 +                {
 +                    UINT8 *p_data = p_rsp->param.track;
 +                    /* Update the UID for current track
 +                     * Attributes will be fetched after the AVRCP procedure
 +                     */
 +                    BE_STREAM_TO_UINT64(btif_rc_cb.rc_playing_uid, p_data);
 +                }
 +                break;
 +
 +            case AVRC_EVT_APP_SETTING_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_NOW_PLAYING_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_AVAL_PLAYERS_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_ADDR_PLAYER_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_UIDS_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_TRACK_REACHED_END:
 +            case AVRC_EVT_TRACK_REACHED_START:
 +            case AVRC_EVT_PLAY_POS_CHANGED:
 +            case AVRC_EVT_BATTERY_STATUS_CHANGE:
 +            case AVRC_EVT_SYSTEM_STATUS_CHANGE:
 +            default:
 +                BTIF_TRACE_ERROR("%s  Unhandled interim response 0x%2X", __FUNCTION__,
 +                    p_rsp->event_id);
 +                return;
 +        }
-         list_foreach_ext(btif_rc_cb.rc_supported_event_list,
++        list_foreach(btif_rc_cb.rc_supported_event_list,
 +                iterate_supported_event_list_for_interim_rsp,
-                 (void*)&p_rsp->event_id);
++                &p_rsp->event_id);
 +
 +        node = list_begin(btif_rc_cb.rc_supported_event_list);
 +        while (node != NULL)
 +        {
 +            p_event = (btif_rc_supported_event_t *)list_node(node);
 +            if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
 +            {
 +                register_for_event_notification(p_event);
 +                break;
 +            }
 +            node = list_next (node);
 +            p_event = NULL;
 +        }
 +        /* Registered for all events, we can request application settings */
 +        if ((p_event == NULL) && (btif_rc_cb.rc_app_settings.query_started == false))
 +        {
 +            /* we need to do this only if remote TG supports
 +             * player application settings
 +             */
 +            btif_rc_cb.rc_app_settings.query_started = TRUE;
 +            if (btif_rc_cb.rc_features & BTA_AV_FEAT_APP_SETTING)
 +            {
 +                list_player_app_setting_attrib_cmd();
 +            }
 +            else
 +            {
 +                BTIF_TRACE_DEBUG("%s App setting not supported, complete procedure", __FUNCTION__);
 +                rc_ctrl_procedure_complete();
 +            }
 +        }
 +    }
 +    else if (pmeta_msg->code == AVRC_RSP_CHANGED)
 +    {
 +        btif_rc_supported_event_t *p_event;
 +        list_node_t *node;
 +
 +        BTIF_TRACE_DEBUG("%s Notification completed : 0x%2X ", __FUNCTION__,
 +            p_rsp->event_id);
 +
 +        node = list_begin(btif_rc_cb.rc_supported_event_list);
 +        while (node != NULL)
 +        {
 +            p_event = (btif_rc_supported_event_t *)list_node(node);
 +            if ((p_event != NULL) && (p_event->event_id == p_rsp->event_id))
 +            {
 +                p_event->status = eNOT_REGISTERED;
 +                register_for_event_notification(p_event);
 +                break;
 +            }
 +            node = list_next (node);
 +        }
 +
 +        switch (p_rsp->event_id)
 +        {
 +            case AVRC_EVT_PLAY_STATUS_CHANGE:
 +                /* Start timer to get play status periodically
 +                 * if the play state is playing.
 +                 */
 +                if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
 +                {
 +                    rc_start_play_status_timer();
 +                }
 +                else
 +                {
 +                    rc_stop_play_status_timer();
 +                }
 +                HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
 +                    &rc_addr, p_rsp->param.play_status);
 +                break;
 +
 +            case AVRC_EVT_TRACK_CHANGE:
 +                if (rc_is_track_id_valid (p_rsp->param.track) != true)
 +                {
 +                    break;
 +                }
 +                get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
 +                break;
 +
 +            case AVRC_EVT_APP_SETTING_CHANGE:
 +            {
 +                btrc_player_settings_t app_settings;
 +                UINT16 xx;
 +
 +                app_settings.num_attr = p_rsp->param.player_setting.num_attr;
 +                for (xx = 0; xx < app_settings.num_attr; xx++)
 +                {
 +                    app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
 +                    app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx];
 +                }
 +                HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
 +                    &rc_addr, &app_settings);
 +            }
 +                break;
 +
 +            case AVRC_EVT_NOW_PLAYING_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_AVAL_PLAYERS_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_ADDR_PLAYER_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_UIDS_CHANGE:
 +                break;
 +
 +            case AVRC_EVT_TRACK_REACHED_END:
 +            case AVRC_EVT_TRACK_REACHED_START:
 +            case AVRC_EVT_PLAY_POS_CHANGED:
 +            case AVRC_EVT_BATTERY_STATUS_CHANGE:
 +            case AVRC_EVT_SYSTEM_STATUS_CHANGE:
 +            default:
 +                BTIF_TRACE_ERROR("%s  Unhandled completion response 0x%2X",
 +                    __FUNCTION__, p_rsp->event_id);
 +                return;
 +        }
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_app_attr_response
 +**
 +** Description      handles the the application attributes response and
 +**                  initiates procedure to fetch the attribute values
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp)
 +{
 +    UINT8 xx;
 +
 +    if (p_rsp->status != AVRC_STS_NO_ERROR)
 +    {
 +        BTIF_TRACE_ERROR("%s Error getting Player application settings: 0x%2X",
 +                __FUNCTION__, p_rsp->status);
 +        rc_ctrl_procedure_complete();
 +        return;
 +    }
 +
 +    for (xx = 0; xx < p_rsp->num_attr; xx++)
 +    {
 +        UINT8 st_index;
 +
 +        if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT)
 +        {
 +            st_index = btif_rc_cb.rc_app_settings.num_ext_attrs;
 +            btif_rc_cb.rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
 +            btif_rc_cb.rc_app_settings.num_ext_attrs++;
 +        }
 +        else
 +        {
 +            st_index = btif_rc_cb.rc_app_settings.num_attrs;
 +            btif_rc_cb.rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
 +            btif_rc_cb.rc_app_settings.num_attrs++;
 +        }
 +    }
 +    btif_rc_cb.rc_app_settings.attr_index = 0;
 +    btif_rc_cb.rc_app_settings.ext_attr_index = 0;
 +    btif_rc_cb.rc_app_settings.ext_val_index = 0;
 +    if (p_rsp->num_attr)
 +    {
 +        list_player_app_setting_value_cmd (btif_rc_cb.rc_app_settings.attrs[0].attr_id);
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s No Player application settings found",
 +                __FUNCTION__);
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_app_val_response
 +**
 +** Description      handles the the attributes value response and if extended
 +**                  menu is available, it initiates query for the attribute
 +**                  text. If not, it initiates procedure to get the current
 +**                  attribute values and calls the HAL callback for provding
 +**                  application settings information.
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp)
 +{
 +    UINT8 xx, attr_index;
 +    int i,j;
 +    UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
 +    btif_rc_player_app_settings_t *p_app_settings;
 +    bt_bdaddr_t rc_addr;
 +
 +    /* Todo: Do we need to retry on command timeout */
 +    if (p_rsp->status != AVRC_STS_NO_ERROR)
 +    {
 +        BTIF_TRACE_ERROR("%s Error fetching attribute values 0x%02X",
 +                __FUNCTION__, p_rsp->status);
 +        return;
 +    }
 +
 +    p_app_settings = &btif_rc_cb.rc_app_settings;
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    if (p_app_settings->attr_index < p_app_settings->num_attrs)
 +    {
 +        attr_index = p_app_settings->attr_index;
 +        p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
 +        for (xx = 0; xx < p_rsp->num_val; xx++)
 +        {
 +            p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
 +        }
 +        attr_index++;
 +        p_app_settings->attr_index++;
 +        if (attr_index < p_app_settings->num_attrs)
 +        {
 +            list_player_app_setting_value_cmd (p_app_settings->attrs[p_app_settings->attr_index].attr_id);
 +        }
 +        else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
 +        {
 +            attr_index = 0;
 +            p_app_settings->ext_attr_index = 0;
 +            list_player_app_setting_value_cmd (p_app_settings->ext_attrs[attr_index].attr_id);
 +        }
 +        else
 +        {
 +            for (xx = 0; xx < p_app_settings->num_attrs; xx++)
 +            {
 +                attrs[xx] = p_app_settings->attrs[xx].attr_id;
 +            }
 +            get_player_app_setting_cmd (p_app_settings->num_attrs, attrs);
 +            HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
 +                        p_app_settings->num_attrs, &p_app_settings->attrs, 0, NULL);
 +        }
 +    }
 +    else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
 +    {
 +        attr_index = p_app_settings->ext_attr_index;
 +        p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
 +        for (xx = 0; xx < p_rsp->num_val; xx++)
 +        {
 +            p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx];
 +        }
 +        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);
 +        }
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_app_cur_val_response
 +**
 +** Description      handles the the get attributes value response.
 +**
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp)
 +{
 +    btrc_player_settings_t app_settings;
 +    bt_bdaddr_t rc_addr;
 +    UINT16 xx;
 +
 +    /* Todo: Do we need to retry on command timeout */
 +    if (p_rsp->status != AVRC_STS_NO_ERROR)
 +    {
 +        BTIF_TRACE_ERROR("%s Error fetching current settings: 0x%02X",
 +                __FUNCTION__, p_rsp->status);
 +        return;
 +    }
 +
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    app_settings.num_attr = p_rsp->num_val;
 +    for (xx = 0; xx < app_settings.num_attr; xx++)
 +    {
 +        app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
 +        app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
 +    }
 +    HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
 +        &rc_addr, &app_settings);
 +    /* Application settings are fetched only once for initial values
 +     * initiate anything that follows after RC procedure.
 +     * Defer it if browsing is supported till players query
 +     */
 +    rc_ctrl_procedure_complete ();
 +    osi_freebuf(p_rsp->p_vals);
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_app_attr_txt_response
 +**
 +** Description      handles the the get attributes text response, if fails
 +**                  calls HAL callback with just normal settings and initiates
 +**                  query for current settings else initiates query for value text
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
 +{
 +    UINT8 xx, attr_index;
 +    UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
 +    btif_rc_player_app_settings_t *p_app_settings;
 +    bt_bdaddr_t rc_addr;
 +
 +    p_app_settings = &btif_rc_cb.rc_app_settings;
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    /* Todo: Do we need to retry on command timeout */
 +    if (p_rsp->status != AVRC_STS_NO_ERROR)
 +    {
 +        UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
 +
 +        BTIF_TRACE_ERROR("%s Error fetching attribute text: 0x%02X",
 +                __FUNCTION__, p_rsp->status);
 +        /* Not able to fetch Text for extended Menu, skip the process
 +         * and cleanup used memory. Proceed to get the current settings
 +         * for standard attributes.
 +         */
 +        p_app_settings->num_ext_attrs = 0;
 +        for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
 +        {
 +            osi_freebuf (p_app_settings->ext_attrs[xx].p_str);
 +        }
 +        p_app_settings->ext_attr_index = 0;
 +
 +        for (xx = 0; xx < p_app_settings->num_attrs; xx++)
 +        {
 +            attrs[xx] = p_app_settings->attrs[xx].attr_id;
 +        }
 +        HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
 +                    p_app_settings->num_attrs, &p_app_settings->attrs, 0, NULL);
 +
 +        get_player_app_setting_cmd (xx, attrs);
 +        return;
 +    }
 +
 +    for (xx = 0; xx < p_rsp->num_attr; xx++)
 +    {
 +        UINT8 x;
 +        for (x = 0; x < p_app_settings->num_ext_attrs; x++)
 +        {
 +            if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id)
 +            {
 +                p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
 +                p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
 +                p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
 +                break;
 +            }
 +        }
 +    }
 +
 +    for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++)
 +    {
 +        vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
 +    }
 +    get_player_app_setting_value_text_cmd(vals, xx);
 +}
 +
 +
 +/***************************************************************************
 +**
 +** Function         handle_app_attr_val_txt_response
 +**
 +** Description      handles the the get attributes value text response, if fails
 +**                  calls HAL callback with just normal settings and initiates
 +**                  query for current settings
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
 +{
 +    UINT8 xx, attr_index;
 +    UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
 +    UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
 +    btif_rc_player_app_settings_t *p_app_settings;
 +    bt_bdaddr_t rc_addr;
 +
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +    p_app_settings = &btif_rc_cb.rc_app_settings;
 +
 +    /* Todo: Do we need to retry on command timeout */
 +    if (p_rsp->status != AVRC_STS_NO_ERROR)
 +    {
 +        UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
 +
 +        BTIF_TRACE_ERROR("%s Error fetching attribute value text: 0x%02X",
 +                __FUNCTION__, p_rsp->status);
 +
 +        /* Not able to fetch Text for extended Menu, skip the process
 +         * and cleanup used memory. Proceed to get the current settings
 +         * for standard attributes.
 +         */
 +        p_app_settings->num_ext_attrs = 0;
 +        for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
 +        {
 +            int x;
 +            btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
 +
 +            for (x = 0; x < p_ext_attr->num_val; x++)
 +            {
 +                osi_freebuf (p_ext_attr->ext_attr_val[x].p_str);
 +            }
 +            p_ext_attr->num_val = 0;
 +            osi_freebuf (p_app_settings->ext_attrs[xx].p_str);
 +        }
 +        p_app_settings->ext_attr_index = 0;
 +
 +        for (xx = 0; xx < p_app_settings->num_attrs; xx++)
 +        {
 +            attrs[xx] = p_app_settings->attrs[xx].attr_id;
 +        }
 +        HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
 +                    p_app_settings->num_attrs, &p_app_settings->attrs, 0, NULL);
 +
 +        get_player_app_setting_cmd (xx, attrs);
 +        return;
 +    }
 +
 +    for (xx = 0; xx < p_rsp->num_attr; xx++)
 +    {
 +        UINT8 x;
 +        btrc_player_app_ext_attr_t *p_ext_attr;
 +        p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
 +        for (x = 0; x < p_rsp->num_attr; x++)
 +        {
 +            if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id)
 +            {
 +                p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
 +                p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
 +                p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
 +                break;
 +            }
 +        }
 +    }
 +    p_app_settings->ext_val_index++;
 +
 +    if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs)
 +    {
 +        attr_index = p_app_settings->ext_val_index;
 +        for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++)
 +        {
 +            vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
 +        }
 +        get_player_app_setting_value_text_cmd(vals, xx);
 +    }
 +    else
 +    {
 +        UINT8 x;
 +
 +        for (xx = 0; xx < p_app_settings->num_attrs; xx++)
 +        {
 +            attrs[xx] = p_app_settings->attrs[xx].attr_id;
 +        }
 +        for (x = 0; x < p_app_settings->num_ext_attrs; x++)
 +        {
 +            attrs[xx+x] = p_app_settings->ext_attrs[x].attr_id;
 +        }
 +        HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
 +                    p_app_settings->num_attrs, &p_app_settings->attrs,
 +                    p_app_settings->num_ext_attrs, &p_app_settings->ext_attrs);
 +        get_player_app_setting_cmd (xx + x, attrs);
 +
 +        /* Free the application settings information after sending to
 +         * application.
 +         */
 +        for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
 +        {
 +            int x;
 +            btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
 +
 +            for (x = 0; x < p_ext_attr->num_val; x++)
 +            {
 +                osi_freebuf (p_ext_attr->ext_attr_val[x].p_str);
 +            }
 +            p_ext_attr->num_val = 0;
 +            osi_freebuf (p_app_settings->ext_attrs[xx].p_str);
 +        }
 +        p_app_settings->num_attrs = 0;
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_set_app_attr_val_response
 +**
 +** Description      handles the the set attributes value response, if fails
 +**                  calls HAL callback to indicate the failure
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp)
 +{
 +    uint8_t accepted = 0;
 +    bt_bdaddr_t rc_addr;
 +
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    /* For timeout pmeta_msg will be NULL, else we need to
 +     * check if this is accepted by TG
 +     */
 +    if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT))
 +    {
 +        accepted = 1;
 +    }
 +    HAL_CBACK(bt_rc_ctrl_callbacks, setplayerappsetting_rsp_cb, &rc_addr, accepted);
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_get_elem_attr_response
 +**
 +** Description      handles the the element attributes response, calls
 +**                  HAL callback to update track change information.
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_ELEM_ATTRS_RSP *p_rsp)
 +{
 +    btrc_element_attr_val_t *p_attr;
 +    bt_bdaddr_t rc_addr;
 +    UINT16 xx;
 +
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    if (p_rsp->status == AVRC_STS_NO_ERROR)
 +    {
 +        p_attr = (btrc_element_attr_val_t*)osi_getbuf (p_rsp->num_attr * sizeof(btrc_element_attr_val_t));
 +        if (p_attr != NULL)
 +        {
 +            memset(p_attr, 0, osi_get_buf_size (p_attr));
 +            for (xx = 0; xx < p_rsp->num_attr; xx++)
 +            {
 +                p_attr[xx].attr_id = p_rsp->p_attrs[xx].attr_id;
 +                /* Todo. Legth limit check to include null */
 +                if (p_rsp->p_attrs[xx].name.str_len && p_rsp->p_attrs[xx].name.p_str)
 +                {
 +                    memcpy(p_attr[xx].text, p_rsp->p_attrs[xx].name.p_str,
 +                            p_rsp->p_attrs[xx].name.str_len);
 +                    osi_freebuf (p_rsp->p_attrs[xx].name.p_str);
 +                }
 +            }
 +            HAL_CBACK(bt_rc_ctrl_callbacks, track_changed_cb,
 +                &rc_addr, p_rsp->num_attr, p_attr);
 +            osi_freebuf (p_attr);
 +        }
 +    }
 +    else if (p_rsp->status == BTIF_RC_STS_TIMEOUT)
 +    {
 +        /* Retry for timeout case, this covers error handling
 +         * for continuation failure also.
 +         */
 +        UINT32 attr_list[] = {
 +            AVRC_MEDIA_ATTR_ID_TITLE,
 +            AVRC_MEDIA_ATTR_ID_ARTIST,
 +            AVRC_MEDIA_ATTR_ID_ALBUM,
 +            AVRC_MEDIA_ATTR_ID_TRACK_NUM,
 +            AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
 +            AVRC_MEDIA_ATTR_ID_GENRE,
 +            AVRC_MEDIA_ATTR_ID_PLAYING_TIME
 +            };
 +        get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s: Error in get element attr procedure %d",
 +            __FUNCTION__, p_rsp->status);
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_get_playstatus_response
 +**
 +** Description      handles the the play status response, calls
 +**                  HAL callback to update play position.
 +** Returns          None
 +**
 +***************************************************************************/
 +static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp)
 +{
 +    bt_bdaddr_t rc_addr;
 +
 +    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
 +
 +    if (p_rsp->status == AVRC_STS_NO_ERROR)
 +    {
 +        HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb,
 +            &rc_addr, p_rsp->song_len, p_rsp->song_pos);
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s: Error in get play status procedure %d",
 +            __FUNCTION__, p_rsp->status);
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         clear_cmd_timeout
 +**
 +** Description      helper function to stop the command timeout timer
 +** Returns          None
 +**
 +***************************************************************************/
 +static void clear_cmd_timeout (UINT8 label)
 +{
 +    rc_transaction_t *p_txn;
 +
 +    p_txn = get_transaction_by_lbl (label);
 +    if (p_txn == NULL)
 +    {
 +        BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __FUNCTION__);
 +        return;
 +    }
 +
 +    btu_stop_timer (&p_txn->tle_txn);
 +    if (p_txn->tle_txn.data != NULL)
 +    {
 +        osi_freebuf (p_txn->tle_txn.data);
 +        p_txn->tle_txn.data = NULL;
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_avk_rc_metamsg_rsp
 +**
 +** Description      Handle RC metamessage response
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
 +{
 +    tAVRC_RESPONSE    avrc_response = {0};
 +    UINT8             scratch_buf[512] = {0};// this variable is unused
 +    UINT16            buf_len;
 +    tAVRC_STS         status;
 +
 +    BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ", __FUNCTION__,
 +                        pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
 +
 +    if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode)&&
 +                (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)&&
 +                (pmeta_msg->code <= AVRC_RSP_INTERIM))
 +    {
 +        status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
 +        BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d",
 +                         __FUNCTION__, status, avrc_response.pdu,
 +                         pmeta_msg->p_msg->vendor.hdr.ctype);
 +
 +        switch (avrc_response.pdu)
 +        {
 +            case AVRC_PDU_REGISTER_NOTIFICATION:
 +                handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
 +                if (pmeta_msg->code == AVRC_RSP_INTERIM)
 +                {
 +                    /* Don't free the transaction Id */
 +                    clear_cmd_timeout (pmeta_msg->label);
 +                    return;
 +                }
 +                break;
 +
 +            case AVRC_PDU_GET_CAPABILITIES:
 +                handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
 +                break;
 +
 +            case AVRC_PDU_LIST_PLAYER_APP_ATTR:
 +                handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
 +                break;
 +
 +            case AVRC_PDU_LIST_PLAYER_APP_VALUES:
 +                handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
 +                break;
 +
 +            case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
 +                handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
 +                break;
 +
 +            case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
 +                handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
 +                break;
 +
 +            case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
 +                handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
 +                break;
 +
 +            case AVRC_PDU_SET_PLAYER_APP_VALUE:
 +                handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
 +                break;
 +
 +            case AVRC_PDU_GET_ELEMENT_ATTR:
 +                handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_elem_attrs);
 +                break;
 +
 +            case AVRC_PDU_GET_PLAY_STATUS:
 +                handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
 +                break;
 +        }
 +        release_transaction(pmeta_msg->label);
 +    }
 +    else
 +    {
 +        BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
 +            __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
 +        return;
 +    }
 +}
 +
 +/***************************************************************************
 +**
 +** Function         handle_avk_rc_metamsg_cmd
 +**
 +** Description      Handle RC metamessage response
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg)
 +{
 +    tAVRC_COMMAND    avrc_cmd = {0};
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ",__FUNCTION__,
 +                     pmeta_msg->p_msg->hdr.opcode,pmeta_msg->code);
 +    if ((AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode)&&
 +                (pmeta_msg->code <= AVRC_CMD_GEN_INQ))
 +    {
 +        status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
 +        BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d",
 +                         __FUNCTION__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label);
 +
 +        if (status != AVRC_STS_NO_ERROR)
 +        {
 +            /* return error */
 +            BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
 +                __FUNCTION__, status);
 +            send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status);
 +        }
 +        else
 +        {
 +            if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
 +            {
 +                UINT8 event_id = avrc_cmd.reg_notif.event_id;
 +                BTIF_TRACE_EVENT("%s:Register notification event_id: %s",
 +                        __FUNCTION__, dump_rc_notification_event_id(event_id));
 +            }
 +            else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME)
 +            {
 +                BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __FUNCTION__);
 +            }
 +            btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label);
 +        }
 +    }
 +    else
 +    {
 +      BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
 +                       __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
 +        return;
 +    }
 +}
 +#endif
 +
 +/***************************************************************************
 +**
 +** Function         cleanup
 +**
 +** Description      Closes the AVRC interface
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static void cleanup()
 +{
 +    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
 +    close_uinput();
 +    if (bt_rc_callbacks)
 +    {
 +        bt_rc_callbacks = NULL;
 +    }
 +    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
 +    lbl_destroy();
 +    BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
 +}
 +
 +/***************************************************************************
 +**
 +** Function         cleanup_ctrl
 +**
 +** Description      Closes the AVRC Controller interface
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static void cleanup_ctrl()
 +{
 +    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
 +
 +    if (bt_rc_ctrl_callbacks)
 +    {
 +        bt_rc_ctrl_callbacks = NULL;
 +    }
 +    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
 +    lbl_destroy();
 +    BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
 +}
 +
 +/***************************************************************************
 +**
 +** Function         getcapabilities_cmd
 +**
 +** Description      GetCapabilties from Remote(Company_ID, Events_Supported)
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t getcapabilities_cmd (uint8_t cap_id)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    rc_transaction_t *p_transaction = NULL;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    BTIF_TRACE_DEBUG("%s: cap_id %d", __FUNCTION__, cap_id);
 +    CHECK_RC_CONNECTED
 +    bt_status_t tran_status=get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +     tAVRC_COMMAND avrc_cmd = {0};
 +     BT_HDR *p_msg = NULL;
 +     avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
 +     avrc_cmd.get_caps.capability_id = cap_id;
 +     avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
 +     avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
 +     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
 +     if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
 +     {
 +         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);
 +         status =  BT_STATUS_SUCCESS;
 +         start_status_command_timer (AVRC_PDU_GET_CAPABILITIES, p_transaction);
 +     }
 +     else
 +     {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                             __FUNCTION__, status);
 +     }
 +     if (p_msg != NULL)
 +         osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         list_player_app_setting_attrib_cmd
 +**
 +** Description      Get supported List Player Attributes
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t list_player_app_setting_attrib_cmd(void)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    rc_transaction_t *p_transaction = NULL;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
 +    CHECK_RC_CONNECTED
 +    bt_status_t tran_status=get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +     tAVRC_COMMAND avrc_cmd = {0};
 +     BT_HDR *p_msg = NULL;
 +     avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
 +     avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
 +     avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
 +     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
 +     if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
 +     {
 +         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);
 +         status =  BT_STATUS_SUCCESS;
 +         start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_ATTR, p_transaction);
 +     }
 +     else
 +     {
 +
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +     }
 +     if (NULL!=p_msg)
 +         osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         list_player_app_setting_value_cmd
 +**
 +** Description      Get values of supported Player Attributes
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    rc_transaction_t *p_transaction=NULL;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    BTIF_TRACE_DEBUG("%s: attrib_id %d", __FUNCTION__, attrib_id);
 +    CHECK_RC_CONNECTED
 +    bt_status_t tran_status=get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +     tAVRC_COMMAND avrc_cmd = {0};
 +     BT_HDR *p_msg = NULL;
 +     avrc_cmd.list_app_values.attr_id = attrib_id;
 +     avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
 +     avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
 +     avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
 +     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
 +     if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
 +     {
 +         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);
 +         status =  BT_STATUS_SUCCESS;
 +         start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_VALUES, p_transaction);
 +     }
 +     else
 +     {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
 +     }
 +     if (NULL!=p_msg)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         get_player_app_setting_cmd
 +**
 +** Description      Get current values of Player Attributes
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    rc_transaction_t *p_transaction = NULL;
 +    int count  = 0;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
 +    CHECK_RC_CONNECTED
 +    bt_status_t tran_status=get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +     tAVRC_COMMAND avrc_cmd = {0};
 +     BT_HDR *p_msg = NULL;
 +     avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
 +     avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
 +     avrc_cmd.get_cur_app_val.num_attr = num_attrib;
 +     avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
 +
 +     for (count = 0; count < num_attrib; count++)
 +     {
 +         avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
 +     }
 +     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
 +     if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
 +     {
 +         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);
 +         status =  BT_STATUS_SUCCESS;
 +         start_status_command_timer (AVRC_PDU_GET_CUR_PLAYER_APP_VALUE, p_transaction);
 +     }
 +     else
 +     {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +     }
 +     if (p_msg != NULL)
 +         osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         change_player_app_setting
 +**
 +** Description      Set current values of Player Attributes
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t change_player_app_setting(bt_bdaddr_t *bd_addr, uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    rc_transaction_t *p_transaction = NULL;
 +    int count  = 0;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
 +    CHECK_RC_CONNECTED
 +    bt_status_t tran_status=get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +     tAVRC_COMMAND avrc_cmd = {0};
 +     BT_HDR *p_msg = NULL;
 +     avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
 +     avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
 +     avrc_cmd.set_app_val.num_val = num_attrib;
 +     avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
 +     avrc_cmd.set_app_val.p_vals =
 +           (tAVRC_APP_SETTING*)osi_getbuf(sizeof(tAVRC_APP_SETTING)*num_attrib);
 +    if (avrc_cmd.set_app_val.p_vals == NULL)
 +    {
 +        BTIF_TRACE_ERROR("%s: alloc failed", __FUNCTION__);
 +        return BT_STATUS_FAIL;
 +    }
 +     for (count = 0; count < num_attrib; count++)
 +     {
 +         avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
 +         avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
 +     }
 +     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
 +     if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
 +     {
 +         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_CTRL,
 +                              data_start, p_msg->len);
 +         status =  BT_STATUS_SUCCESS;
 +         start_control_command_timer (AVRC_PDU_SET_PLAYER_APP_VALUE, p_transaction);
 +     }
 +     else
 +     {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +     }
 +     if (p_msg != NULL)
 +         osi_freebuf(p_msg);
 +     osi_freebuf(avrc_cmd.set_app_val.p_vals);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    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);
 +        if (p_msg != NULL)
 +            osi_freebuf(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);
 +    }
 +    if (NULL != p_msg)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         get_player_app_setting_val_text_cmd
 +**
 +** Description      Get text description for app attribute values
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals)
 +{
 +    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_vals %d", __FUNCTION__, num_vals);
 +
 +    tran_status = get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +    avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
 +    avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
 +    avrc_cmd.get_app_val_txt.num_val = num_vals;
 +
 +    for (count = 0; count < num_vals; count++)
 +    {
 +        avrc_cmd.get_app_val_txt.vals[count] = vals[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);
 +        if (p_msg != NULL)
 +        {
 +            BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
 +                    AVRC_CMD_STATUS, data_start, p_msg->len);
 +            status =  BT_STATUS_SUCCESS;
 +            start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT, p_transaction);
 +        }
 +    }
 +    else
 +    {
 +        BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                __FUNCTION__, status);
 +    }
 +    if (NULL != p_msg)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         register_notification_cmd
 +**
 +** Description      Send Command to register for a Notification ID
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value)
 +{
 +
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    tAVRC_COMMAND avrc_cmd = {0};
 +    BT_HDR *p_msg = NULL;
 +    CHECK_RC_CONNECTED
 +
 +
 +    BTIF_TRACE_DEBUG("%s: event_id %d  event_value", __FUNCTION__, event_id, event_value);
 +
 +    avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
 +    avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
 +    avrc_cmd.reg_notif.event_id = event_id;
 +    avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
 +    avrc_cmd.reg_notif.param = event_value;
 +    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__, label);
 +        if (p_msg != NULL)
 +        {
 +            BTA_AvVendorCmd(btif_rc_cb.rc_handle, label, AVRC_CMD_NOTIF,
 +                    data_start, p_msg->len);
 +            status =  BT_STATUS_SUCCESS;
 +        }
 +    }
 +    else
 +    {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +    }
 +    if (p_msg != NULL)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         get_element_attribute_cmd
 +**
 +** Description      Get Element Attribute for  attributeIds
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids)
 +{
 +    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_attribute  %d attribute_id %d",
 +                   __FUNCTION__, num_attribute, p_attr_ids[0]);
 +
 +    tran_status = get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +    avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
 +    avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
 +    avrc_cmd.get_elem_attrs.num_attr = num_attribute;
 +    avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
 +    for (count = 0; count < num_attribute; count++)
 +    {
 +        avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[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);
 +        if (p_msg != NULL)
 +        {
 +            BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
 +                    AVRC_CMD_STATUS, data_start, p_msg->len);
 +            status =  BT_STATUS_SUCCESS;
 +            start_status_command_timer (AVRC_PDU_GET_ELEMENT_ATTR,
 +                    p_transaction);
 +        }
 +    }
 +    else
 +    {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +    }
 +    if (p_msg != NULL)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         get_play_status_cmd
 +**
 +** Description      Get Element Attribute for  attributeIds
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t get_play_status_cmd(void)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    rc_transaction_t *p_transaction = NULL;
 +#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: ", __FUNCTION__);
 +    tran_status = get_transaction(&p_transaction);
 +    if (BT_STATUS_SUCCESS != tran_status)
 +        return BT_STATUS_FAIL;
 +
 +    avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
 +    avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
 +    avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
 +    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);
 +        if (p_msg != NULL)
 +        {
 +            BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,
 +                    AVRC_CMD_STATUS, data_start, p_msg->len);
 +            status =  BT_STATUS_SUCCESS;
 +            start_status_command_timer (AVRC_PDU_GET_PLAY_STATUS, p_transaction);
 +        }
 +    }
 +    else
 +    {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +    }
 +    if (p_msg != NULL)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +
 +}
 +
 +/***************************************************************************
 +**
 +** Function         set_volume_rsp
 +**
 +** Description      Rsp for SetAbsoluteVolume Command
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t set_volume_rsp(bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    tAVRC_RESPONSE avrc_rsp;
 +    BT_HDR *p_msg = NULL;
 +    CHECK_RC_CONNECTED
 +
 +    BTIF_TRACE_DEBUG("%s: abs_vol %d", __FUNCTION__, abs_vol);
 +
 +    avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
 +    avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
 +    avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
 +    avrc_rsp.volume.volume = abs_vol;
 +    status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &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__, btif_rc_cb.rc_vol_label);
 +        if (p_msg != NULL)
 +        {
 +            BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
 +                    BTA_AV_RSP_ACCEPT, data_start, p_msg->len, 0);
 +            status =  BT_STATUS_SUCCESS;
 +        }
 +    }
 +    else
 +    {
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +    }
 +    if (p_msg != NULL)
 +        osi_freebuf(p_msg);
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         send_register_abs_vol_rsp
 +**
 +** Description      Rsp for Notification of Absolute Volume
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t volume_change_notification_rsp(bt_bdaddr_t *bd_addr, btrc_notification_type_t rsp_type,
 +            uint8_t abs_vol, uint8_t label)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +    tAVRC_RESPONSE avrc_rsp;
 +    BT_HDR *p_msg = NULL;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    BTIF_TRACE_DEBUG("%s: rsp_type  %d abs_vol %d", __FUNCTION__, rsp_type, abs_vol);
 +    CHECK_RC_CONNECTED
 +
 +     avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
 +     avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
 +     avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
 +     avrc_rsp.reg_notif.param.volume = abs_vol;
 +     avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
 +
 +    status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
 +     if (status == AVRC_STS_NO_ERROR)
 +     {
 +         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
 +                            __FUNCTION__,label);
 +         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
 +                     BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
 +                (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ? AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
 +                data_start, p_msg->len, 0);
 +         if (p_msg != NULL)
 +             osi_freebuf(p_msg);
 +         status =  BT_STATUS_SUCCESS;
 +     }
 +     else
 +     {
 +         if (NULL!=p_msg)
 +            osi_freebuf(p_msg);
 +         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
 +                            __FUNCTION__, status);
 +     }
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         send_groupnavigation_cmd
 +**
 +** Description      Send Pass-Through command
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code,
 +                                            uint8_t key_state)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    rc_transaction_t *p_transaction=NULL;
 +    BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
 +                                                    key_code, key_state);
 +    CHECK_RC_CONNECTED
 +    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
 +    {
 +        bt_status_t tran_status = get_transaction(&p_transaction);
 +        if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction))
 +        {
 +             UINT8* p_buf = (UINT8*)osi_getbuf(AVRC_PASS_THRU_GROUP_LEN);
 +             if (p_buf != NULL)
 +             {
 +                 UINT8* start = p_buf;
 +                 UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
 +                 *(start)++ = 0;
 +                 UINT8_TO_BE_STREAM(start, key_code);
 +                 BTA_AvRemoteVendorUniqueCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
 +                    (tBTA_AV_STATE)key_state, p_buf, AVRC_PASS_THRU_GROUP_LEN);
 +                status =  BT_STATUS_SUCCESS;
 +                BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA",
 +                                                                          __FUNCTION__);
 +             }
 +        }
 +        else
 +        {
 +            status =  BT_STATUS_FAIL;
 +            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
 +        }
 +    }
 +    else
 +    {
 +        status =  BT_STATUS_FAIL;
 +        BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
 +    }
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +/***************************************************************************
 +**
 +** Function         send_passthrough_cmd
 +**
 +** Description      Send Pass-Through command
 +**
 +** Returns          void
 +**
 +***************************************************************************/
 +static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
 +{
 +    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
 +#if (AVRC_CTLR_INCLUDED == TRUE)
 +    CHECK_RC_CONNECTED
 +    rc_transaction_t *p_transaction=NULL;
 +    BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
 +                                                    key_code, key_state);
 +    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
 +    {
 +        bt_status_t tran_status = get_transaction(&p_transaction);
 +        if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
 +        {
 +            BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
 +                (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
 +            status =  BT_STATUS_SUCCESS;
 +            BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
 +        }
 +        else
 +        {
 +            status =  BT_STATUS_FAIL;
 +            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
 +        }
 +    }
 +    else
 +    {
 +        status =  BT_STATUS_FAIL;
 +        BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
 +    }
 +#else
 +    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 +#endif
 +    return status;
 +}
 +
 +static const btrc_interface_t bt_rc_interface = {
 +    sizeof(bt_rc_interface),
 +    init,
 +    get_play_status_rsp,
      NULL, /* list_player_app_attr_rsp */
      NULL, /* list_player_app_value_rsp */
      NULL, /* get_player_app_value_rsp */