void sendUnitInfoResponse(AVRCP *avrcp, bool accept, avc_subunit_type unit_type, uint8 unit, uint32 company_id) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_UNITINFO_RES); #ifdef AVRCP_DEBUG_LIB if (unit_type > 0x1F) { AVRCP_DEBUG(("Out of range subunit type 0x%x\n", unit_type)); } if (unit > 0x07) { AVRCP_DEBUG(("Out of range unit 0x%x\n", unit)); } if (company_id > 0xFFFFFF) { AVRCP_DEBUG(("Out of range company id 0x%lx\n", company_id)); } #endif message->accept = accept; message->unit_type = unit_type; message->unit = unit; message->company_id = company_id; MessageSend(&avrcp->task, AVRCP_INTERNAL_UNITINFO_RES, message); }
/*lint -e818 -e830 */ void AvrcpPassthrough(AVRCP *avrcp, avc_subunit_type subunit_type, avc_subunit_id subunit_id, bool state, avc_operation_id opid, uint16 operation_data_length, Source operation_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 (opid > 0x7F) { AVRCP_DEBUG(("Out of range op id 0x%x\n", opid)); } #endif if (avrcp->block_received_data || (avrcp->pending && (avrcp->pending != avrcp_next_group) && (avrcp->pending != avrcp_previous_group))) avrcpSendPassthroughCfmToClient(avrcp, avrcp_busy); else if (!avrcp->sink) /* Immediately reject the request if we have not been passed a valid sink */ avrcpSendPassthroughCfmToClient(avrcp, avrcp_invalid_sink); else { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_PASSTHROUGH_REQ); message->subunit_type = subunit_type; message->subunit_id = subunit_id; message->state = state; message->opid = opid; if (opid == opid_vendor_unique) { message->operation_data = operation_data; message->operation_data_length = operation_data_length; } else { if (SourceSize(operation_data)) SourceEmpty(operation_data); message->operation_data = 0; message->operation_data_length = 0; } MessageSend(&avrcp->task, AVRCP_INTERNAL_PASSTHROUGH_REQ, message); } }
/**************************************************************************** NAME handleUnexpected DESCRIPTION This function is called as a result of a message arriving when this library was not expecting it. */ static void handleUnexpected(avrcpUnexpectedReasonCode code, avrcpState state, uint16 type) { state = state; type = type; code = code; AVRCP_DEBUG(("handleUnexpected - Code 0x%x State 0x%x MsgId 0x%x\n", code, state, type)); }
void AvrcpConnect(AVRCP *avrcp, const bdaddr *bd_addr) { #ifdef AVRCP_DEBUG_LIB if (!bd_addr) { AVRCP_DEBUG(("Null Bluetooth address pointer\n")); } #endif avrcpSendInternalConnectReq(avrcp, bd_addr); }
/**************************************************************************** NAME AvrcpGetSink DESCRIPTION This function is called to retrieve the connection Sink. PARAMETER RETURNED The connection sink. This will be 0 if no connection exists. */ Sink AvrcpGetSink(AVRCP *avrcp) { if (!avrcp) { #ifdef AVRCP_DEBUG_LIB AVRCP_DEBUG(("AvrcpGetSink NULL AVRCP instance\n")); #endif return (Sink)0; } return avrcp->sink; }
/*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); } }
/**************************************************************************** *NAME * AvrcpBrowseGetFolderItemsResponse * *DESCRIPTION * This function is used to send response for GetFolderItems command to CT. * This will be called in response to a AVRCP_BROWSE_GET_FOLDER_ITEMS_IND * message. * *PARAMETRS * avrcp - Task * avrcp_response_type- response. avrcp_response_browsing_success on Success. * uint16 - UID Counter. 0 for non database aware players * uint16 - number of items returned * uint16 - size of the item list in bytes * Source - item list *****************************************************************************/ void AvrcpBrowseGetFolderItemsResponse( AVRCP* avrcp, avrcp_response_type response, uint16 uid_counter, uint16 num_items, uint16 item_list_size, Source item_list) { AVBP *avbp = (AVBP*)avrcp->avbp_task; if((SourceBoundary(item_list) < item_list_size) || (!num_items && item_list_size) || (item_list_size > (avbp->avbp_mtu - AVBP_MAX_FIXED_PDU_SIZE))) { AVRCP_DEBUG(("Wrong parameters\n")); if(item_list) { SourceEmpty(item_list); } return; } if((isAvbpCheckConnected(avbp)) && (avbp->blocking_cmd == AVBP_GET_FOLDER_ITEMS_PDU_ID)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_GET_FOLDER_ITEMS_RES); message->response = response; message->num_items = num_items; message->item_list_size = item_list_size; message->item_list = item_list; if(isAvrcpDatabaseEnabled(avrcpGetDeviceTask())) { message->uid_counter = uid_counter; } else { message->uid_counter = 0; } /* Queue the Response */ MessageSend(&avbp->task, AVRCP_INTERNAL_GET_FOLDER_ITEMS_RES, message); } else { AVRCP_INFO(("Wrong State. Ignoring the response\n")); if(item_list) { SourceEmpty(item_list); } } }
/**************************************************************************** NAME AvrcpVendorDependentResponse DESCRIPTION This function is called in response to an AVRCP_VENDORDEPENDENT_IND message to verify the data that was sent. MESSAGE RETURNED */ void AvrcpVendorDependentResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_VENDORDEPENDENT_RES); #ifdef AVRCP_DEBUG_LIB if ((response < avctp_response_not_implemented) || (response > avctp_response_bad_profile)) { AVRCP_DEBUG(("Out of range response 0x%x\n", response)); } #endif message->response= response; MessageSend(&avrcp->task, AVRCP_INTERNAL_VENDORDEPENDENT_RES, message); }
void sendVendorDependentResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_VENDORDEPENDENT_RES); #ifdef AVRCP_DEBUG_LIB if (response > avctp_response_interim) { AVRCP_DEBUG(("Out of range response 0x%x\n", response)); } #endif message->response= response; MessageSend(&avrcp->task, AVRCP_INTERNAL_VENDORDEPENDENT_RES, message); }
void sendPassThroughResponse(AVRCP *avrcp, avrcp_response_type response) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_PASSTHROUGH_RES); #ifdef AVRCP_DEBUG_LIB if (response > avctp_response_interim) { AVRCP_DEBUG(("Out of range response 0x%x\n", response)); } #endif message->response = response; MessageSend(&avrcp->task, AVRCP_INTERNAL_PASSTHROUGH_RES, message); }
void AvrcpBrowseGetItemAttributesResponse(AVRCP* avrcp, avrcp_response_type response, uint8 num_attributes, uint16 size_attr_list, Source attr_value_list) { AVBP *avbp = (AVBP*)avrcp->avbp_task; if((SourceBoundary(attr_value_list) < size_attr_list) || (!num_attributes && size_attr_list) || (size_attr_list > (avbp->avbp_mtu - AVBP_MAX_FIXED_PDU_SIZE))) { AVRCP_DEBUG(("Invalid parameters\n")); if(attr_value_list) { SourceEmpty(attr_value_list); } return; } /* validate avbp and send the message if it is connected */ if((isAvbpCheckConnected(avbp)) && (avbp->blocking_cmd == AVBP_GET_ITEM_ATTRIBUTES_PDU_ID)) { MAKE_AVRCP_MESSAGE(AVRCP_INTERNAL_GET_ITEM_ATTRIBUTES_RES); message->response = response; message->num_attributes = num_attributes; message->size_attr_list = size_attr_list; message->attr_value_list = attr_value_list; /* Queue the Response */ MessageSend(&avbp->task, AVRCP_INTERNAL_GET_ITEM_ATTRIBUTES_RES, message); } else { AVRCP_INFO(("Wrong State.Ignoring the response\n")); if(attr_value_list) { SourceEmpty(attr_value_list); } } }
/*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 * avrcpAvctpReceiveMessage * *DESCRIPTION * This function is called to process the AVCTP message received. * *PARAMETERS * avrcp - Task * * ptr - Received Data * packet_size - packet_size * *RETURN * bool - Return TRUE if the message is ready to process, otherwise return * FALSE *******************************************************************************/ bool avrcpAvctpReceiveMessage( AVRCP *avrcp, const uint8* ptr, uint16 packet_size) { bool result = FALSE; uint16 packet_type = ptr[AVCTP_HEADER_START_OFFSET] & AVCTP0_PACKET_TYPE_MASK; uint16 pid_offset = AVCTP_SINGLE_PKT_PID_OFFSET; uint8* temp; uint8 cr_type= ptr[0] & AVCTP0_CR_MASK; switch(packet_type) { case AVCTP0_PACKET_TYPE_START: if(packet_size < AVRCP_START_PKT_HEADER_SIZE) { break; } /* Check remote device is planning to send a Message greater than AV Size */ if((((ptr[AVCTP_NUM_PKT_OFFSET]-1) * avrcp->l2cap_mtu) > AVRCP_AVC_MAX_PKT_SIZE) || (ptr[AVCTP_NUM_PKT_OFFSET] <= 1)) { if(cr_type == AVCTP0_CR_COMMAND) { avrcp->av_msg = (uint8*)ptr; avrcpSendAvcResponse(avrcp, AVRCP_START_PKT_HEADER_SIZE, avctp_response_rejected, 0, NULL); } break; } pid_offset = AVCTP_START_PKT_PID_OFFSET; case AVCTP0_PACKET_TYPE_SINGLE: /* Fall through */ if(packet_size < AVRCP_TOTAL_HEADER_SIZE) { break; } /* Check if we have received any fragmented pkts before */ if(avrcp->av_msg_len) { /* Silently drop it */ free(avrcp->av_msg); avrcp->av_msg_len = 0; } /* Check the PID Values */ if (ptr[pid_offset] != AVCTP1_PROFILE_AVRCP_HIGH) { avrcp->av_msg = (uint8*)ptr; avrcpSendAvcResponse(avrcp,0,avctp_response_bad_profile, 0, NULL); break; } if(ptr[pid_offset+1] != AVCTP2_PROFILE_AVRCP_REMOTECONTROL) { if(((avrcp->device_type == avrcp_target) && (ptr[pid_offset+1] != AVCTP2_PROFILE_AVRCP_CONTROLTARGET)) || ((avrcp->device_type == avrcp_controller) && (ptr[pid_offset+1] != AVCTP2_PROFILE_AVRCP_REMOTECONTROLLER))) { avrcp->av_msg = (uint8*)ptr; avrcpSendAvcResponse(avrcp,0,avctp_response_bad_profile,0,NULL); break; } } if(packet_type == AVCTP0_PACKET_TYPE_SINGLE) { avrcp->av_msg = (uint8*)ptr; avrcp->av_msg_len = packet_size; result = TRUE; } else { /* * Allocate memory and copy the fragmented packet for reassembling * This allocated memory is freed in avrcpSourceProcessed() after * processing the packet. Memory is freed after sending the response * for command packets and for response packets it is freed after * processing the response. This memory may be send to application * if it contains any data interested to the app. In this case, app * shall call AvrcpSourceProcessed() to free it. */ avrcp->av_msg= (uint8*)PanicUnlessMalloc(packet_size); avrcp->av_msg_len=packet_size; memmove(avrcp->av_msg, ptr, packet_size); avrcp->av_msg[AVCTP_NUM_PKT_OFFSET]--; } break; case AVCTP0_PACKET_TYPE_CONTINUE: case AVCTP0_PACKET_TYPE_END: if((avrcp->av_msg_len == 0)||(packet_size < AVCTP_CONT_PKT_HEADER_SIZE) || (avrcp->av_msg[AVCTP_NUM_PKT_OFFSET] == 0) ) { /* Bad Packet. Just ignore */ break; } /* Check the transaction ID */ if((ptr[AVCTP_HEADER_START_OFFSET] & AVCTP_TRANSACTION_MASK) != (avrcp->av_msg[AVCTP_HEADER_START_OFFSET] & AVCTP_TRANSACTION_MASK)) { /* Send the Response and Drop the packet */ avrcpSendAvcResponse(avrcp, AVRCP_START_PKT_HEADER_SIZE, avctp_response_rejected, 0, NULL); break; } /* Reassemble the Continuation Packet */ temp = (uint8*)realloc(avrcp->av_msg, avrcp->av_msg_len+packet_size-1); if(!temp) { /* We failed to allocate memory . Stop receiving further packets and give this to app for processing */ avrcp->av_msg[AVCTP_NUM_PKT_OFFSET] = 0; /* Panic in Debug Mode */ AVRCP_DEBUG(("Failed to realloc memory for the received fragment")); } else { /* Ignore the 1 byte Header */ packet_size--; memmove(temp+avrcp->av_msg_len, &ptr[1],packet_size); avrcp->av_msg=temp; avrcp->av_msg_len+= packet_size; /* Reduce the number of packets */ avrcp->av_msg[AVCTP_NUM_PKT_OFFSET]--; } if((packet_type == AVCTP0_PACKET_TYPE_END) || (avrcp->av_msg[AVCTP_NUM_PKT_OFFSET] == 0)) { /* Last packet Received */ result = TRUE; } break; } return result; }