📄 session.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*************************************************************************
Disclaimer:
This code and information is provided "as is" without warranty of
any kind, either expressed or implied, including but not limited to
the implied warranties of merchantability and/or fitness for a
particular purpose.
Module Name:
Session.cpp
Abstract:
CSession is a wrapper for IRTCSession that internalizes much of the
error handling and session information.
Notes:
**************************************************************************/
#include <windows.h>
#include "Session.h"
#include "RTCInternal.h"
#include "rtcs.h"
/*************************************************************************************************
Constructors: Default and by value
*************************************************************************************************/
CSession::CSession(
SWCB_FN_PTR fnSWCB
): m_fnSWCB( fnSWCB )
{
m_Init();
}
CSession::CSession(
IRTCSession* pSess,
SWCB_FN_PTR fnSWCB
): m_fnSWCB( fnSWCB )
{
m_Init();
ASSERT(pSess);
m_pSess = pSess;
m_Valid = (pSess != NULL);
}
CSession::CSession(
IN IRTCSession* pSess,
IN RTC_SESSION_TYPE enRST,
IN RTC_SESSION_STATE enRSS,
IN SWCB_FN_PTR fnSWCB
): m_fnSWCB( fnSWCB )
{
m_Init();
ASSERT(pSess);
m_pSess = pSess;
pSess->AddRef();
m_enRST = enRST;
m_enRSS = enRSS;
m_Valid = (pSess != NULL);
}
/*************************************************************************************************
m_Init()
Initialize all values to defaults. Since the RTC enumerations do not have INVALID types,
simply use what we'd expect: RTCST_PC_TO_PC, RTCSS_IDLE, etc.
*************************************************************************************************/
VOID CSession::m_Init()
{
m_Valid = FALSE;
m_pSess = NULL;
m_bstrRemoteURI = NULL;
m_enRST = RTCST_PC_TO_PC; // default
m_enRSS = RTCSS_IDLE; // not doing anything
m_pProfile = NULL;
m_lSessionFlags = NULL; // use FORCE_ PROFILE and FAIL_ON_REDIRECT
m_bstrLocalPhoneURI = NULL; // set to local phone number for p2p calls
m_sPartInfo.Init();
}
CSession::~CSession()
{
Clear();
}
/*************************************************************************************************
Accessor Functions:
*************************************************************************************************/
inline
IRTCSession*
CSession::get_Session()
{
return m_pSess;
}
inline
VOID
CSession::put_Session(
IN IRTCSession *pSess
)
{
pSess->AddRef();
m_pSess = pSess;
}
SWCB_FN_PTR
CSession::get_SWCBfn()
{
return m_fnSWCB;
}
VOID
CSession::put_SWCBfn( FARPROC fnSWCB)
{
m_fnSWCB = (SWCB_FN_PTR) fnSWCB;
}
RTC_SESSION_STATE
CSession::get_SessionState()
{
return m_enRSS;
}
VOID
CSession::put_SessionState(
IN RTC_SESSION_STATE enRSS
)
{
m_enRSS = enRSS;
}
RTC_SESSION_TYPE
CSession::get_SessionType()
{
return m_enRST;
}
VOID
CSession::put_SessionType(
IN RTC_SESSION_TYPE enRST
)
{
m_enRST = enRST;
}
/************************************************************************************************
put_LocalPhoneURI()
Copy the local phone URI to this session, only if non-null and only allocate space
if bRealloc == TRUE (set to default)
*************************************************************************************************/
BOOL
CSession::put_LocalPhoneURI(
IN BSTR bstrLocalPhoneURI,
BOOL bRealloc
)
{
if (!bstrLocalPhoneURI)
return TRUE;
if (bRealloc) {
return NewStrCopy( bstrLocalPhoneURI, m_bstrLocalPhoneURI );
} else {
m_bstrLocalPhoneURI = bstrLocalPhoneURI;
}
return TRUE;
}
/************************************************************************************************
get_ParticipantName()
Return the participant name if already stored. If not, pull it from the IRTCParticipant interface.
*************************************************************************************************/
BSTR
CSession::get_ParticipantName( IRTCParticipant* pPart)
{
if (m_sPartInfo.get_Name() != NULL) {
return m_sPartInfo.get_Name();
}
BSTR bstrName = NULL;
// note, need to free memory with SysFreeString()
HRESULT hr = pPart->get_Name(&bstrName);
m_sPartInfo.put_Name(bstrName, NO_ALLOC);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: CSession get_ParticipantName() IRTCParticipant get_Name failed! 0x%lx", hr) );
return NULL;
}
return m_sPartInfo.get_Name();
}
/*************************************************************************************************
get_ParticipantIpAddr()
Return the participant's URI (or IP addr). If not stored locally, pull it from the IRTCParticipant interface
and store it for re-use.
*************************************************************************************************/
BSTR
CSession::get_ParticipantIpAddr( IRTCParticipant* pPart)
{
if (m_sPartInfo.get_Addr() != NULL) {
return m_sPartInfo.get_Addr();
}
// note, need to free memory with SysFreeString()
BSTR bstrAddr = NULL;
HRESULT hr = pPart->get_UserURI( &bstrAddr );
m_sPartInfo.put_Addr(bstrAddr, NO_ALLOC);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: CSession get_ParticipantIpAddr() IRTCParticipant get_UserURI failed! 0x%lx", hr) );
return NULL;
}
return m_sPartInfo.get_Addr();
}
/*************************************************************************************************
get_ParticipantInfo()
return a pointer to the participant info, ensuring it's filled.
*************************************************************************************************/
P_PARTICIPANT_INFO
CSession::get_ParticipantInfo( IRTCParticipant* pPart)
{
if ( get_ParticipantName(pPart) == NULL )
return NULL;
if ( get_ParticipantIpAddr(pPart) == NULL )
return NULL;
return &m_sPartInfo;
}
/************************************************************************************************
Clear()
re-initialize CSession to default state.
*************************************************************************************************/
VOID
CSession::Clear()
{
// release our internal reference of the session
if (m_Valid == TRUE && m_pSess != NULL) {
Hangup();
}
if (m_pSess)
{
m_pSess->Release();
m_pSess = NULL;
}
if (m_bstrRemoteURI != NULL) {
SysFreeString( m_bstrRemoteURI );
}
if (m_bstrLocalPhoneURI) {
SysFreeString( m_bstrLocalPhoneURI );
}
m_sPartInfo.Clear();
m_Init();
} // end Clear()
/*************************************************************************************************
Hangup()
If the session is valid and not NULL, hangup then invalidate this CSession object.
otherwise do nothing and return an error.
*************************************************************************************************/
BOOL
CSession::Hangup(
IN RTC_TERMINATE_REASON enReason
)
{
if (m_Valid == FALSE) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Hangup() called on invalid session!\r\n") );
return FALSE;
}
if (m_pSess != NULL) {
DEBUGMSG( ZONE_STATUS, (L"VoipDemo: CSession::Hangup() successful on session.\r\n ") );
// invalidate this object
m_Valid = FALSE;
// WARNING, will trigger DISCONNECTED event
m_pSess->Terminate( enReason );
} else {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Hangup() called on non-existent session!\r\n ") );
}
return TRUE;
} // end Hangup ()
/************************************************************************************************
Reject()
If the session is in INCOMING state, terminate via a reject message. If not return an error.
************************************************************************************************/
BOOL
CSession::Reject(
VOID
)
{
HRESULT hr;
if (m_Valid == FALSE || m_pSess == NULL) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Reject() called on invalid session!\r\n ") );
return FALSE;
}
if (m_enRSS != RTCSS_INCOMING) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Reject() called on non-incoming session!\r\n ") );
return FALSE;
}
// turn off incoming voice session ring
hr = g_pRTCClient->PlayRing( RTCRT_PHONE, VARIANT_FALSE );
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, ( L"VoipDemo: CSession::Reject() PlayRing failed! 0x%lx\r\n", hr ) );
}
// will initiate DISCONNECTED and succesfuly destroy session
hr = m_pSess->Terminate( RTCTR_REJECT );
return (SUCCEEDED(hr));
} // end CSession::Reject()
/************************************************************************************************
Accept()
If the session is in INCOMING state, answer. If not reject, cleanup, and return an error.
************************************************************************************************/
BOOL
CSession::Accept(
VOID
)
{
HRESULT hr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -