/**************************************************************************** * NAME * avrcpSendCommonFragmentedMetadataCfm * * DESCRIPTION * Send MetaData confirm to the CT application with the extracted data from * the response * * RETURNS * void *******************************************************************************/ void avrcpSendCommonFragmentedMetadataCfm(AVRCP *avrcp, avrcp_status_code status, uint16 id, uint16 metadata_packet_type, uint16 data_length, const uint8* data) { uint16 offset=0; MAKE_AVRCP_MESSAGE(AVRCP_COMMON_FRAGMENTED_METADATA_CFM); message->avrcp = avrcp; message->status = status; #ifdef AVRCP_ENABLE_DEPRECATED if(avrcp->av_msg) { message->transaction = (avrcp->av_msg[AVCTP_HEADER_START_OFFSET] >> AVCTP0_TRANSACTION_SHIFT); }
/**************************************************************************** *NAME * avrcpHandleRegisterNotificationCommand * *DESCRIPTION * Handle an incoming Register Notification command. * *PARAMETERS * avrcp - AVRCP instance * ptr - Data pointer to the command. ****************************************************************************/ void avrcpHandleRegisterNotificationCommand(AVRCP *avrcp, const uint8 *ptr) { uint8 event = ptr[0]; MAKE_AVRCP_MESSAGE(AVRCP_REGISTER_NOTIFICATION_IND); message->avrcp = avrcp; #ifdef AVRCP_ENABLE_DEPRECATED /* Deprecated fields will be removed later */ message->transaction = avrcp->rsp_transaction_label; #endif message->event_id = event; message->playback_interval = convertUint8ValuesToUint32(&ptr[1]); /* Store which event has been registered for. */ avrcp->registered_events |= (1<<event); /* Store the transaction label associated with the event. */ avrcp->notify_transaction_label[event-1] = avrcp->rsp_transaction_label; MessageSend(avrcp->clientTask,AVRCP_REGISTER_NOTIFICATION_IND,message); }
/**************************************************************************** *NAME * AvrcpEventSystemStatusChangedResponse * *DESCRIPTION * API function to notify battery status change event at TG. * *PARAMETERS * avrcp - Task * response - On success , avctp_response_interim for intermediate response * and avctp_response_changed for final response. * battery_status - Current battery status * *RETURN *****************************************************************************/ void AvrcpEventSystemStatusChangedResponse(AVRCP *avrcp, avrcp_response_type response, avrcp_system_status system_status) { /* Only send a response if this event was registered by the CT. */ if (avrcp->registered_events & (1<<EVENT_SYSTEM_STATUS_CHANGED)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_EVENT_SYSTEM_STATUS_CHANGED_RES); message->response = response; message->system_status = system_status; MessageSend(&avrcp->task, AVRCP_INTERNAL_EVENT_SYSTEM_STATUS_CHANGED_RES, message); if (response == avctp_response_changed) clearRegisterNotification(avrcp, EVENT_SYSTEM_STATUS_CHANGED); } else { AVRCP_INFO(("AvrcpEventSystemStatusChangedResponse: Event not registered\n")); } }
void avrcpSendGetPlayStatusCfm(AVRCP *avrcp, avrcp_status_code status, uint32 song_length, uint32 song_elapsed, avrcp_play_status play_status, uint8 transaction) { MAKE_AVRCP_MESSAGE(AVRCP_GET_PLAY_STATUS_CFM); message->avrcp = avrcp; #ifdef AVRCP_ENABLE_DEPRECATED /* Deprecated fields will be removed later */ message->transaction = transaction; #endif message->status = status; message->song_length = song_length; message->song_elapsed = song_elapsed; message->play_status = play_status; MessageSend(avrcp->clientTask, AVRCP_GET_PLAY_STATUS_CFM, message); }
void AvrcpEventPlaybackPosChangedResponse(AVRCP *avrcp, avrcp_response_type response, uint32 playback_pos) { /* Only send a response if this event was registered by the CT. */ if (avrcp->registered_events & (1<<EVENT_PLAYBACK_POS_CHANGED)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_EVENT_PLAYBACK_POS_CHANGED_RES); message->response = response; message->playback_pos = playback_pos; MessageSend(&avrcp->task, AVRCP_INTERNAL_EVENT_PLAYBACK_POS_CHANGED_RES, message); if (response == avctp_response_changed) clearRegisterNotification(avrcp, EVENT_PLAYBACK_POS_CHANGED); } else { AVRCP_INFO(("AvrcpEventPlaybackPosChangedResponse: Event not registered\n")); } }
/**************************************************************************** *NAME * avrcpHandleListAppValuesCommand * *DESCRIPTION * Handle the incoming PlayerApplicationListValues Command from CT. * *PARAMETERS * AVRCP - AVRCP Instance * attribute_id - Requested attribute ID for Value. ****************************************************************************/ void avrcpHandleListAppValuesCommand(AVRCP *avrcp, uint16 attribute_id) { if (!isAvrcpPlayerSettingsEnabled(avrcpGetDeviceTask())) { sendListValuesResponse(avrcp, avctp_response_not_implemented, 0, 0); } else { /* We know this PDU cannot be fragmented. Pass the request directly to the client. */ MAKE_AVRCP_MESSAGE(AVRCP_LIST_APP_VALUE_IND); message->avrcp = avrcp; #ifdef AVRCP_ENABLE_DEPRECATED /* Deprecated fields will be removed later */ message->transaction = avrcp->rsp_transaction_label; #endif message->attribute_id = attribute_id; MessageSend(avrcp->clientTask, AVRCP_LIST_APP_VALUE_IND, message); } }
/**************************************************************************** *NAME * AvrcpSetAbsoluteVolumeResponse * *DESCRIPTION * API function to respond to SetAbsoluteVolume request. TG application shall * call function on receiving AVRCP_SET_ABSOLUTE_VOLUME_IND. If the volume * got changed due to this procedure, Application must call * AvrcpEventVolumeChangedResponse() if CT has registered for * EVENT_VOLUME_CHANGED notification. * *PARAMETERS * avrcp - Task * avrcp_response_code - response. Expected responses are * avctp_response_accepted or avctp_response_rejected * or avrcp_response_rejected_internal_error. * uint8 - Volume at TG. 0x0 as Minimum and 0x7F as Max * *RETURN *******************************************************************************/ void AvrcpSetAbsoluteVolumeResponse(AVRCP *avrcp, avrcp_response_type response, uint8 volume) { if (avrcp->block_received_data == avrcp_absolute_volume) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_SET_ABSOLUTE_VOL_RES); message->volume=(volume < AVRCP_MAX_VOL_MASK)?volume:AVRCP_MAX_VOL_MASK; message->response=response; MessageSend(&avrcp->task, AVRCP_INTERNAL_SET_ABSOLUTE_VOL_RES, message); } else { AVRCP_INFO(("AvrcpSetAbsoluteVolumeResponse: CT is not waiting for" " the response\n")); } }
/*lint -e818 -e830 */ void AvrcpVendorDependent(AVRCP *avrcp, avc_subunit_type subunit_type, avc_subunit_id subunit_id, uint8 ctype, uint32 company_id, uint16 data_length, Source data) { #ifdef AVRCP_DEBUG_LIB if (subunit_type > 0x1F) { AVRCP_DEBUG(("Out of range subunit type 0x%x\n", subunit_type)); } if (subunit_id > 0x07) { AVRCP_DEBUG(("Out of range subunit id 0x%x\n", subunit_id)); } if (company_id > 0xFFFFFF) { AVRCP_DEBUG(("Out of range company id 0x%lx\n", company_id)); } #endif if (avrcp->block_received_data || (avrcp->pending && (avrcp->pending < avrcp_get_caps))) avrcpSendVendordependentCfmToClient(avrcp, avrcp_busy, 0); else if (!avrcp->sink) { /* Immediately reject the request if we have not been passed a valid sink */ if (avrcp->pending >= avrcp_get_caps) avrcpSendMetadataFailCfmToClient(avrcp, avrcp_invalid_sink); else avrcpSendVendordependentCfmToClient(avrcp, avrcp_invalid_sink, 0); } else { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_VENDORDEPENDENT_REQ); message->company_id = company_id; message->subunit_type = subunit_type; message->subunit_id = subunit_id; message->ctype = ctype; message->data = data; message->data_length = data_length; MessageSend(&avrcp->task, AVRCP_INTERNAL_VENDORDEPENDENT_REQ, message); } }
void AvrcpEventTrackChangedResponse(AVRCP *avrcp, avrcp_response_type response, uint32 track_index_high, uint32 track_index_low) { /* Only send a response if this event was registered by the CT. */ if (avrcp->registered_events & (1<<EVENT_TRACK_CHANGED)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_EVENT_TRACK_CHANGED_RES); message->response = response; message->track_index_high = track_index_high; message->track_index_low = track_index_low; MessageSend(&avrcp->task, AVRCP_INTERNAL_EVENT_TRACK_CHANGED_RES, message); if (response == avctp_response_changed) clearRegisterNotification(avrcp, EVENT_TRACK_CHANGED); } else { AVRCP_INFO(("AvrcpEventTrackChangedResponse: Event not registered\n")); } }
/**************************************************************************** *NAME * AvrcpBrowseSearchResponse * *DESCRIPTION * This function is used to send response for Search command to CT. * This will be called in response to a AVRCP_BROWSE_SEARCH_IND * message. * *PARAMETRS * avrcp - Task * avrcp_response_type- response. avrcp_response_browsing_success on Success. * uint16 - UID Counter * uint32 - Number of matching items *****************************************************************************/ void AvrcpBrowseSearchResponse(AVRCP* avrcp, avrcp_response_type response, uint16 uid_counter, uint32 num_items) { AVBP *avbp = (AVBP*)avrcp->avbp_task; if(isAvbpCheckConnected(avbp)) { if(avbp->blocking_cmd == AVBP_SEARCH_PDU_ID) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_SEARCH_RES); message->response = response; message->num_items = num_items; if(isAvrcpDatabaseEnabled(avrcpGetDeviceTask())) { message->uid_counter = uid_counter; } else { message->uid_counter = 0; } /* Queue the Response */ MessageSend(&avbp->task, AVRCP_INTERNAL_SEARCH_RES, message); } else { AVRCP_INFO(("GetFolderItems Command is not pending\n")); } } else { AVRCP_INFO(("Browsing channel not connected. Ignoring the response\n")); } }
/*lint -e818 -e830 */ void AvrcpSubUnitInfo(AVRCP *avrcp, uint8 page) { #ifdef AVRCP_DEBUG_LIB if (page > 0x07) { AVRCP_DEBUG(("Out of range page 0x%x\n", page)); } #endif if (avrcp->dataFreeTask.sent_data || avrcp->block_received_data || avrcp->pending) avrcpSendSubunitInfoCfmToClient(avrcp, avrcp_busy, 0, 0); else if (!avrcp->sink) /* Immediately reject the request if we have not been passed a valid sink */ avrcpSendSubunitInfoCfmToClient(avrcp, avrcp_invalid_sink, 0, 0); else { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_SUBUNITINFO_REQ); message->page = page; MessageSend(&avrcp->task, AVRCP_INTERNAL_SUBUNITINFO_REQ, message); } }
/**************************************************************************** *NAME * AvrcpEventVolumeChangedResponse * *DESCRIPTION * TG shall use this API function to send volume change events if CT has * Registered for EVENT_VOLUME_CHANGED notifications. TG shall send an interim * response immediately after receiving a AVRCP_REGISTER_NOTIFICATION_IND for * EVENT_VOLUME_CHANGED from the CT before sending the final response on Volume * change. Otherwise lib will reject the Register Notification request from CT * after timeout of 1000ms. * * *PARAMETERS * avrcp - Task * avrcp_response_code - response. Response indicating whether the volume * has been changed or the notification was * rejected. * Expected response values avctp_response_changed, * avrcp_response_interim or avctp_response_rejected. * uint8 - Volume at TG. 0x0 as Minimum and 0x7F as Max * *RETURN *******************************************************************************/ void AvrcpEventVolumeChangedResponse(AVRCP *avrcp, avrcp_response_type response, uint8 volume) { /* Only send a response if this event was registered by the CT. */ if (isEventRegistered(avrcp,EVENT_VOLUME_CHANGED)) { /* Internal Event response */ MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_EVENT_VOLUME_CHANGED_RES); message->volume=(volume < AVRCP_MAX_VOL_MASK)?volume:AVRCP_MAX_VOL_MASK; message->response=response; MessageSend(&avrcp->task, AVRCP_INTERNAL_EVENT_VOLUME_CHANGED_RES, message); } else { AVRCP_INFO(("AvrcpEventVolumeChangedResponse: " "Event not registered\n")); } }
void AvrcpConnectLazy(Task clientTask, const bdaddr *bd_addr, const avrcp_init_params *config) { if (!config) { /* Client must pass down a valid config so report connect fail */ MAKE_AVRCP_MESSAGE(AVRCP_CONNECT_CFM); message->status = avrcp_fail; message->sink = 0; message->avrcp = 0; MessageSend(clientTask, AVRCP_CONNECT_CFM, message); /* TODO use fun below but it needs updating avrcpSendCommonCfmMessageToApp(AVRCP_CONNECT_CFM, avrcp_fail, 0, avrcp); */ } else { AVRCP *avrcp = PanicUnlessNew(AVRCP); avrcpInitTaskData(avrcp, clientTask, avrcpReady, config->device_type, config->supported_controller_features, config->supported_target_features, config->profile_extensions, 1); avrcpSendInternalConnectReq(avrcp, bd_addr); } }
/**************************************************************************** *NAME * AvrcpBrowseChangePathResponse * *DESCRIPTION * This function is used to send response for Changepath command to CT. * This will be called in response to a AVRCP_BROWSE_CHANGE_PATH_IND message. * *PARAMETRS * avrcp - Task * avrcp_response_type- response. avrcp_response_browsing_success on Success. * uint32 - number of items *****************************************************************************/ void AvrcpBrowseChangePathResponse(AVRCP* avrcp, avrcp_response_type response, uint32 num_items) { AVBP *avbp = (AVBP*)avrcp->avbp_task; /* validate avbp and send the message if it is connected */ if((isAvbpCheckConnected(avbp)) && (avbp->blocking_cmd == AVBP_CHANGE_PATH_PDU_ID)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_CHANGE_PATH_RES); message->response = response; message->num_items = num_items; /* Queue the Response */ MessageSend(&avbp->task, AVRCP_INTERNAL_CHANGE_PATH_RES, message); } else { AVRCP_INFO(("Wrong state.Ignoring the response\n")); } }
/**************************************************************************** *NAME * AvrcpEventPlayerAppSettingChangedResponse * *DESCRIPTION * API function to notify player app setting change event at TG. * *PARAMETERS * avrcp - Task * response - On success , avctp_response_interim for intermediate response * and avctp_response_changed for final response. * size_attributes - The length of the supplied attribute data (in bytes) * attributes - The list of attribute data returned in the response. * *RETURN *****************************************************************************/ void AvrcpEventPlayerAppSettingChangedResponse(AVRCP *avrcp, avrcp_response_type response, uint16 size_attributes, Source attributes) { /* Only send a response if this event was registered by the CT. */ if (avrcp->registered_events & (1<<EVENT_PLAYER_SETTING_CHANGED)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_EVENT_PLAYER_APP_SETTING_CHANGED_RES); message->response = response; message->size_attributes = size_attributes; message->attributes = attributes; MessageSend(&avrcp->task, AVRCP_INTERNAL_EVENT_PLAYER_APP_SETTING_CHANGED_RES, message); if (response == avctp_response_changed) clearRegisterNotification(avrcp, EVENT_PLAYER_SETTING_CHANGED); } else { AVRCP_INFO(("AvrcpEventPlayerAppSettingChangedResponse: " "Event not registered\n")); } }
/**************************************************************************** *NAME * AvrcpBrowseGetFolderItemsRequest * *DESCRIPTION * This function is used to send GetFolderItems Command to the TG. * *PARAMETRS * avrcp - Task * avrcp_browse_scope - Scope for media navigation. * start - Start index of the item in the folder. * end - End index of the item in the folder * uint8 - Number of attributes requested. 0 for all and * 0xFF for No attributes. * Source - Size of source should be number of attributes * 4. * *RETURN * AVRCP_BROWSE_GET_FOLDER_ITEMS_CFM *****************************************************************************/ void AvrcpBrowseGetFolderItemsRequest( AVRCP* avrcp, avrcp_browse_scope scope, uint32 start, uint32 end, uint8 num_attr, Source attr_list) { AVBP *avbp = (AVBP*)avrcp->avbp_task; uint16 size_attr_list = num_attr * 4; if(num_attr == 0 || num_attr == 0xFF) { if(attr_list) { SourceEmpty(attr_list); } size_attr_list = 0; attr_list = 0; } else { /* Validate the length */ if(SourceBoundary(attr_list) < size_attr_list) { AVRCP_INFO(("Invalid length of attributes \n")); avrcpGetFolderItemsCfm(avbp,avrcp_rejected_invalid_content, NULL, 0); if(attr_list) { SourceEmpty(attr_list); } return; } } /* validate the start and end index */ if(start > end) { AVRCP_INFO(("End index > Start\n")); avrcpGetFolderItemsCfm(avbp, avrcp_rejected_out_of_bound, NULL, 0); if(attr_list) { SourceEmpty(attr_list); } return; } if(isAvbpCheckConnected(avbp)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_GET_FOLDER_ITEMS_REQ); message->scope = scope; message->start = start; message->end = end; message->num_attr = num_attr; message->attr_list_size = size_attr_list; message->attr_list = attr_list; /* Queue the Command if there is any Outstanding command in progress */ MessageSendConditionally(&avbp->task, AVRCP_INTERNAL_GET_FOLDER_ITEMS_REQ, message, &avbp->blocking_cmd); } else { AVRCP_INFO(("Browsing channel not connected\n")); avrcpGetFolderItemsCfm(avbp, avrcp_browsing_channel_not_connected, NULL, 0); if(attr_list) { SourceEmpty(attr_list); } } }
/**************************************************************************** *NAME * AvrcpBrowseGetItemAttributesRequest * *DESCRIPTION * This function is used to send GetItemAttributes Command to the TG. * *PARAMETRS * avrcp - Task * avrcp_browse_scope - Scope in which the UID of the media element * item or folder item is valid. * avrcp_browse_uid - The UID of the media element item or folder item * uint16 - UID Counter * uint8 - Number of attributes requested. 0 for all and * 0xFF for No attributes. * Source - Size of source should be number of attributes * 4. * *RETURN * AVRCP_BROWSE_GET_ITEM_ATTRIBUTES_CFM *****************************************************************************/ void AvrcpBrowseGetItemAttributesRequest( AVRCP* avrcp, avrcp_browse_scope scope, avrcp_browse_uid uid, uint16 uid_counter, uint8 num_attr, Source attr_list) { AVBP *avbp = (AVBP*)avrcp->avbp_task; uint16 size_attr_list = num_attr * 4; if(num_attr == 0 || num_attr == 0xFF) { if(attr_list) { SourceEmpty(attr_list); } size_attr_list = 0; attr_list = 0; } else { /* Validate the length */ if(SourceBoundary(attr_list) < size_attr_list) { AVRCP_INFO(("Invalid length of attributes \n")); avrcpGetItemAttributesCfm(avbp,avrcp_rejected_invalid_content, NULL, 0); if(attr_list) { SourceEmpty(attr_list); } return; } } /* validate avbp and send the message if it is connected */ if(isAvbpCheckConnected(avbp)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_GET_ITEM_ATTRIBUTES_REQ); message->scope = scope; message->uid = uid; message->uid_counter = uid_counter; message->num_attr = num_attr; message->attr_list_size = size_attr_list; message->attr_list = attr_list; /* Queue the Command if there is any Outstanding command in progress */ MessageSendConditionally(&avbp->task, AVRCP_INTERNAL_GET_ITEM_ATTRIBUTES_REQ, message, &avbp->blocking_cmd); } else { AVRCP_INFO(("Browsing channel not connected\n")); avrcpGetItemAttributesCfm(avbp, avrcp_browsing_channel_not_connected, NULL, 0); if(attr_list) { SourceEmpty(attr_list); } } }
/**************************************************************************** *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; }
void avrcpSendInformBatteryResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_INFORM_BATTERY_STATUS_RES); message->response = response; MessageSend(&avrcp->task, AVRCP_INTERNAL_INFORM_BATTERY_STATUS_RES, message); }
void avrcpSendInformCharSetResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_INFORM_CHAR_SET_RES); message->response = response; MessageSend(&avrcp->task, AVRCP_INTERNAL_INFORM_CHAR_SET_RES, message); }
void sendGroupResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_GROUP_RES); message->response = response; MessageSend(&avrcp->task, AVRCP_INTERNAL_GROUP_RES, message); }
void sendSetValuesResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_SET_APP_VALUE_RES); message->response = response; MessageSend(&avrcp->task, AVRCP_INTERNAL_SET_APP_VALUE_RES, message); }
bool avrcpSendNotification( AVRCP *avrcp, avrcp_response_type response, const uint8* ptr, uint16 packet_size) { uint16 event_id; bool source_processed = TRUE; uint16 data_len = 0; uint16 data_start=0; #ifdef AVRCP_ENABLE_DEPRECATED /* Deprecated fields will be removed later */ uint16 transaction = (avrcp->av_msg[0] & AVCTP_TRANSACTION_MASK) >> AVCTP0_TRANSACTION_SHIFT; #endif event_id = ptr[data_start]; data_start=1; 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 /* EVENT_PLAYBACK_STATUS_CHANGED Length expected is 1 */ if(data_len >= 1){ message->response = response; message->play_status = ptr[data_start]; } else { message->response = avrcp_rejected_invalid_content; 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 */ if(data_len >= 8) { message->response = response; message->track_index_high = convertUint8ValuesToUint32(&ptr[data_start]); message->track_index_low = convertUint8ValuesToUint32(&ptr[data_start+4]); } else { message->response = avrcp_rejected_invalid_content; 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 /* * 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->response = response; message->playback_pos = convertUint8ValuesToUint32(&ptr[data_start]); } else { message->response = avrcp_rejected_invalid_content; 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 if(data_len >= 1){ message->response = response; message->battery_status = ptr[data_start]; } else { message->response = avrcp_rejected_invalid_content; 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 if(data_len >= 1){ message->response = response; message->system_status = ptr[data_start]; } else { message->system_status = 0; message->response = avrcp_rejected_invalid_content; } 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; #endif message->metadata_packet_type = AVCTP0_PACKET_TYPE_SINGLE; message->response = response; if(data_len >= 3){ message->number_of_attributes = ptr[data_start]; source_processed = FALSE; message->attributes =avrcpSourceFromConstData(avrcp, ptr+1, data_len-1); message->size_attributes = data_len - 1; } else { message->number_of_attributes = 0; message->size_attributes = 0; message->attributes = 0; message->response = avrcp_rejected_invalid_content; } MessageSend(avrcp->clientTask, AVRCP_EVENT_PLAYER_APP_SETTING_CHANGED_IND, message); } break; case avrcp_event_volume_changed: { MAKE_AVRCP_MESSAGE(AVRCP_EVENT_VOLUME_CHANGED_IND); message->avrcp = avrcp; if(data_len >= 1){ message->response = response; message->volume = ptr[data_start]; } else { message->volume = 0; message->response = avrcp_rejected_invalid_content; } MessageSend(avrcp->clientTask, AVRCP_EVENT_VOLUME_CHANGED_IND, message); } break; default: /* Unknown event. ignore */ break; } /* 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 source_processed; }
static void avrcpSendInternalConnectReq(AVRCP *avrcp, const bdaddr *bd_addr) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_CONNECT_REQ); message->bd_addr = *bd_addr; MessageSend(&avrcp->task, AVRCP_INTERNAL_CONNECT_REQ, message); }