static void avrcpSendNowPlayingCommand( AVRCP*              avrcp, 
                                        avrcp_browse_scope  scope,    
                                        avrcp_browse_uid    uid,  
                                        uint16              uid_counter,
                                        uint16              pdu_id)
{
    uint8 extra_params[AVRCP_PLAY_ITEM_SIZE];
    avrcp_status_code status;

    if((scope ==  avrcp_media_player_scope) ||
       (scope >   avrcp_now_playing_scope))       
    {
        avrcpNowPlayingCfm(avrcp, avrcp_rejected_invalid_param, pdu_id);
        return;
    }

    /* Fill in the Parameters */
    extra_params[0] = (uint8)scope;
    convertUint32ToUint8Values(&extra_params[1], uid.msb);
    convertUint32ToUint8Values(&extra_params[5], uid.lsb);
    AVRCP_UINT16_TO_UINT8(uid_counter, extra_params, 9);

    status = avrcpMetadataControlCommand(avrcp, pdu_id, 
                                       (pdu_id == AVRCP_PLAY_ITEM_PDU_ID)?
                                       avrcp_play_item:avrcp_add_to_now_playing,
                                       AVRCP_PLAY_ITEM_SIZE,
                                       extra_params, 0 , 0);

   /* Failure confirmation if the request got failed */
    if(status != avrcp_success)
    {
        avrcpNowPlayingCfm(avrcp, status, pdu_id);
    }
}
void avrcpHandleInternalGetPlayStatusResponse(AVRCP *avrcp,
                     AVRCP_INTERNAL_GET_PLAY_STATUS_RES_T *res)
{
    uint16 size_mandatory_data = 1;
    uint8 mandatory_data[9];
    uint16 param_length = 1;

    mandatory_data[0] = avrcpGetErrorStatusCode(&res->response, 
                                                AVRCP0_CTYPE_STATUS);

    if (res->response == avctp_response_stable)
    {
        size_mandatory_data = 9;
        param_length = size_mandatory_data;
        /* Insert the mandatory data */
        convertUint32ToUint8Values(&mandatory_data[0], res->song_length);
        convertUint32ToUint8Values(&mandatory_data[4], res->song_elapsed);
        mandatory_data[8] = res->play_status;
    }

    avrcpSendMetadataResponse(avrcp,  res->response, 
                              AVRCP_GET_PLAY_STATUS_PDU_ID, 0, 
                              avrcp_packet_type_single, param_length, 
                              size_mandatory_data, mandatory_data);

}
/****************************************************************************
*NAME    
*    AvrcpGetElementAttributes    
*
*DESCRIPTION
*  API function to request GetElementAttributes. 
*    
*PARAMETERS
*   avrcp            - Task
*   identifier_high -  Element identifier is 8 octets in big-endian format, 
*                      this parameter should be the most significant 4 
*                      octets. Currently only allowed identifier value is 
*                      PLAYING (0x0), so it must be set to 0.
*   identifier_low  - least significant 4 octets of the element identifier.
*                     currently allowed value is only PLAYING(0x0), so it 
*                     must be set to 0.
*   size_attributes - Size of attributes in Bytes
*   attributes      - list of attributes. 
*
*RETURN
*  AVRCP_GET_ELEMENT_ATTRIBUTES_CFM 
*******************************************************************************/
void AvrcpGetElementAttributes(AVRCP    *avrcp,
                               uint32   identifier_high, 
                               uint32   identifier_low, 
                               uint16   size_attributes, 
                               Source   attributes)
{
    uint8 extra_params[AVRCP_GET_ELEMENTS_HDR_SIZE];
    avrcp_status_code status;

    /* Fill in the extra Header for Get Elements which is Identifier and
       number of elements*/
    convertUint32ToUint8Values(&extra_params[0], identifier_high);
    convertUint32ToUint8Values(&extra_params[4], identifier_low);
    extra_params[8] = size_attributes/4;

    status = avrcpMetadataStatusCommand(avrcp, 
                                        AVRCP_GET_ELEMENT_ATTRIBUTES_PDU_ID,
                                        avrcp_get_element_attributes, 
                                        AVRCP_GET_ELEMENTS_HDR_SIZE, 
                                        extra_params,size_attributes,
                                        attributes);

    if (status != avrcp_success)
    {
        avrcpSendCommonFragmentedMetadataCfm(avrcp, status, 
                                            AVRCP_GET_ELEMENT_ATTRIBUTES_CFM, 
                                            0, 0, 0);
    }
}
void avrcpHandleInternalGetPlayStatusResponse(AVRCP *avrcp, AVRCP_INTERNAL_GET_PLAY_STATUS_RES_T *res)
{
	uint16 size_mandatory_data = 0;
	uint8 *mandatory_data = 0;
	uint16 param_length = 0;

	standardiseCtypeStatus(&res->response);

	if (res->response == avctp_response_stable)
	{
		size_mandatory_data = 9;
		param_length = size_mandatory_data;
		/* Insert the mandatory data */
		mandatory_data = (uint8 *) malloc(size_mandatory_data);
		convertUint32ToUint8Values(&mandatory_data[0], res->song_length);
		convertUint32ToUint8Values(&mandatory_data[4], res->song_elapsed);
		mandatory_data[8] = res->play_status;
	}
	else
	{
		mandatory_data = insertRejectCode(&res->response, &size_mandatory_data, &param_length);
	}

    sendMetadataResponse(avrcp,  res->response, AVRCP_GET_PLAY_STATUS_PDU_ID, 0, avrcp_packet_type_single, param_length, size_mandatory_data, mandatory_data);

    avrcpHandleReceivedData(avrcp);
}
void avrcpHandleInternalEventTrackChangedResponse(AVRCP *avrcp,
                     AVRCP_INTERNAL_EVENT_TRACK_CHANGED_RES_T *res)
{
    uint8 mandatory_data[AVRCP_EVENT_TRACK_HDR_SIZE];

    mandatory_data[0] = avrcp_event_track_changed;
    convertUint32ToUint8Values(&mandatory_data[1], res->track_index_high);
    convertUint32ToUint8Values(&mandatory_data[5], res->track_index_low);

    sendRegisterNotificationResponse(avrcp, res->response, 
                                AVRCP_EVENT_TRACK_HDR_SIZE,
                                mandatory_data, 0, 0);
}
void avrcpHandleInternalEventPlaybackPosChangedResponse(AVRCP *avrcp,
                 AVRCP_INTERNAL_EVENT_PLAYBACK_POS_CHANGED_RES_T *res)
{
    /* 5 Byte length data for play back position changed response */
    uint8 mandatory_data[AVRCP_EVENT_POS_HDR_SIZE];
    mandatory_data[0] = avrcp_event_playback_pos_changed;
    convertUint32ToUint8Values(&mandatory_data[1], res->playback_pos);

    sendRegisterNotificationResponse(avrcp, res->response, 
                                    AVRCP_EVENT_POS_HDR_SIZE, 
                                    mandatory_data, 0, 0);
}
/****************************************************************************
 *NAME    
 *    AvrcpRegisterNotification    
 *
 *DESCRIPTION
 *  CT shall use this API function to register Event Notifications 
 *
 *PARAMETERS
 * avrcp            -   AVRCP Entity
 * event_id         -   Event to be registered with TG for notifications.
 * playback_interval-   Only applicable to EVENT_PLAYBACK_POS_CHANGED 
 *
 *MESSAGE RETURNED
 * EVENT_IND messages on Event notifications from TG.
*****************************************************************************/
void AvrcpRegisterNotification(AVRCP                    *avrcp, 
                               avrcp_supported_events   event_id, 
                               uint32                   playback_interval)
{
    uint8 params[5];
    avrcp_status_code status;

    params[0] = event_id & 0xFF;
    convertUint32ToUint8Values(&params[1], playback_interval);

    status = avrcpMetadataStatusCommand(avrcp, 
                                        AVRCP_REGISTER_NOTIFICATION_PDU_ID, 
                                        event_id + avrcp_events_start_dummy, 
                                        sizeof(params), params, 0, 0);

    if (status != avrcp_success)
    {
        avrcpSendRegisterNotificationFailCfm(avrcp, status, event_id);
    }
}