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);
	}
}
Beispiel #7
0
/****************************************************************************
*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);
}
Beispiel #11
0
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;
}