📄 voipapp.cpp
字号:
disable the IP calling, if there is on going voip call, wait till them end
Returns (HRESULT): S_FALSE if the object is not yet initialized
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::DisableCalling()
{
if (m_cpRTCClient == NULL)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Not an initialized object - aborting uninitialization"));
return S_FALSE;
}
return Shutdown();
}
/*------------------------------------------------------------------------------
VoIPApp_t::UnregisterCallbackInterface
Unregister our event sink from RTC's event connection point
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::UnregisterCallbackInterface()
{
if (m_cpConnectionPt == NULL)
{
return E_FAIL;
}
HRESULT hr = m_cpConnectionPt->Unadvise(m_ConnectionPtCookie);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to unadvise (unbind) from the connection point! error code - 0x%x", hr));
return hr;
}
//release our internal members
m_cpConnectionPt = NULL;
m_ConnectionPtCookie = 0;
return S_OK;
}
/*------------------------------------------------------------------------------
VoIPApp_t::Event
Event Sink for the RTC Client
Parameters:
RTCEvent: event type of the fired event
piEvent: pointer to use for QI representing the type of event
Returns (HRESULT): indicating whether handling the event succeeded or failed
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::Event(
RTC_EVENT RTCEvent,
IDispatch* pDispatch
)
{
TRACE(ZONE_PHONEAPP_EVENT);
if (! pDispatch)
{
ASSERT(FALSE);
return E_POINTER;
}
HRESULT hr = E_NOTIMPL;
//dispatch the event to the proper Handler (see DispatchEvent fn)
switch (RTCEvent)
{
case RTCE_CLIENT:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_CLIENT"));
DispatchEvent(IRTCClientEvent, OnRTCClientEvent);
break;
case RTCE_SESSION_STATE_CHANGE:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SESSION_STATE_CHANGE"));
DispatchEvent(IRTCSessionStateChangeEvent, OnSessionStateChangeEvent);
break;
case RTCE_PARTICIPANT_STATE_CHANGE:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_PARTICIPANT_STATE_CHANGE"));
DispatchEvent(IRTCParticipantStateChangeEvent, OnParticipantStateChangeEvent);
break;
case RTCE_REGISTRATION_STATE_CHANGE:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_REGISTRATION_STATE_CHANGE"));
DispatchEvent(IRTCRegistrationStateChangeEvent, OnRegistrationStateChangeEvent);
break;
case RTCE_SESSION_REFER_STATUS:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SESSION_REFER_STATUS"));
DispatchEvent(IRTCSessionReferStatusEvent, OnSessionReferStatusChangeEvent);
break;
case RTCE_SESSION_REFERRED:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SESSION_REFERRED"));
DispatchEvent(IRTCSessionReferredEvent, OnSessionReferredEvent);
break;
case RTCE_SUBSCRIPTION_STATE_CHANGE_EVENT:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SUBSCRIPTION_STATE_CHANGE_EVENT"));
DispatchEvent(IRTCSubscriptionStateChangeEvent, OnSubscriptionStateChangeEvent);
break;
case RTCE_SUBSCRIPTION_NOTIFY_EVENT:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received an event of type RTCE_SUBSCRIPTION_NOTIFY_EVENT"));
DispatchEvent(IRTCSubscriptionNotificationEvent, OnSubscriptionNotificationEvent);
break;
default:
hr = E_NOTIMPL;
break;
}
UpdatePhoneAppStatus();
return hr;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnRTCClientEvent
Handles an IRTCClientEvent type event - we only care about the async shutdown event
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnRTCClientEvent(
IRTCClientEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
if (! pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
//determine the type of the event
RTC_CLIENT_EVENT_TYPE EventType = RTCCET_DEVICE_CHANGE;
HRESULT hr = pEvent->get_EventType(&EventType);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get the event type from the client event - error code - 0x%x", hr));
return hr;
}
if (EventType != RTCCET_ASYNC_CLEANUP_DONE)
{
return S_FALSE;
}
//post the shutdown event
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received the RTC Async shutdown event - killing message pump by posting a quit msg"));
PostMessage(m_NotificationWindow, WM_RTC_SHUTDOWN_COMPLETE, 0, 0);
return S_OK;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnSessionStateChangeEvent
Handles a session state change event from the RTC event sink
- notifies the phone app of changes
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnSessionStateChangeEvent(
IRTCSessionStateChangeEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
//validate input
if (! pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
CComPtr<IRTCSession> cpSession;
//Get the session object from the event
HRESULT hr = pEvent->get_Session(&cpSession);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC session from the event - error code = 0x%x", hr));
return hr;
}
RTC_SESSION_STATE NewSessionState = RTCSS_IDLE;
//pre-fetch the new state of the session
hr = cpSession->get_State(&NewSessionState);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to get the new session state from the session - error code = 0x%x", hr));
return hr;
}
CComPtr<Call_t> cpAffectedCall;
//find the call who owns this session
FindCallBySession(cpSession, &cpAffectedCall);
if (cpAffectedCall == NULL)
{
//if we aren't currently tracking this call, and this call is not newly incoming
//then this is some rogue call we don't care about - simply ignore it
if (NewSessionState != RTCSS_INCOMING)
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Received a session state change event about a call we don't know - aborting..."));
return E_UNEXPECTED;
}
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received a new IncomingCall event"));
}
else
{
//otherwise, let the call know there was a change in its session state
cpAffectedCall->OnRTCSessionStateChangeEvent(pEvent);
}
switch (NewSessionState)
{
case RTCSS_INCOMING:
if (PHGetSetting(phsCallForwarding))
{
if (Settings_t::s_ForwardingNumber && Settings_t::s_ForwardingNumber[0])
{
//there is valid forwaring number, start forwarding
SaveCallForwardedInfoInRegistry(cpSession);
//we don't log the call as missed call here, just forward directly
return ForwardSession(cpSession);
}
else
{
//auto-forwarding number is not valid, might due to something bad happens to registry
//we need to reset the flag to 'not forwarding' to notify user
PHSetValue(phsCallForwarding, 0);
}
}
hr = CreateIncomingCall(cpSession, &cpAffectedCall);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at creating a new group for incoming call, hr = 0x%x", hr));
return hr;
}
if (ShouldRejectIncomingCall(cpAffectedCall))
{
cpAffectedCall->MarkAsRejected();
return cpSession->Terminate(RTCTR_DND);
}
break;
case RTCSS_DISCONNECTED:
bool PlayingTone;
PlayProgressToneForDisconnectedCall(
cpAffectedCall,
&PlayingTone
);
//now remove the call from our list
m_CallList.remove(cpAffectedCall);
//remove the reference we added when we put the group in our list
static_cast<Call_t*>(cpAffectedCall)->Release();
if (!AreThereAnyCurrentCalls())
{
if (IsMuted(m_cpRTCClient))
{
m_cpRTCClient->put_AudioMuted(
RTCAD_MICROPHONE,
VARIANT_FALSE
);
}
if (m_AudioMode == e_vamSpeakerPhone &&
!PlayingTone &&
m_UIManager.IsEmpty())
{
//simulate a speaker toggle
OnHookModeChange(HotKeys_t::vkSpeaker, FALSE);
}
}
if (cpAffectedCall == m_cpActiveVoicemailCall)
{
m_cpActiveVoicemailCall = NULL;
}
break;
default:
break;
}
return m_UIManager.OnCallEvent(cpAffectedCall);
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnParticipantStateChangeEvent
Handles a participant state change event from the RTC event sink
- notifies group of changes to its participants
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnParticipantStateChangeEvent(
IRTCParticipantStateChangeEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
//validate input
if (! pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
CComPtr<IRTCSession> cpSession;
CComPtr<IRTCParticipant> cpParticipant;
//Get the participant object from the event
HRESULT hr = pEvent->get_Participant(&cpParticipant);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC participant from the event - error code = 0x%x", hr));
return hr;
}
//then get the session from the participant
hr = cpParticipant->get_Session(&cpSession);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC session from the participant - error code = 0x%x", hr));
return hr;
}
//find our group by the session and notify it of the change
CComPtr<Call_t> cpAffectedCall;
FindCallBySession(cpSession, &cpAffectedCall);
///: For now, we don't do anything on a participant state change event, other than notify the group.
///: However, this will probably change after we implement multiparty calling...
if ( cpAffectedCall != NULL )
{
cpAffectedCall->OnRTCParticipantStateChangeEvent(pEvent);
}
return S_OK;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnRegistrationStateChangeEvent
Handles a RegistrationStateChange event indicating a SIP REGISTER request
is being handled by the remote proxy
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnRegistrationStateChangeEvent(
IRTCRegistrationStateChangeEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
//validate input
if (! pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
return m_ProxyServices.OnRegistrationStateChangeEvent(pEvent);
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnSessionReferStatusChangeEvent
Handles a session refer status change event from the RTC event sink
- notifies the phone app of changes
This notification is handled by the initiator in transfer scenario
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnSessionReferStatusChangeEvent(
IRTCSessionReferStatusEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
//validate input
if (! pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
CComPtr<IRTCSession2> cpSession;
//Get the session object from the event
HRESULT hr = pEvent->get_Session(&cpSession);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure getting the RTC session from the event - error code = 0x%x", hr));
return hr;
}
CComPtr<Call_t> cpAffectedCall;
//find the group who owns this session
FindCallBySession(cpSession, &cpAffectedCall);
if ( cpAffectedCall == NULL )
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"Received a new RTC_SESSION_REFER_STATUS event w/o associating a call"));
return E_UNEXPECTED;
}
//otherwise, let the group know there was a change in its session state
hr = cpAffectedCall->OnRTCSessionReferStatusChangeEvent(pEvent);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at handling the Refer status change event, hr = 0x%x", hr));
}
//this event should not trigger the UI update
return hr;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnSessionReferredEvent
Handles a session referred event from the RTC event sink
- notifies the phone app of changes
This notification is h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -