Example #1
0
/****************************************************************************
NAME    
    hfpHandleSupportedFeaturesInd

DESCRIPTION
    Handle the supported features sent by the AG.

AT INDICATION
    +BRSF

RETURNS
    void
*/
void hfpHandleSupportedFeaturesInd(Task link_ptr, const struct hfpHandleSupportedFeaturesInd *ind)
{
    hfp_link_data* link = (hfp_link_data*)link_ptr;

    /* Deal with supported Features */
    hfpHandleSupportedFeaturesNotification(link, ind->supportedfeat);
    
    /* Send AT+BAC if supported */
    hfpHandleBacRequest(link);
}
Example #2
0
/****************************************************************************
NAME    
    hfpHandleServiceSearchAttributeCfm

DESCRIPTION
    Service search has completed, check it has succeeded and get the required
    attrubutes from the returned list.

RETURNS
    void
*/
void hfpHandleServiceSearchAttributeCfm(const CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *cfm)
{
    /* Get the link from the bdaddr */
    hfp_link_data* link = hfpGetLinkFromBdaddr(&cfm->bd_addr);
    
    /* The link may have been pulled from under us by an early
    disconnect request. If this has happened ignore SDP result */
    if(link)
    {
        /* Check the outcome of the service search */
        if (cfm->status == sdp_response_success)
        {
            uint16 sdp_data  =  0;
            
            if(link->ag_slc_state == hfp_slc_searching)
            {
                if (getRfcommChannelNumber(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data))
                {
                    /* We have an rfcomm channel we can proceed with the connection establishment */
                    hfpSetLinkSlcState(link, hfp_slc_outgoing);
                    /* Use the local channel to specify the security requirements for this connection */
                    ConnectionRfcommConnectRequest(&theHfp->task, &cfm->bd_addr, link->service->rfc_server_channel, sdp_data, 0);
                }
                else
                {
                    /* Received unexpected data.  Should never happen since we're issuing the search and should 
                       know what we're looking.  However, if it does, treat as SDP failure.   */
                    hfpSdpRetry(link);
                }
            }
            else if(link->ag_slc_state == hfp_slc_connected)
            {
                /* If SLC is up then this must be a features request */
                if (getHfpAgSupportedFeatures(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data))
                {    /* Send an internal message with the supported features. */
                    hfpHandleSupportedFeaturesNotification(link, sdp_data);
                }
                /*
                else
                {
                    Received unexpected data.  Should never happen since we're issuing the search and should 
                    know what we're looking.  However, if it does, just ignore since SLC setup is already 
                    being continued.
                }
                */
            }
        }
        else
        {
            /* RFCOMM channel search failed, tell the application */
            if(link->ag_slc_state == hfp_slc_searching)
            {
                if (cfm->status == sdp_no_response_data)
                {
                    /* Retry next profile if possible... */
                    hfpSdpRetry(link);
                }
                else
                {
                    /* Generic fail by default */
                    hfp_connect_status status = hfp_connect_failed;
                    
                    /* Was it a page timeout? */
                    if (cfm->status == sdp_connection_error)
                        status = hfp_connect_timeout;
                    
                    /* Tell the app */
                    hfpSendSlcConnectCfmToApp(link, NULL, status);
                }
            }
        }
    }
}
Example #3
0
/****************************************************************************
NAME	
	hfpHandleServiceSearchAttributeCfm

DESCRIPTION
	Service search has completed, check it has succeeded and get the required
	attrubutes from the returned list.

RETURNS
	void
*/
void hfpHandleServiceSearchAttributeCfm(HFP *hfp, const CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *cfm)
{
	/* Check the outcome of the service search */
	if (cfm->status == sdp_response_success)
	{		
		uint16 sdp_data = 0;

		switch ( hfp->sdp_search_mode )
		{
		case hfp_sdp_search_rfcomm_channel:
			if (getRfcommChannelNumber(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data))
			{	/* We have an rfcomm channel we can proceed with the connection establishment */
			
				HFP_INTERNAL_RFCOMM_CONNECT_REQ_T message ;
				message.addr = cfm->bd_addr;
				message.rfc_channel = sdp_data;
					
				if (hfp->state == hfpSlcConnecting)
					hfpHandleRfcommConnectRequest(hfp, &message);
			
			}
			else
			{
				/* Received unexpected data.  Should never happen since we're issuing the search and should 
			       know what we're looking.  However, if it does, assume a failure has occurred as below.   */
			       
				/* Tell the app the connection attempt has failed. */
			    hfpSendSlcConnectCfmToApp(hfp_connect_sdp_fail, hfp);
			}
			break;
		case hfp_sdp_search_profile_version:
			
			if (getHfpAgProfileVersion(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data))
			{	/* Obtained version of HFP running on AG */
				hfp->agSupportedProfile = (hfp_profile)sdp_data;
				
				if( supportedProfileIsHfp15(hfp->agSupportedProfile) )
				{
					hfpSendRemoteAGProfileVerIndToApp(hfp->agSupportedProfile, hfp);
				}
			}
			else
			{
				/* Received unexpected data.  Should never happen since we're issuing the search and should 
			       know what we're looking.  However, if it does, assume a failure has occurred as below.   */

				/* Incorrect response from AG, so assume it's running HFP v1.0 */
				hfp->agSupportedProfile = hfp_handsfree_profile;
			}
			
			break;
		case hfp_sdp_search_supported_features:
			if (getHfpAgSupportedFeatures(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data))
			{	/* Send an internal message with the supported features. */
				hfpHandleSupportedFeaturesNotification(hfp, sdp_data);
			}
			else
			{
				/* Received unexpected data.  Should never happen since we're issuing the search and should 
			       know what we're looking.  However, if it does, just ignore since SLC setup is already 
			       being continued.                                                                         */
			}
			break;
		default:
			/* 
				else ... We have received data we don't know what to do with.
				This shouldn't happen since we're issuing the search and should 
				know what we're looking for so for the moment just ignore.
			*/
			break;
		}
	}
	else
	{
		switch ( hfp->sdp_search_mode )
		{
		case hfp_sdp_search_rfcomm_channel:
			/* A RFCOMM connection will not exist at this point */
            if (cfm->status == sdp_no_response_data)
			{	/* Tell the app the connection attempt has failed. */
			    hfpSendSlcConnectCfmToApp(hfp_connect_sdp_fail, hfp);
		    }
            else if (cfm->status == sdp_connection_error)
            {	/* If it was a page timeout the client would like to know */
                hfpSendSlcConnectCfmToApp(hfp_connect_timeout, hfp);
            }
            else
            {	/* All other sdp fails */
                hfpSendSlcConnectCfmToApp(hfp_connect_failed, hfp);
            }
			break;
		case hfp_sdp_search_profile_version:
			/* No response from AG, so assume it's running HFP v1.0 */
			hfp->agSupportedProfile = hfp_handsfree_profile;
			break;
		case hfp_sdp_search_supported_features:
			/* Just ignore.  SLC setup is already being continued */
			break;
		default:
			/* 
				else ... We have received data we don't know what to do with.
				This shouldn't happen since we're issuing the search and should 
				know what we're looking for so for the moment just ignore.
			*/
			break;
		}
	}
	
	
	/* Reset sdp search mode */
	hfp->sdp_search_mode = hfp_sdp_search_none;
}