📄 headset_hfp_handler.c
字号:
/* However, we have come across phones that send this before a callind [1]
on accepting a call - -interop issue*/
if ( stateManagerIsHfpConnected() )
{
stateManagerEnterHfpConnectedState ( pApp ) ;
}
break;
case (hfp_incoming_call_setup): /*!< HFP device currently ringing.*/
stateManagerEnterIncomingCallEstablishState ( pApp ) ;
break;
case (hfp_outgoing_call_setup): /*!< Call currently being dialed.*/
case (hfp_outgoing_call_alerting_setup):/*!< Remote end currently ringing.*/
stateManagerEnterOutgoingCallEstablishState ( pApp ) ;
break;
default:
break;
}
}
/*****************************************************************************/
void hfpHandlerRingInd ( hsTaskData *pApp )
{
/* Disconnect A2DP audio if it is streaming from a standalone A2DP source */
if (!IsA2dpSourceAnAg(pApp))
streamControlCeaseA2dpStreaming(pApp, TRUE);
if ( ! pApp->InBandRingEnabled )
{
HFP_DEBUG(("HFP_DEBUG: OutBandRing\n")) ;
/* Play ring tone from configuration */
TonesPlayTone ( pApp , pApp->RingTone , FALSE);
}
}
/*****************************************************************************/
void hfpHandlerVoiceRecognitionInd( hsTaskData *pApp, const HFP_VOICE_RECOGNITION_IND_T *ind )
{
/* Update the local flag */
pApp->voice_recognition_enabled = ind->enable;
/* If voice dial has been deactivated then try a restart A2DP if no SCO active */
if (!pApp->voice_recognition_enabled && !pApp->sco_sink)
streamControlResumeA2dpStreaming(pApp, 0);
}
/*****************************************************************************/
void hfpHandlerVoiceRecognitionCfm( hsTaskData *pApp, const HFP_VOICE_RECOGNITION_ENABLE_CFM_T *cfm )
{
if (cfm->status)
{
/* Voice recognition cmd not accepted - toggle state */
pApp->voice_recognition_enabled ^= 1 ;
/* Resume A2DP streaming. Needs extra delay because of the Nokia 8800 phone which says
voice dial has failed then carries on with it. The media player breaks if
the headset sends an AVDTP_START too early.
*/
streamControlResumeA2dpStreaming(pApp, 1000);
MessageSend ( &pApp->task , EventError , 0 );
}
}
/*****************************************************************************/
void hfpHandlerLastNoRedialCfm( hsTaskData *pApp, const HFP_LAST_NUMBER_REDIAL_CFM_T *cfm )
{
if (cfm->status)
{
MessageSend ( &pApp->task , EventError , 0 );
}
}
/*****************************************************************************/
void hfpHandlerEncryptionChangeInd( hsTaskData *pApp, const HFP_ENCRYPTION_CHANGE_IND_T *ind )
{
}
/*****************************************************************************/
void hfpHandlerSpeakerVolumeInd( hsTaskData *pApp, const HFP_SPEAKER_VOLUME_IND_T *ind )
{
HFP_DEBUG(("HFP: hfpHandlerSpeakerVolumeInd [%d]\n", ind->volume_gain)) ;
pApp->audioData.gHfpVolumeLevel = ind->volume_gain;
if (stateManagerIsA2dpStreaming())
return;
VolumeSetHeadsetVolume(pApp, pApp->audioData.gHfpVolumeLevel, FALSE, FALSE);
}
/*****************************************************************************/
void hfpHandlerAudioConnectInd( hsTaskData *pApp, const HFP_AUDIO_CONNECT_IND_T *ind )
{
HFP *active_hfp = 0;
/* Accept audio if its for a task we own */
if ((ind->hfp == pApp->hfp) || (ind->hfp == pApp->hsp))
active_hfp = ind->hfp;
if (active_hfp)
{
/* Accept the audio connection */
if (pApp->profile_connected == hfp_headset_profile)
HfpAudioConnectResponse(active_hfp, 1, (sync_all_sco), 0, ind->bd_addr);
else
HfpAudioConnectResponse(active_hfp, 1, sync_all_pkt_types, 0, ind->bd_addr);
}
else
{
HfpAudioConnectResponse(active_hfp, 0, sync_hv1, 0, ind->bd_addr);
}
}
/*****************************************************************************/
void hfpHandlerAudioConnectCfm( hsTaskData *pApp, const HFP_AUDIO_CONNECT_CFM_T *cfm )
{
if ( cfm->status == hfp_success)
{
pApp->sco_sink = cfm->audio_sink;
audioConnectSco ( pApp ) ;
/* 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 ( &pApp->task , EventSCOLinkOpen , 0 ) ;
/* If this is a headset instance, enter the active call state */
if (pApp->profile_connected == hfp_headset_profile)
{
stateManagerEnterActiveCallState (pApp) ;
}
}
}
/*****************************************************************************/
void hfpHandlerAudioDisconnectInd( hsTaskData *pApp, const HFP_AUDIO_DISCONNECT_IND_T *ind )
{
pApp->sco_sink = 0;
AudioDisconnect() ;
/* Turn the audio amp off after a delay */
AmpOffLater(pApp);
pApp->dsp_process = dsp_process_none;
/* Try to resume A2DP streaming if not outgoing or incoming call */
if ((stateManagerGetHfpState() != headsetIncomingCallEstablish) && (stateManagerGetHfpState() != headsetOutgoingCallEstablish))
{
if ((stateManagerGetHfpState() == headsetActiveCall) && IsA2dpSourceAnAg(pApp))
{
/* Do nothing with A2DP_AG as the music can't start while call active */
}
else
{
streamControlResumeA2dpStreaming(pApp, 0);
}
}
MessageSend ( &pApp->task , EventSCOLinkClose , 0 ) ;
/* Set the mic bias */
LEDManagerSetMicBias ( pApp , FALSE ) ;
/* If this is a headset instance, end the call */
if ( pApp->profile_connected == hfp_headset_profile )
{
if(stateManagerIsHfpConnected())
{
stateManagerEnterHfpConnectedState ( pApp ) ;
}
}
/* If we are muted - then un mute at disconnection */
if (pApp->audioData.gMuted )
{
MessageSend(&pApp->task , EventMuteOff , 0) ;
}
}
/****************************************************************************
NAME
audioConnectSco
DESCRIPTION
This function connects the synchronous connection to the CVC EC/NR Algorithm running
in the Kalimba DSP.
*/
static bool audioConnectSco ( hsTaskData *pApp )
{
bool lResult = FALSE ;
/* The mode to connect - connected as default */
AUDIO_MODE_T lMode = AUDIO_MODE_CONNECTED ;
/* Disconnect A2DP audio if it was active */
streamControlCeaseA2dpStreaming(pApp, TRUE);
/* Turn the audio amp on */
AmpOn(pApp);
/* Mute control */
if (pApp->audioData.gMuted )
{
lMode = AUDIO_MODE_MUTE_MIC ;
}
if (!pApp->cvcEnabled)
{
HFP_DEBUG(("HFP: Route SCO mode=%d mic_mute=%d volindex=%d volgain=%d\n",lMode,pApp->audioData.gMuted,pApp->audioData.gHfpVolumeLevel,VolumeRetrieveGain(pApp->audioData.gHfpVolumeLevel, FALSE)));
lResult = AudioConnect( (TaskData *)&csr_no_dsp_plugin ,
pApp->sco_sink ,
pApp->theCodecTask,
VolumeRetrieveGain(pApp->audioData.gHfpVolumeLevel, FALSE) ,
0 ,
TRUE ,
lMode ,
0 );
}
else
{
/* Don't enable speaker sidetone unless active call. */
if(stateManagerGetHfpState() != headsetActiveCall)
{
lMode = AUDIO_MODE_MUTE_SPEAKER ;
}
HFP_DEBUG(("HFP: Route SCO mode=%d mic_mute=%d volindex=%d volgain=%d\n",lMode,pApp->audioData.gMuted,pApp->audioData.gHfpVolumeLevel,VolumeRetrieveGain(pApp->audioData.gHfpVolumeLevel, FALSE)));
lResult = AudioConnect( (TaskData *)&csr_cvc_plugin ,
pApp->sco_sink ,
pApp->theCodecTask,
VolumeRetrieveGain(pApp->audioData.gHfpVolumeLevel, FALSE) ,
0,
TRUE ,
lMode ,
0 );
}
pApp->dsp_process = dsp_process_sco;
/* Set the mic bias */
LEDManagerSetMicBias ( pApp , TRUE ) ;
return (lResult=TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -