Esempio n. 1
0
/****************************************************************************
NAME    
    HfpResponseHoldActionRequest

DESCRIPTION
    Requests that the AG performs a given response and hold action.
    
MESSAGE RETURNED
    HFP_RESPONSE_HOLD_ACTION_CFM

RETURNS
    void
*/
void HfpResponseHoldActionRequest(hfp_link_priority priority, hfp_btrh_action action)
{
    MAKE_HFP_MESSAGE(HFP_INTERNAL_AT_BTRH_REQ);
    message->link = hfpGetLinkFromPriority(priority);
    message->action = action;
    MessageSend(&theHfp->task, HFP_INTERNAL_AT_BTRH_REQ, message);
}
void HfpCsrModifyIndicators(HFP *hfp, uint16 size_indicators, const hfp_csr_mod_indicator *indicators)
{
	if (hfp->use_csr2csr)
	{
		hfp_csr_mod_indicator *ind;
		
		ind = (hfp_csr_mod_indicator*)malloc(sizeof(hfp_csr_mod_indicator)*size_indicators);
		if (ind)
		{
		    MAKE_HFP_MESSAGE(HFP_INTERNAL_CSR_MOD_INDS_REQ);
			message->size_indicators = size_indicators;
			message->indicators = ind;
			memmove(ind, indicators, sizeof(hfp_csr_mod_indicator)*size_indicators);
		    MessageSend(&hfp->task, HFP_INTERNAL_CSR_MOD_INDS_REQ, message);
		}
		else
		{
			hfpSendCsrModifyIndicatorsCfm(hfp, hfp_csr_mod_ind_no_mem);
		}
	}
	else
	{
		hfpSendCsrModifyIndicatorsCfm(hfp, hfp_csr_not_inited);
	}
}
Esempio n. 3
0
/****************************************************************************
NAME    
    hfpSendSlcConnectCfmToApp

DESCRIPTION
    Send a HFP_SLC_CONNECT_CFM message to the app telling it the outcome
    of the connect attempt.

RETURNS
    void
*/
void hfpSendSlcConnectCfmToApp(hfp_link_data* link, const bdaddr* bd_addr, hfp_connect_status status)
{
    if(link && (link->ag_link_loss_state != hfp_link_loss_none))
    {
        if (status == hfp_connect_success)
            hfpSlcConnectTidy(link);
        
        /* We're trying to recover from link loss... keep going */
        hfpHandleRfcommLinkLossComplete(link, status);
    }
    else
    {
        MAKE_HFP_MESSAGE(HFP_SLC_CONNECT_CFM);
        message->status   = status;
        message->sink     = hfpGetLinkSink(link);
        message->priority = hfpGetLinkPriority(link);
        message->profile  = hfpLinkGetProfile(link);
        /* Try and get bdaddr from the link data */
        if(!hfpGetLinkBdaddr(link, &message->bd_addr) && bd_addr)
            message->bd_addr = *bd_addr;
        
        /* If the connect succeeded need to tidy up a few things */
        if(link)
        {
            if (status == hfp_connect_success)
                hfpSlcConnectTidy(link);
            else if (status != hfp_connect_failed_busy)
                hfpLinkReset(link, TRUE);
        }
        MessageSend(theHfp->clientTask, HFP_SLC_CONNECT_CFM, message);
    }
}
void hfpSendCsrModifyIndicatorsCfm(HFP *hfp, hfp_lib_status status)
{
    MAKE_HFP_MESSAGE(HFP_CSR_MODIFY_INDICATORS_CFM);
    message->hfp = hfp;
    message->status = status;
    MessageSend(hfp->clientTask, HFP_CSR_MODIFY_INDICATORS_CFM, message);
}
Esempio n. 5
0
/****************************************************************************
NAME    
    HfpCallAnswerRequest

DESCRIPTION
    This function is used to answer an incoming call. The AT command to 
    answer the call will be sent out on the SLC corresponding to the 
    priority passed into the function from the application. The message 
    returned indicates whether the command was recognised by the AG or not. 

MESSAGE RETURNED
    HFP_CALL_ANSWER_CFM

RETURNS
    void
*/
void HfpCallAnswerRequest(hfp_link_priority priority, bool accept)
{
    MAKE_HFP_MESSAGE(HFP_INTERNAL_AT_ANSWER_REQ);
    message->link = hfpGetLinkFromPriority(priority);
    message->accept = accept;
    MessageSend(&theHfp->task, HFP_INTERNAL_AT_ANSWER_REQ, message);
}
Esempio n. 6
0
/****************************************************************************
NAME    
    hfpHandleRing

DESCRIPTION
    Received a RING indication.

AT INDICATION
    RING

RETURNS
    void
*/
void hfpHandleRing(Task link_ptr)
{
    /* Get the link we got ring indication on */
    hfp_link_data* link = (hfp_link_data*)link_ptr;

    if(link)
    {
        /* Update call state if required */
        hfpHandleCallRingIndication(link);
        
        if(link->ag_call_state == hfp_call_state_incoming)
        {
            MAKE_HFP_MESSAGE(HFP_RING_IND);
            message->in_band = FALSE;
            
            /* This is an in band ring if... */
            if((hfpLinkIsHfp(link) && agFeatureEnabled(link, AG_IN_BAND_RING)))
            {
                /* ...AG is HFP and supports in band ring */
                message->in_band = TRUE;
            }
            else if(hfpLinkIsHsp(link) && link->audio_state == hfp_audio_connected)
            {
                /* ...AG is HSP and SCO is open */
                message->in_band = TRUE;
            }
            
            /* Send a message to the application */
            message->priority = hfpGetLinkPriority(link);
            MessageSend(theHfp->clientTask, HFP_RING_IND, message);
        }
    }
}
/****************************************************************************
NAME    
    hfpHandleBtrhAtAck

DESCRIPTION
    Request to AG to perform a response and hold action has been acknowledged 
    (completed) by the AG.

RETURNS
    void
*/
void hfpHandleBtrhAtAck(hfp_link_data* link, hfp_btrh_action action, hfp_lib_status status)
{
    MAKE_HFP_MESSAGE(HFP_RESPONSE_HOLD_ACTION_CFM);
    message->priority = hfpGetLinkPriority(link);
    message->action   = action;
    message->status   = status;
    MessageSend(theHfp->clientTask, HFP_RESPONSE_HOLD_ACTION_CFM, message);
}
/****************************************************************************
NAME    
    sendSpeakerVolumeIndToApp

DESCRIPTION
    We're in the right state to inform the app that the volume gain has
    been changed from the AG.

RETURNS
    void
*/
static void sendSpeakerVolumeIndToApp(hfp_link_data* link, uint16 gain)
{
    /* This is generated in response to receiving a volume indication from the AG */
    MAKE_HFP_MESSAGE(HFP_VOLUME_SYNC_SPEAKER_GAIN_IND);
    message->priority = hfpGetLinkPriority(link);
    message->volume_gain = gain;
    MessageSend(theHfp->clientTask, HFP_VOLUME_SYNC_SPEAKER_GAIN_IND, message);
}
Esempio n. 9
0
void HfpCallHoldActionRequest(hfp_link_priority priority, hfp_chld_action action, uint16 index)
{
    MAKE_HFP_MESSAGE(HFP_INTERNAL_AT_CHLD_REQ);
    message->link = hfpGetLinkFromPriority(priority);
    message->action = action;
    message->index = index;
    MessageSend(&theHfp->task, HFP_INTERNAL_AT_CHLD_REQ, message);
}
static void sendIndicatorBattChgToApp(hfp_link_data* link, uint16 batt_chg)
{
    /* Send a message to the app */
    MAKE_HFP_MESSAGE(HFP_BATTCHG_IND);
    message->priority = hfpGetLinkPriority(link);
    message->battchg = batt_chg;
    MessageSend(theHfp->clientTask, HFP_BATTCHG_IND, message);
}
static void sendIndicatorServiceToApp(hfp_link_data* link, uint16 service)
{
    /* Send a message to the app */
    MAKE_HFP_MESSAGE(HFP_SERVICE_IND);
    message->priority = hfpGetLinkPriority(link);
    message->service = service;
    MessageSend(theHfp->clientTask, HFP_SERVICE_IND, message);
}
/****************************************************************************
NAME    
    sendMicVolumeIndToApp

DESCRIPTION
    Pass on the received microphone gain indication to the app.

RETURNS
    void
*/
static void sendMicVolumeIndToApp(hfp_link_data* link, uint16 mic_gain)
{
    /* This is generated in response to receiving a mic indication from the AG */
    MAKE_HFP_MESSAGE(HFP_VOLUME_SYNC_MICROPHONE_GAIN_IND);
    message->priority = hfpGetLinkPriority(link);
    message->mic_gain = mic_gain;
    MessageSend(theHfp->clientTask, HFP_VOLUME_SYNC_MICROPHONE_GAIN_IND, message);
}
static void sendIndicatorRoamToApp(hfp_link_data* link, uint16 roam)
{
    /* Send a message to the app */
    MAKE_HFP_MESSAGE(HFP_ROAM_IND);
    message->priority = hfpGetLinkPriority(link);
    message->roam = roam;
    MessageSend(theHfp->clientTask, HFP_ROAM_IND, message);
}
static void sendIndicatorSignalToApp(hfp_link_data* link, uint16 signal)
{
    /* Send a message to the app */
    MAKE_HFP_MESSAGE(HFP_SIGNAL_IND);
    message->priority = hfpGetLinkPriority(link);
    message->signal = signal;
    MessageSend(theHfp->clientTask, HFP_SIGNAL_IND, message);
}
/*
	Handle +CSR=0 sent from AG
*/
void hfpHandleResponseCSRModAgIndicatorsDisable(Task task)
{
	HFP *hfp = (HFP*)task;
	if (hfp->use_csr2csr)
	{
        MAKE_HFP_MESSAGE(HFP_CSR_AG_INDICATORS_DISABLE_IND);
        message->hfp = hfp;
        MessageSend(hfp->clientTask, HFP_CSR_AG_INDICATORS_DISABLE_IND, message);
	}
}
Esempio n. 16
0
/****************************************************************************
NAME	
	hfpHandleRfcommConnectInd

DESCRIPTION
	Notification of an incoming rfcomm connection, pass this up to the app
	to decide whather to accept this or not.

RETURNS
	void
*/
void hfpHandleRfcommConnectInd(HFP *hfp, const CL_RFCOMM_CONNECT_IND_T *ind)
{
	/* Ask the app whather to accept this connection or not */
	MAKE_HFP_MESSAGE(HFP_SLC_CONNECT_IND);
	message->addr = ind->bd_addr;
	message->hfp = hfp;
	MessageSend(hfp->clientTask, HFP_SLC_CONNECT_IND, message);

	/* Update the local state to indicate we're in the middle of connecting. */
	hfpSetState(hfp, hfpSlcConnecting);
}
static void sendUnhandledIndicatorToApp(hfp_link_data* link, uint16 index, uint16 value)
{
    /*
        We have received an indicator not defined by the HFP spec. Pass it 
        up to the application as it might want to make use of these extra
        indicators that some AGs send out.
    */
    MAKE_HFP_MESSAGE(HFP_EXTRA_INDICATOR_UPDATE_IND);
    message->priority = hfpGetLinkPriority(link);
    message->index = index;
    message->value = value;
    MessageSend(theHfp->clientTask, HFP_EXTRA_INDICATOR_UPDATE_IND, message);
}
/* Send the indicator list to the app so it can parse it for any non-HFP indicators it is interested in */
static void hfpSendUnhandledIndicatorListToApp(hfp_link_data* link, uint16 register_index, uint16 cind_index, uint16 min_range, uint16 max_range)
{
    MAKE_HFP_MESSAGE(HFP_EXTRA_INDICATOR_INDEX_IND);
    message->priority = hfpGetLinkPriority(link);
    message->indicator_register_index = register_index;
    message->indicator_index = cind_index;
    message->min_range = min_range;
    message->max_range = max_range;
    MessageSend(theHfp->clientTask, HFP_EXTRA_INDICATOR_INDEX_IND, message);
    
    /* Store the extra indicator index internally */
    hfpStoreUnhandledIndicator(link, cind_index);
}
Esempio n. 19
0
/****************************************************************************
NAME	
	HfpVoiceRecognitionEnable

DESCRIPTION
	Enable / disable voice recognition function at the AG. An SLC for the 
	supplied profile instance (hfp) must already be established before calling 
	this function. The enable flag determines whether a request will be made 
	to the AG to enabe or disable its voice recognition function. The message 
	returned indicates whether the command was recognised by the AG or not. 
	
	The AG may autonomously notify the HFP device of a change in the state of
	its voice recognition function. This notification will be passed on to the 
	application using a HFP_VOICE_RECOGNITION_IND message.

MESSAGE RETURNED
	HFP_VOICE_RECOGNITION_ENABLE_CFM

RETURNS
	void
*/
void HfpVoiceRecognitionEnable(HFP *hfp, bool enable)
{
#ifdef HFP_DEBUG_LIB
	if (!hfp)
		HFP_DEBUG(("Null hfp task ptr passed in.\n"));
#endif

	{
		/* Send an internal message to kick off SLC creation */
		MAKE_HFP_MESSAGE(HFP_INTERNAL_AT_BVRA_REQ);
		message->enable = enable;
		MessageSend(&hfp->task, HFP_INTERNAL_AT_BVRA_REQ, message);
	}
}
static void hfpSendCsrSupportedFeaturesCfm(HFP *hfp, hfp_lib_status status, bool callerName, bool rawText, bool smsInd, bool battLevel, bool pwrSource , uint16 codecs)
{
    /* Send an internal message */
    MAKE_HFP_MESSAGE(HFP_CSR_SUPPORTED_FEATURES_CFM);
    message->hfp = hfp;
    message->status = status;
	message->callerName = callerName;
	message->rawText = rawText;
	message->smsInd = smsInd;
	message->battLevel = battLevel;
	message->pwrSource = pwrSource;
	message->codecs = codecs ;
    MessageSend(hfp->clientTask, HFP_CSR_SUPPORTED_FEATURES_CFM, message);
}
void hfpHandleFeatureNegotiation  ( Task task , const struct hfpHandleFeatureNegotiation *feat ) 
{
	HFP *hfp = (HFP*)task;
 
    PRINT(("CSFN received\n" ));
    
    if ( hfp->use_csr2csr)
    {
        MAKE_HFP_MESSAGE(HFP_CSR_FEATURE_NEGOTIATION_IND);
        message->hfp = hfp;
	    message->indicator = feat->ind;
        message->value = feat->val ;        
        MessageSend(hfp->clientTask, HFP_CSR_FEATURE_NEGOTIATION_IND, message);        
    }
}
void HfpCsrPowerSource(HFP *hfp, hfp_csr_power_status_report pwr_status)
{
#ifdef HFP_DEBUG_LIB
    if (!hfp)
    {
        HFP_DEBUG(("Null hfp task ptr passed in.\n"));
    }
#endif

	if (hfp->use_csr2csr)
    {
        /* Send an internal message */
        MAKE_HFP_MESSAGE(HFP_INTERNAL_CSR_POWER_SOURCE_REQ);
        message->pwr_status = pwr_status;
        MessageSend(&hfp->task, HFP_INTERNAL_CSR_POWER_SOURCE_REQ, message);
    }
}
Esempio n. 23
0
/****************************************************************************
NAME	
	hfpHandleRfcommDisconnectInd

DESCRIPTION
	Indication that the RFCOMM connection has been disconnected.

RETURNS
	void
*/
void hfpHandleRfcommDisconnectInd(HFP *hfp, const CL_RFCOMM_DISCONNECT_IND_T *ind)
{
	if (hfp->state == hfpSlcConnecting)
	{   /* Rfcomm connection has been shutdown during the SLC connection process */
    	/* Cancel the AT response timeout message because we'll have no more AT cmds being sent */
    	(void) MessageCancelAll(&hfp->task, HFP_INTERNAL_WAIT_AT_TIMEOUT_IND);
    	
	    /* Report a failed connect attempt to app */
		hfpSendSlcConnectCfmToApp(hfp_connect_slc_failed, hfp);
	}
	else
	{   /* Convert the rfc disconnect status into its hfp counterpart and inform library */
    	MAKE_HFP_MESSAGE(HFP_INTERNAL_SLC_DISCONNECT_IND);
    	message->status = convertRfcommDisconnectStatus(ind->status);
    	MessageSend(&hfp->task, HFP_INTERNAL_SLC_DISCONNECT_IND, message);
    }
}
void HfpCsrPowerLevel(HFP *hfp, uint16 pwr_level)
{
#ifdef HFP_DEBUG_LIB
    if (!hfp)
    {
        HFP_DEBUG(("Null hfp task ptr passed in.\n"));
    }
#endif

	if (hfp->use_csr2csr)
    {
        /* Send an internal message */
        MAKE_HFP_MESSAGE(HFP_INTERNAL_CSR_POWER_LEVEL_REQ);
        message->pwr_level = pwr_level;
        MessageSend(&hfp->task, HFP_INTERNAL_CSR_POWER_LEVEL_REQ, message);
    }
}
Esempio n. 25
0
/****************************************************************************
NAME    
    hfpSendSlcDisconnectIndToApp

DESCRIPTION
    Send a HFP_SLC_DISCONNECT_IND message to the app notifying it that
    the SLC has been disconnected.

RETURNS
    void
*/
void hfpSendSlcDisconnectIndToApp(hfp_link_data* link, hfp_disconnect_status status)
{
    MAKE_HFP_MESSAGE(HFP_SLC_DISCONNECT_IND);
    message->status   = status;
    message->priority = hfpGetLinkPriority(link);
    (void)hfpGetLinkBdaddr(link, &message->bd_addr);
    
    /* Tidy up if valid link was disconnected */
    if(status != hfp_disconnect_no_slc)
    {
        /* Reset the connection related state */
        hfpLinkReset(link, TRUE);

        /* Cancel the AT response timeout message because we'll have no more AT cmds being sent */
        (void) MessageCancelAll(&theHfp->task, hfpGetLinkTimeoutMessage(link, HFP_INTERNAL_WAIT_AT_TIMEOUT_LINK_0_IND));
    }
    MessageSend(theHfp->clientTask, HFP_SLC_DISCONNECT_IND, message);
}
void hfpHandleReponseCSRSupportedFeatures(Task task, const struct hfpHandleReponseCSRSupportedFeatures *features)
{
	HFP *hfp = (HFP*)task;
	if (!hfp->use_csr2csr)
    { /* CSR 2 CSR Extensions not initialised.  Ignore */
	    return;
    }
    else
    {
		/* Send internal message */
		MAKE_HFP_MESSAGE(HFP_INTERNAL_CSR_SUPPORTED_FEATURES_ACK);
		message->callerName = (features->callerName=='0'?FALSE:TRUE);
		message->rawText = (features->rawText=='0'?FALSE:TRUE);
		message->smsInd = (features->smsInd=='0'?FALSE:TRUE);
		message->battLevel = (features->battLevel=='0'?FALSE:TRUE);
		message->pwrSource = (features->pwrSource=='0'?FALSE:TRUE);
		MessageSend(task, HFP_INTERNAL_CSR_SUPPORTED_FEATURES_ACK, message);
	}
}
void HfpCsrGetSms(HFP *hfp, uint16 index)
{
#ifdef HFP_DEBUG_LIB
    if (!hfp)
    {
        HFP_DEBUG(("Null hfp task ptr passed in.\n"));
    }
#endif

	if (hfp->use_csr2csr)
    {
        /* Send an internal message */
        MAKE_HFP_MESSAGE(HFP_INTERNAL_CSR_GET_SMS_REQ);
        message->index = index;
        MessageSend(&hfp->task, HFP_INTERNAL_CSR_GET_SMS_REQ, message);
    }
    else
    {
	    hfpSendCsrSmsCfm(hfp, hfp_csr_not_inited, 0, NULL);
    }
}
/****************************************************************************
NAME    
    hfpHandleChldAtAck

DESCRIPTION
    This function handles the receipt of an OK or ERROR response to a
    multiparty call handling request. The status argument is used to inform 
    the application whether the AT command was recognised by the AG or not. 

RETURNS
    void
*/
void hfpHandleChldAtAck(hfp_link_data* link, hfp_chld_action action, hfp_lib_status status)
{
    /* Handle special cases for CHLD Acks */
    if(action == hfp_chld_add_held_to_multiparty)
    {
        /* Enter multiparty state if AG doesn't support CLCC */
        if(status == hfp_success)
            hfpHandleCallMultiparty(link);
    }
    else if(action == hfp_chld_release_active_accept_other)
    {
        hfp_at_cmd pending_cmd = hfpCmdPending;
        
        /* Try sending AT+CHUP if AT+CHLD=1 failed and we are in TWC state (regardless of TWC support) */
        if(status == hfp_fail && hfpCheckCallActionState(link, action, 0, &pending_cmd))
        {
            /* If we already tried sending AT+CHUP give up */
            if(!link->at_chup_retried)
            {
                /* Otherwise attempt sending AT+CHUP */
                link->at_chup_retried = hfpHandleTerminateCall(link, pending_cmd);
                /* If we sent AT+CHUP don't send confirmation yet */
                if(link->at_chup_retried)
                    return;
            }
        }
        /* Clear the chup retry flag */
        link->at_chup_retried = FALSE;
    }
    
#ifndef HFP_MIN_CFM
    {
        MAKE_HFP_MESSAGE(HFP_CALL_HOLD_ACTION_CFM);
        message->priority = hfpGetLinkPriority(link);
        message->action = action;
        message->status = status;
        MessageSend(theHfp->clientTask, HFP_CALL_HOLD_ACTION_CFM, message);
    }
#endif
}
/****************************************************************************
NAME	
	HfpDialMemoryLocation

DESCRIPTION
	This function issues a request to the AG to dial from the the supplied 
	memory_location (the HFP specification defines the command but it is 
	AG implementation dependent how this is implemented). The request is 
	issued on the SLC associated with the hfp profile instance passed in by 
	the application. 
	
	The length argument specifies the length in bytes of the memory_location 
	to be sent. 
	
	The memory_location is the location the AG must dial from. The message 
	returned indicates whether the command was recognised by the AG or not.
	
MESSAGE RETURNED
	HFP_DIAL_MEMORY_CFM

RETURNS
	void
*/
void HfpDialMemoryLocation(HFP *hfp, uint16 length, const uint8 *memory_location)
{
#ifdef HFP_DEBUG_LIB
	if (!hfp)
		HFP_DEBUG(("Null hfp task ptr passed in.\n"));

	if (!length)
		HFP_DEBUG(("Zero length passed in.\n"));

	if (!memory_location)
		HFP_DEBUG(("Null memory location ptr passed in.\n"));
#endif

	/* Send an internal message */
	{
		MAKE_HFP_MESSAGE(HFP_INTERNAL_AT_ATD_MEMORY_REQ);
		message->length = length;
		message->memory = (uint8 *) PanicUnlessMalloc(length);
		memmove(message->memory, memory_location, length);
		MessageSend(&hfp->task, HFP_INTERNAL_AT_ATD_MEMORY_REQ, message);
	}
}
Esempio n. 30
0
/****************************************************************************
NAME
    hfpHandleDisconnectRequest

DESCRIPTION
    We're in the right state and have received a disconnect request, 
    handle it here.

RETURNS
    void
*/
void hfpHandleDisconnectRequest(hfp_link_data* link)
{
    if (link->audio_sink)
    {
        MAKE_HFP_MESSAGE(HFP_INTERNAL_SLC_DISCONNECT_REQ);
        message->link = link;
        /* If we have a SCO/eSCO active need to tear that down first */
        hfpHandleAudioDisconnectReq(link);
        /* Queue up the SLC disconnect message */
        MessageSendConditionally(&theHfp->task, HFP_INTERNAL_SLC_DISCONNECT_REQ, message, (uint16 *) &link->audio_sink);    /*lint !e740 */
    }
    else 
    {
        /* If recovering from link loss or timed out we need to be sure to force disconnect */
        if (link->ag_link_loss_state == hfp_link_loss_recovery || link->ag_link_loss_state == hfp_link_loss_timeout)
        {
            /* Link was recovering from link loss, stop the procedure */
            MessageId message_id = hfpGetLinkTimeoutMessage(link, HFP_RFCOMM_LINK_LOSS_TIMEOUT_LINK_0_IND);
            MessageCancelFirst(&theHfp->task, message_id);
            hfpHandleRfcommLinkLossAbort(link, TRUE);
        }
        /* Either no link loss or we aborted link loss recovery. Now bring down the link. */
        else
        {
            /* Can only get here from searching/outgoing/incoming/connected/complete */
            if(link->ag_slc_state == hfp_slc_searching)
            {
                /* Notify application of connection failure (link will be reset so SDP results ignored) */
                hfpSendSlcConnectCfmToApp(link, NULL, hfp_connect_sdp_fail);
            }
            else
            {
                /* Request the connection lib aborts/disconnects the RFCOMM connection */
                ConnectionRfcommDisconnectRequest(&theHfp->task, hfpGetLinkSink(link));
            }
        }
    }
}