⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 session.cpp

📁 Windows CE .Net 下面 VOIP编程的经典实例。对于初学Windows 平台下VOIP编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -