/**************************************************************************** NAME sinkHangUpCall DESCRIPTION Hang up the call from the device. RETURNS void */ void sinkHangUpCall( void ) { /* Determine which is the current active call */ hfp_link_priority priority = hfp_invalid_link; hfp_call_state call_state; /* Get profile if AG with audio, also ensure AG is actually in a call, otherwise try other methods */ if((theSink.routed_audio)&&(HfpLinkGetCallState(HfpLinkPriorityFromAudioSink(theSink.routed_audio), &call_state)&& (call_state))) priority = HfpLinkPriorityFromAudioSink(theSink.routed_audio); /* No audio so use AG state */ if(!priority) priority = HfpLinkPriorityFromCallState(hfp_call_state_active); /* No active call, check for an outgoing call to terminate */ if(!priority) priority = HfpLinkPriorityFromCallState(hfp_call_state_outgoing); /* No active/outgoing calls, check for TWC state */ if(!priority) priority = HfpLinkPriorityWithActiveCall(FALSE); /* no active calls but still a held call on the phone */ if(!priority) priority = HfpLinkPriorityFromCallState(hfp_call_state_held_remaining); /* If match found */ if(priority && HfpLinkGetCallState(priority, &call_state)) { switch(call_state) { case hfp_call_state_twc_incoming: case hfp_call_state_twc_outgoing: case hfp_call_state_held_active: case hfp_call_state_multiparty: CM_DEBUG(("CM: HangUp TWC active Call on AG%x\n",priority)) ; HfpCallHoldActionRequest(priority, hfp_chld_release_active_accept_other, 0); break; case hfp_call_state_held_remaining: CM_DEBUG(("CM: HangUp TWC held Call on AG%x\n",priority)) ; HfpCallHoldActionRequest(priority, hfp_chld_release_held_reject_waiting, 0); break; default: /* Terminate call using AT+CHUP */ CM_DEBUG(("CM: HangUp Call on AG%x\n",priority)) ; HfpCallTerminateRequest(priority); break; } } }
/**************************************************************************** NAME audioGetLinkPriority DESCRIPTION Common method of getting the link we want to manipulate audio settings on RETURNS */ hfp_link_priority audioGetLinkPriority ( bool audio ) { hfp_link_priority priority; /* See if we can get a link from the device audio sink... */ priority = HfpLinkPriorityFromAudioSink(theSink.routed_audio); /* If that fails see if we have an active call... */ if(!priority) priority = HfpLinkPriorityWithActiveCall(audio); /* If we got something return it, otherwise return primary link */ return (priority ? priority : hfp_primary_link); }
/**************************************************************************** NAME audioHandleSyncDisconnectInd DESCRIPTION Handle HFP_AUDIO_DISCONNECT_IND. This indicates that an incoming sychronous connection has been disconnected RETURNS */ void audioHandleSyncDisconnectInd ( const HFP_AUDIO_DISCONNECT_IND_T * pInd ) { Sink sink; /* Get the priority of the other link */ hfp_link_priority other = (pInd->priority == hfp_primary_link) ? hfp_secondary_link : hfp_primary_link; AUD_DEBUG(("AUD: Synchronous Disconnect Ind [%x]:\n",pInd->priority)) ; /* ensure disconnection was succesfull */ if(pInd->status == hfp_audio_disconnect_success) { MessageSend ( &theSink.task , EventSCOLinkClose , 0 ) ; /* update sco priority */ setScoPriorityFromHfpPriority(pInd->priority, sco_none); /* SCO has been disconnected, check for the prescence of another sco in hold state, this occurs when the AG has performed an audio transfer, promote the held call to active */ if(getScoPriorityFromHfpPriority(other) == sco_held_call) setScoPriorityFromHfpPriority(other, sco_active_call); AUD_DEBUG(("AUD: Synchronous Disconnect Ind [%x]: sco_pri = %d\n",pInd->priority, HfpLinkPriorityFromAudioSink(theSink.routed_audio) )) ; /* deroute the audio */ audioHandleRouting(audio_source_none); /*change the active call state if necessary*/ if ((stateManagerGetState() == deviceActiveCallSCO)) stateManagerEnterActiveCallState(); /* Send our link policy settings for normal role now SCO is dropped */ if(HfpLinkGetSlcSink(pInd->priority, &sink)) linkPolicyUseHfpSettings(pInd->priority, sink); } }