void sendRegisterNotificationResponse(  AVRCP               *avrcp, 
                                        avrcp_response_type resp, 
                                        uint16              size_mandatory, 
                                        uint8               *mandatory, 
                                        uint16              size_attributes, 
                                        Source              attributes)
{
    /* 1 byte error status code as data for rejected response */ 
    uint8  error_data[1];
    uint16 param_length = 1;
    avrcp_packet_type  metadata_packet_type =  avrcp_packet_type_single;

   /* Get the error status code */
    error_data[0] = avrcpGetErrorStatusCode(&resp, AVRCP0_CTYPE_NOTIFY);

    if ((resp == avctp_response_interim) || (resp == avctp_response_changed))
    {
        param_length = size_mandatory + size_attributes;
    }
    else
    {
        size_mandatory = 1; /*  1 octet length only for error code */
        mandatory = &error_data[0];
    }

    
    if (param_length > AVRCP_AVC_MAX_DATA_SIZE)
    {        
        /* There are more fragments to be sent, 
            store the data for the following fragments. */

        /* madatory[0] contains the event ID */
        avrcpStoreNextContinuationPacket(avrcp, attributes, 
                                param_length-AVRCP_AVC_MAX_DATA_SIZE, 
                                AVRCP_REGISTER_NOTIFICATION_PDU_ID, 
                                resp, 
                                GetNotificationTransaction(avrcp, mandatory[0]));

        param_length = AVRCP_AVC_MAX_DATA_SIZE;
        metadata_packet_type = avrcp_packet_type_start;
    }
    
    avrcpSendMetadataResponse(avrcp,  resp, AVRCP_REGISTER_NOTIFICATION_PDU_ID,
                              attributes, metadata_packet_type, param_length, 
                              size_mandatory, mandatory);

}
/****************************************************************************
 *NAME    
 *    avrcpSendNotification  
 *
 *DESCRIPTION
 *   Send Notification Indications to the CT application.
 *
 *PARAMETERS
 * avrcp            - AVRCP instance
 * response         - Response code
 * ptr              - Pointer to the response data
 * packet_size      - Data size in ptr
 ****************************************************************************/
void avrcpSendNotification( AVRCP *avrcp,  
                            avrcp_response_type response, 
                            const uint8* ptr, 
                            uint16 packet_size)
{
    avrcp_supported_events event_id;
    uint16 data_len    = 0;
    uint16 data_start  = 0;
    uint16 transaction = (avrcp->av_msg[0] & AVCTP_TRANSACTION_MASK) >>
                         AVCTP0_TRANSACTION_SHIFT;
    if(!packet_size)
    {
        /* Unknown event. Ignore */
        return;
    }

    if(response == avctp_response_rejected)
    {
        for(event_id = 1; event_id <= AVRCP_MAX_NUM_EVENTS; event_id++)
        {
            if(isEventRegistered(avrcp, event_id) &&
                GetNotificationTransaction(avrcp, event_id) == transaction)
            {
                break;
            }
        }       

        /* data[0] would be error status code */
        response = ptr[data_start] | AVRCP_ERROR_STATUS_BASE;
    }
    else
    {
        event_id = ptr[data_start];
        data_start++;
        data_len = packet_size-data_start;
    }
    
    switch (event_id)
    {
    case avrcp_event_playback_status_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_PLAYBACK_STATUS_CHANGED_IND);
            message->avrcp = avrcp;

#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif
            
            message->response = response;

            /* EVENT_PLAYBACK_STATUS_CHANGED Length expected is 1 */
            if(data_len){
                message->play_status = ptr[data_start];
            }
            else
            {
                /* This will be error value on rejected response. 
                   App will ignore it */
                message->play_status = 0xFF;
            }
            MessageSend(avrcp->clientTask,
                         AVRCP_EVENT_PLAYBACK_STATUS_CHANGED_IND, message);
            
        }
        break;
    case avrcp_event_track_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_TRACK_CHANGED_IND);
            message->avrcp = avrcp;

#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif
            
            /*
             * If the Packet comes in continuation or end packet
             * fragmented, it may  not process
             * Identifier is 8 octets long
             */
            message->response = response;
            if(data_len >= 8)
            {
                message->track_index_high =
                               convertUint8ValuesToUint32(&ptr[data_start]);
                message->track_index_low = 
                               convertUint8ValuesToUint32(&ptr[data_start+4]);
            }
            else
            {
                message->track_index_high = 0;
                message->track_index_low = 0;
            }
            MessageSend(avrcp->clientTask, 
                        AVRCP_EVENT_TRACK_CHANGED_IND, message);
        }
        break;
    case avrcp_event_track_reached_end:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_TRACK_REACHED_END_IND);
            message->avrcp = avrcp;
#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif
            message->response = response;
            MessageSend(avrcp->clientTask, 
                        AVRCP_EVENT_TRACK_REACHED_END_IND, message);
        }
        break;
    case avrcp_event_track_reached_start:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_TRACK_REACHED_START_IND);
            message->avrcp = avrcp;
#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif
            message->response = response;
            MessageSend(avrcp->clientTask, 
                        AVRCP_EVENT_TRACK_REACHED_START_IND, message);
        }
        break;
    case avrcp_event_playback_pos_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_PLAYBACK_POS_CHANGED_IND);
            message->avrcp = avrcp;
#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif

            message->response = response;
            /*
             * If the Packet comes in continuation or end packet fragmented,
             * it may  not process the Identifier which is 8 octets long
             */
            if(data_len >= 4)
            {
                message->playback_pos =
                             convertUint8ValuesToUint32(&ptr[data_start]);
            }
            else
            {
                message->playback_pos = 0;
            }
            MessageSend(avrcp->clientTask,
                        AVRCP_EVENT_PLAYBACK_POS_CHANGED_IND, message);
        }
        break;
    case avrcp_event_batt_status_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_BATT_STATUS_CHANGED_IND);
            message->avrcp = avrcp;
#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif
            message->response = response;
            if(data_len)
            {
                message->battery_status = ptr[data_start];
            }
            else
            {
                message->battery_status = 0;
            }
            MessageSend(avrcp->clientTask,
                        AVRCP_EVENT_BATT_STATUS_CHANGED_IND, message);
        }
        break;
    case avrcp_event_system_status_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_SYSTEM_STATUS_CHANGED_IND);
            message->avrcp = avrcp;
#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
#endif

            message->response = response;
            if(data_len)
            {
                message->system_status = ptr[data_start];
            }
            else
            {
                message->system_status = 0;
            }
            MessageSend(avrcp->clientTask,
                        AVRCP_EVENT_SYSTEM_STATUS_CHANGED_IND, message);
        }
        break;
    case avrcp_event_player_app_setting_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_PLAYER_APP_SETTING_CHANGED_IND);

            message->avrcp = avrcp;
#ifdef AVRCP_ENABLE_DEPRECATED 
        /* Deprecated fields will be removed later */
            message->transaction = transaction;
            message->no_packets = 0;
            message->ctp_packet_type = AVCTP0_PACKET_TYPE_SINGLE;
            message->data_offset = 0;
            message->metadata_packet_type = avrcp_packet_type_single;
#endif

            message->response = response;

            if(data_len >= 3){
                message->number_of_attributes = ptr[data_start];
                message->attributes =avrcpSourceFromConstData(avrcp, 
                                    ptr+data_start+1, data_len-1);
                message->size_attributes = data_len - 1;
            }
            else
            {
                message->number_of_attributes = 0;
                message->size_attributes = 0;
                message->attributes = 0;
            }

            MessageSend(avrcp->clientTask,
                        AVRCP_EVENT_PLAYER_APP_SETTING_CHANGED_IND, message);

        }
        break;
    case avrcp_event_now_playing_content_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED_IND);
            message->avrcp = avrcp;
             message->response = response;
            MessageSend(avrcp->clientTask,
                       AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED_IND, 
                       message);

        }
        break;

    case avrcp_event_available_players_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED_IND);
            message->avrcp = avrcp;
            message->response = response;
            MessageSend(avrcp->clientTask,
                       AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED_IND, message);
        }
        break;

    case  avrcp_event_addressed_player_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED_IND);
            message->avrcp = avrcp;

            message->response = response;
            if(data_len >= 4)
            {
                AVRCP_UINT8_TO_UINT16(ptr, message->player_id, data_start);
                AVRCP_UINT8_TO_UINT16(ptr, message->uid_counter, data_start+2);
                                     
            }
            else
            {
                message->player_id = 0;
                message->uid_counter = 0;
            }

            MessageSend(avrcp->clientTask,
                        AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED_IND, message);
        }
        break;

    case avrcp_event_uids_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_UIDS_CHANGED_IND);
            message->avrcp = avrcp;

            message->response = response;
            if(data_len >= 2)
            {
                AVRCP_UINT8_TO_UINT16(ptr,message->uid_counter,data_start);
            }
            else
            {
                message->uid_counter = 0;
            }

            MessageSend(avrcp->clientTask,
                       AVRCP_EVENT_UIDS_CHANGED_IND, 
                       message);
        }
    
        break;

    case avrcp_event_volume_changed:
        {
            MAKE_AVRCP_MESSAGE(AVRCP_EVENT_VOLUME_CHANGED_IND);

            message->avrcp = avrcp;

            message->response = response;
            if(data_len)
            {
                message->volume = ptr[data_start];
            }
            else
            {
                message->volume = 0;
            }
            MessageSend(avrcp->clientTask,
                        AVRCP_EVENT_VOLUME_CHANGED_IND, message);
        }   
        break;
    default:
        /* Unknown event. ignore */
        return;
    }

    if(response != avctp_response_interim)
    {
        clearRegisterNotification(avrcp, event_id);
    }

    /* Clear the pending flag only if the library was waiting for 
       the corresponding REGISTER_NOTIFICATION response. 
       otherwise ignore */
    if((event_id + avrcp_events_start_dummy) == avrcp->pending)
    {
        (void) MessageCancelAll(&avrcp->task, AVRCP_INTERNAL_WATCHDOG_TIMEOUT);
        avrcp->pending = avrcp_none;
    }

    return;

}