Exemplo n.º 1
0
/****************************************************************************
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);
    }
    
}
void hfpHandlerCallInd ( const HFP_CALL_IND_T * pInd ) 
{
    switch (pInd->call)
    {
    case 0:
		if ( stateManagerGetHfpState() == headsetActiveCall )
        {		
			if (theHeadset.SecondIncomingCall)
			{
				theHeadset.SecondIncomingCall = FALSE;
				stateManagerEnterIncomingCallEstablishState() ;
			}
			else
			{
            	stateManagerEnterHfpConnectedState() ;
			}
        }    
      	break;

    case 1:
        stateManagerEnterActiveCallState() ;  
        break;

    default:
        break;
    }
}
void hfpHandlerAudioConnectCfm( const HFP_AUDIO_CONNECT_CFM_T *cfm )
{
    if ( cfm->status == hfp_success)
    {
	    AUDIO_SINK_T sink_type;
		
		if (theHeadset.hfp_hsp == NULL)
		{
			/* The audio has obviously been established before being notified of SLC.
			   Update the HFP pointer accordingly. */
			if (cfm->hfp == theHeadset.hfp)
    		{
        		theHeadset.profile_connected = hfp_handsfree_profile;
				theHeadset.hfp_hsp = theHeadset.hfp;
    		}
    		else if (cfm->hfp == theHeadset.hsp)
    		{
        		theHeadset.profile_connected = hfp_headset_profile;
				theHeadset.hfp_hsp = theHeadset.hsp;
    		}    
		}
		
		/* Stop any audio transfer requests */
		MessageCancelAll(&theHeadset.task, APP_CHECK_FOR_AUDIO_TRANSFER);
	    
        switch (cfm->link_type)
        {
			case sync_link_unknown:  /* Assume SCO if we don't know */
			case sync_link_sco:
				sink_type = AUDIO_SINK_SCO;
				break;
			case sync_link_esco:
				sink_type = AUDIO_SINK_ESCO;
				break;
			default:
				sink_type = AUDIO_SINK_INVALID;
				break;
        }
		
        audioConnectSco(sink_type, cfm->tx_bandwidth) ;
        
       /* Send an event to indicate that a SCO has been opened. This indicates
          that an audio connection has been successfully created to the AG. */
    	MessageSend ( &theHeadset.task , EventSCOLinkOpen , 0 ) ;
    
	    /* If this is a headset instance, enter the active call state */
        if (theHeadset.profile_connected == hfp_headset_profile)
        {
            stateManagerEnterActiveCallState() ;
        }			
		
		/* Update Link Policy as SCO has connected. */
		linkPolicySCOconnect();
    }
}
/****************************************************************************
NAME    
    hfpHandlerReleaseActiveAcceptOtherCallCfm

DESCRIPTION
    Handles HFP_RELEASE_ACTIVE_ACCEPT_OTHER_CALL_CFM_T message from HFP library

*/
void hfpHandlerReleaseActiveAcceptOtherCallCfm ( const HFP_RELEASE_ACTIVE_ACCEPT_OTHER_CALL_CFM_T *cfm )
{
    /* if successful we're just in a normal active call now */
    if (cfm->status == hfp_success)
    {
        stateManagerEnterActiveCallState();
    }
    else
    {
        HFP_DEBUG(("HFP: Failure to ReleaseActiveAcceptOther - status[%d]\n", cfm->status));
    }
}
/****************************************************************************
NAME    
    hfpHandlerReleaseHeldRejectWaitingCallCfm

DESCRIPTION
    Handles HFP_RELEASE_HELD_REJECT_WAITING_CALL_CFM_T message from HFP library

*/
void hfpHandlerReleaseHeldRejectWaitingCallCfm ( const HFP_RELEASE_HELD_REJECT_WAITING_CALL_CFM_T *cfm )
{
    /* if successful we're just in a normal active call now */
    if (cfm->status == hfp_success)
    {
        stateManagerEnterActiveCallState();
    }
    else
    {
        HFP_DEBUG(("HFP: Failure to ReleaseHeldRejectWaiting - status[%d]\n", cfm->status));
    }
}
Exemplo n.º 6
0
/****************************************************************************
NAME    
    audioHandleSyncConnectCfm
    
DESCRIPTION
    Handle HFP_AUDIO_CONNECT_CFM.  This indicates that an incoming sychronous 
    connection has been established

RETURNS
    
*/
void audioHandleSyncConnectCfm ( const HFP_AUDIO_CONNECT_CFM_T * pCfm )
{       
    uint8 index = PROFILE_INDEX(pCfm->priority);
    hfp_call_state CallState;
    
    /* Get the priority of the other link */
    hfp_link_priority other = (pCfm->priority == hfp_primary_link) ? hfp_secondary_link : hfp_primary_link;
    
    
    AUD_DEBUG(("Synchronous Connect Cfm from [%x]:\n", (uint16)pCfm->priority)) ;
 
    /* if successful */
    if ( pCfm->status == hfp_success)
    {      
        Sink sink;
        
        /* obtain sink for this audio connection */
        if(HfpLinkGetSlcSink(pCfm->priority, &sink))
        {
            /* Send our link policy settings for active SCO role */
            linkPolicyUseHfpSettings(pCfm->priority, sink);
        }

        /* store in individual hfp struct as it may be necessary to disconnect and reconnect
           audio on a per hfp basis for multipoint multiparty calling */
        theSink.profile_data[index].audio.tx_bandwidth= pCfm->tx_bandwidth;
        theSink.profile_data[index].audio.link_type= pCfm->link_type;           
        theSink.profile_data[index].audio.codec_selected = pCfm->codec;           
                
        /* Send an event to indicate that a SCO has been opened */           
        /* this indicates that an audio connection has been successfully created to the AG*/
        MessageSend ( &theSink.task , EventSCOLinkOpen , 0 ) ;

        /* update the audio priority state 
           is this sco a streaming audio sco?, check call state for this ag */
        if(HfpLinkGetCallState(pCfm->priority, &CallState))
        {          
            /* determine sco priority based on call status */
            switch(CallState)
            {
                /* no call so this is a steaming audio connection */
                case hfp_call_state_idle:
                    setScoPriorityFromHfpPriority(pCfm->priority, sco_streaming_audio);
                break;
                
                /* incoming call so this is an inband ring sco */
                case hfp_call_state_incoming:
                case hfp_call_state_incoming_held:
                case hfp_call_state_twc_incoming:
                    setScoPriorityFromHfpPriority(pCfm->priority, sco_inband_ring);                    
                break;
   
                /* active call states so this sco has highest priority */
                case hfp_call_state_active:
                case hfp_call_state_twc_outgoing:
                    /* this audio connection may have been the result of the an audio transfer
                       from the AG and there is already an active call on the other AG, check for this
                       and make this new audio connection held leaving the other routed audio connection 
                       intact */
                    if(getScoPriorityFromHfpPriority(other)==sco_active_call)                    
                        setScoPriorityFromHfpPriority(pCfm->priority, sco_held_call);                    
                    else
                        setScoPriorityFromHfpPriority(pCfm->priority, sco_active_call);                    
                break;
                
                /* an outgoing call sco has highest priority, if there is a call on other AG
                   it needs to be put on hold whilst this outgoing call is made */
                case hfp_call_state_outgoing:
                    /* does other AG have active call on it?, if so hold the audio */
                    if(getScoPriorityFromHfpPriority(other)==sco_active_call)
                        setScoPriorityFromHfpPriority(other, sco_held_call);
                    /* make the outgoing call audio the one that gets routed */
                    setScoPriorityFromHfpPriority(pCfm->priority, sco_active_call);
                break;

                /* this call is held so the sco is put to on hold priority which is lower than
                   active call but higher than streaming */
                case hfp_call_state_held_active:
                case hfp_call_state_held_remaining:
                    if(theSink.routed_audio)                    
                        setScoPriorityFromHfpPriority(pCfm->priority, sco_held_call);                    
                break;
   
                /* non covered states treat as highest priority sco connection */
                default:
                    setScoPriorityFromHfpPriority(pCfm->priority, sco_active_call);                    
                break;
            }
        }
        
        /* route the appropriate audio connection */
        audioHandleRouting(audio_source_none);

        /*change the active call state if necessary*/
        if ((stateManagerGetState() == deviceActiveCallNoSCO) )
        {
            stateManagerEnterActiveCallState();
        }
                       
#ifdef DEBUG_AUDIO
        switch (pCfm->link_type)
        {
            case (sync_link_unknown):
                AUD_DEBUG(("AUD: Link = ?\n")) ;
            break ;
            case (sync_link_sco) :
                AUD_DEBUG(("AUD: Link = SCO\n")) ;
            break;
            case sync_link_esco:
                AUD_DEBUG(("AUD: Link = eSCO\n")) ;
            break ;    
        }
#endif        

    }
    else
    {
        AUD_DEBUG(("Synchronous Connect Cfm: FAILED\n")) ;       
    }
    AUD_DEBUG(("AUD : Sco->\n")) ;
}