?? voipcall.cpp
字號:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_EVENT, (L"received a RTCSessionReferStatusChangeEvent w/ RTCSRS_DONE"));
KillTimer(&m_TransferDoneTimerId);
return End();
default:
break;
}
return S_OK;
}
/*------------------------------------------------------------------------------
VoIPGroup_t::OnRTCSessionReferredEvent
Handle a notification from the phone canvas object that there is a Refered event
comming with this session
this notification is handled by the receiver in transfer scenario
------------------------------------------------------------------------------*/
HRESULT
VoIPCall_t::OnRTCSessionReferredEvent(
IRTCSessionReferredEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
//validate the input
if (!pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
return DoPhoneVerb(PH_VERB_HOLD);
}
/*------------------------------------------------------------------------------
VoIPCall_t::OnParticipantStateChangeEvent
Updates internal state based on an RTCE_PARTICIPANT_STATE_CHANGE event
------------------------------------------------------------------------------*/
HRESULT
VoIPCall_t::OnRTCParticipantStateChangeEvent(
IRTCParticipantStateChangeEvent* pEvent
)
{
TRACE(ZONE_PHONEAPP_EVENT);
if (! pEvent)
{
ASSERT(FALSE);
return E_POINTER;
}
RTC_PARTICIPANT_STATE ParticipantState = RTCPS_IDLE;
//get the new state from the event
HRESULT hr = pEvent->get_State(&ParticipantState);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not get the participant state from the event! [Hr = 0x%x]", hr));
return hr;
}
switch (ParticipantState)
{
case RTCPS_CONNECTED:
//if this is the first connected event we should record the new connected time
if (!IsValidTime(&m_StartTime))
{
GetLocalTime(&m_StartTime);
}
else
{
hr = S_FALSE;
}
break;
case RTCPS_DISCONNECTED:
UpdateDisconnectReason(pEvent);
LogCallIfNecessary();
break;
default:
hr = S_FALSE;
break;
}
return hr;
}
/*------------------------------------------------------------------------------
VoIPCall_t::StartRingbackTone
Start playing the ringback tone after a small timeout
------------------------------------------------------------------------------*/
void
VoIPCall_t::StartRingbackTone()
{
if (m_StartRingbackTimerId)
{
return;
}
//start a timer for a short while before actually playing the ringback tone -
//we want to prevent unnecessary playback when we get a 180 then a connect/disconnect/update
//and have to stop the ringback.
GetApp()->GetTimers().AddTimer(
sc_RingbackStartTimeout,
this,
&m_StartRingbackTimerId
);
return;
}
/*------------------------------------------------------------------------------
VoIPCall_t::StopRingbackTone
If we are currently playing the ringback tone, stop it!
------------------------------------------------------------------------------*/
void
VoIPCall_t::StopRingbackTone()
{
KillTimer(&m_StartRingbackTimerId);
if (m_PlayingRingbackTone)
{
GetApp()->StopActiveTone();
m_PlayingRingbackTone = false;
}
}
/*------------------------------------------------------------------------------
VoIPCall_t::KillTimer
Terminates a timer (if the timer is still active)
Parameters:
pTimerId : The pointer to a timer identifier
------------------------------------------------------------------------------*/
void
VoIPCall_t::KillTimer(UINT* pTimerId)
{
if (pTimerId == NULL)
{
return;
}
if ((*pTimerId != 0) && (GetApp() != NULL))
{
GetApp()->GetTimers().RemoveTimer(*pTimerId);
*pTimerId = 0;
}
return;
}
/*------------------------------------------------------------------------------
VoIPCall_t::OnTimerExpires
Handles our inactivity timer expiring - indicating it is time to forward
this call
Parameters:
: The identifier of the timer which has expired
------------------------------------------------------------------------------*/
void
VoIPCall_t::OnTimerExpires(
UINT TimerId
)
{
if (TimerId == 0)
{
return;
}
//if the ringback timer expires, we play the ringback tone
if (TimerId == m_StartRingbackTimerId)
{
GetApp()->PlayProgressTone(AudioManager_t::ProgressToneRingback);
m_PlayingRingbackTone = true;
KillTimer(&m_StartRingbackTimerId);
}
else if (TimerId == m_TransferDoneTimerId)
{
KillTimer(&m_TransferDoneTimerId);
End();
}
return;
}
HRESULT
VoIPCall_t::GetURI(BSTR* pURI)
{
if (m_cpRTCParticipant == NULL)
{
return E_FAIL;
}
return m_cpRTCParticipant->get_UserURI(pURI);
}
HRESULT
VoIPCall_t::GetDuration(
SYSTEMTIME* pDuration
)
{
if (pDuration == NULL)
{
return E_INVALIDARG;
}
//initialize the duration structure to 0
memset(pDuration, 0, sizeof(SYSTEMTIME));
if (!IsValidTime(&m_StartTime))
{
//we have not gotten the RTCPS_CONNECTED event yet, return S_FALSE
return S_FALSE;
}
GetLocalTime(&m_EndTime);
ULONGLONG ullStartTime;
ULONGLONG ullEndTime;
HRESULT hr = GetSystemTimeAsULL(&m_StartTime, &ullStartTime);
if (FAILED(hr))
{
return hr;
}
hr = GetSystemTimeAsULL(&m_EndTime, &ullEndTime);
if (FAILED(hr))
{
return hr;
}
return GetULLAsSystemTime(
ullEndTime - ullStartTime,
pDuration
);
}
HRESULT
VoIPCall_t::DoVerbTransfer(
VPARAM Parameter
)
{
if (Parameter == NULL)
{
return E_INVALIDARG;
}
if (m_cpRTCSession == NULL)
{
return E_UNEXPECTED;
}
WCHAR* pTransferToURI = reinterpret_cast<WCHAR*>(Parameter);
ce::auto_bstr TransferToURI = SysAllocString(pTransferToURI);
CComPtr<IRTCSessionCallControl> cpSessionCallControl;
HRESULT hr = m_cpRTCSession->QueryInterface(
IID_IRTCSessionCallControl,
(void **)&cpSessionCallControl
);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to query interface for IRTCSessionCallControl -- error code = 0x%x", hr));
return hr;
}
hr = cpSessionCallControl->Refer(
TransferToURI,
TransferToURI
);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at refering -- error code = 0x%x", hr));
return hr;
}
return hr;
}
HRESULT
VoIPCall_t::SetInfoAboutBeingTransferred(
IRTCSessionReferredEvent* pRTCSessionReferredEvent,
Call_t* pReferringCall
)
{
if ((pRTCSessionReferredEvent == NULL) || (pReferringCall == NULL))
{
return E_INVALIDARG;
}
if (IsBeingTransferred())
{
return E_FAIL;
}
m_cpRTCSessionReferredEvent = pRTCSessionReferredEvent;
m_cpReferringCall = pReferringCall;
return S_OK;
}
HRESULT
VoIPCall_t::StateChangeWhileBeingTransferred(
RTC_SESSION_STATE NewSessionState
)
{
HRESULT hr = S_OK;
switch(NewSessionState)
{
case RTCSS_CONNECTED:
//transfer: receiver notifies the initiator that refer is successful
hr = m_cpRTCSessionReferredEvent->SetReferredSessionState(RTCSS_CONNECTED);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at setting referred session state -- error code = 0x%x", hr));
return hr;
}
ClearInfoAboutBeingTransferred();
return S_OK;
case RTCSS_DISCONNECTED:
//if this is still being transferred
//transfer: receiver notifies the refer-er that refer is failed, maybe caused by the target rejects the callneeds to check if the current session is still being transferred
hr = m_cpRTCSessionReferredEvent->SetReferredSessionState(RTCSS_DISCONNECTED);
if (FAILED(hr))
{
//even if it fails, still keep going
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at setting referred session state -- error code = 0x%x", hr));
}
//unhold the session with refer-er
hr = m_cpReferringCall->DoPhoneVerb(PH_VERB_UNHOLD);
if (FAILED(hr))
{
//even if it fails, still keep going
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at unholding session -- error code = 0x%x", hr));
}
ClearInfoAboutBeingTransferred();
return hr;
default:
break;
}
return hr;
}
void
VoIPCall_t::UpdateNewLoggedCall(
VoIPCallType CallType
)
{
HRESULT hr;
switch (CallType)
{
case e_vctIncoming:
hr = PHSetValue(phsIncomingCalls, 1);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at writting new incoming call count to regsitry, hr = 0x%x", hr));
}
break;
case e_vctOutgoing:
hr = PHSetValue(phsOutgoingCalls, 1);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at writting new outgoing call count to regsitry, hr = 0x%x", hr));
}
break;
case e_vctMissed:
hr = PHSetValue(phsMissedCalls, 1);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at writting new missed call count to regsitry, hr = 0x%x", hr));
}
break;
default:
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Invalid call type specified."));
}
return;
}
/*------------------------------------------------------------------------------
VoIPCall_t::LogCall
Log call to database
------------------------------------------------------------------------------*/
void
VoIPCall_t::LogCallIfNecessary(
void
)
{
if (m_IsLogged)
{
//return if the call is already been logged
return;
}
GetLocalTime(&m_EndTime);
if (!IsValidTime(&m_StartTime))
{
//if we don't have valid start time, it means we either rejected the call or the call was missed
//we should set the start time as the same as end time for both cases
memcpy(&m_StartTime, &m_EndTime, sizeof(SYSTEMTIME));
}
if (m_CouldBeMissed && m_CallType == e_vctIncoming)
{
m_CallType = e_vctMissed;
}
GetApp()->GetDatabase().AddToCallLog(
GetDisplayNumber(),
GetDisplayName(),
m_bstrName,
m_CallType,
m_StartTime,
m_EndTime
);
UpdateNewLoggedCall(m_CallType);
//set the flag to indicate the call is already logged
m_IsLogged = true;
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -