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

📄 session.cpp

📁 Windows CE .Net 下面 VOIP编程的经典实例。对于初学Windows 平台下VOIP编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if (m_Valid == FALSE || m_pSess == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Accept() called on invalid session!\r\n ") );
		return FALSE;
	}

	if (m_enRSS != RTCSS_INCOMING) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Accept() called on non-incoming session!\r\n ") );
		return FALSE;
	}

	DEBUGMSG( ZONE_STATUS, (L"VoipDemo: Answering incoming session\r\n ") );

	m_Valid = TRUE;
	hr = m_pSess->Answer();
	
	if (FAILED(hr)) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::Accept() Answer failed 0x%lx\r\n ", hr) );
		// It is possible that we've already disconnected thus the session pointer is not valid any more
		if ( m_pSess )
		{
			m_pSess->Terminate( RTCTR_REJECT );
			m_pSess->Release();
			m_pSess = NULL;
		}
		m_Valid = FALSE;
		return FALSE;
	}      			
	
	else {
		return TRUE;
	}
} // end CSession::Accept()

	

/************************************************************************************************
 
   OpenIMSession()
 
	  Set CSession variables for IM sesion predating a call to m_NewSession
 
 ************************************************************************************************/

HRESULT
CSession::OpenIMSession( 			 
						IN P_PARTICIPANT_INFO pPart,
						OUT HANDLE& hSession
						)
{
	HRESULT hr = S_OK;
	hSession = NULL;
	BOOL bSetURI = FALSE;

	// ensure session not already in use
	if (m_Valid == TRUE || m_pSess != NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() this session already open, can't open a new one!\r\n ") );
		return E_FAIL;
	}

	// ensure only 1 IM in a session at a time
	EnterCriticalSection( g_pcsSessionDataLock );	

	if (g_bIMSessionOpen) {
	
		LeaveCriticalSection( g_pcsSessionDataLock );
		
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() an IM session already exists, there is only present support for 1 at a time\r\n ") );
		return E_FAIL;
	}

	g_bIMSessionOpen = TRUE;

	// If an IM session exists, ensure that we're opening a call to the same buddy
	if (g_bVoiceSessionOpen == TRUE && wcscmp(pPart->get_Addr(), g_bstrCurrentlyConnectedURI) != 0) {
		
		LeaveCriticalSection( g_pcsSessionDataLock );
		
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() cannot place a call to a different person than we're already talking to.\r\n") );
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: (more info) URI attempted: %s,  URI currently connected: %s\r\n", pPart->get_Addr(), g_bstrCurrentlyConnectedURI) );
		hr = E_FAIL;
		goto Cleanup;
	}

	// Set the connected URI
	if (g_bstrCurrentlyConnectedURI == NULL)
	{
		if(!NewStrCopy(pPart->get_Addr(), g_bstrCurrentlyConnectedURI)) {
		
			LeaveCriticalSection( g_pcsSessionDataLock );
			
			hr = E_FAIL;
			goto Cleanup;
		}
		bSetURI = TRUE;
	}

	LeaveCriticalSection( g_pcsSessionDataLock );

	// store participant info in session
	if (m_sPartInfo.Copy(pPart) == FALSE) {
		// memory allocation error
		hr = E_FAIL; 
		goto Cleanup;
	}

	// set session type IM
	m_enRST = RTCST_IM;

	// set URI for m_NewSession
	NewStrCopy( pPart->get_Addr(), m_bstrRemoteURI );
	
	if (m_bstrRemoteURI == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenIMSession() Error allocating memory for a new string!\r\n ") );
		hr = E_FAIL;
		goto Cleanup;
	}

	// pass the session handle down to m_NewSession -> Reason blocking call inside
	// RTC will invalidate handle passed as return value
	hr = m_NewSession(hSession);

Cleanup:
	if (FAILED(hr)) {		

		EnterCriticalSection( g_pcsSessionDataLock );
		
		g_bIMSessionOpen = FALSE;

		if (bSetURI) {
			SysFreeString(g_bstrCurrentlyConnectedURI);
			g_bstrCurrentlyConnectedURI = NULL;
		}
		
		LeaveCriticalSection( g_pcsSessionDataLock );
	}

	return hr;
}

/************************************************************************************************
 
   OpenVoiceSession()
 
	Open a voice session to another party.  Depending upon information stored in P_PARTICIPANT_INFO, use a 
 	PC_TO_PC or PC_TO_PHONE connection.  For the PC_TO_PHONE, generate a URI including the local SIP gateway and
 	the phone flag.
	
	Assumption: The user himself is selected in any phone-to-phone calls 

 ************************************************************************************************/

HRESULT
CSession::OpenVoiceSession( 
						   IN P_PARTICIPANT_INFO pPart,
						   IN RTC_SESSION_TYPE enRST,
						   OUT HANDLE& hSession
						   )
{
	HRESULT hr = S_OK;
	m_enRST = enRST;
	hSession = NULL;
	BOOL bSetURI = FALSE;

	// ensure this is the only voice session (even if there's an incoming, yet unaccepted voice session
	EnterCriticalSection( g_pcsSessionDataLock );

	if (g_bVoiceSessionOpen == TRUE) {
	
		LeaveCriticalSection( g_pcsSessionDataLock );
		
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() a voice session already exists, only 1 allowed at any time\r\n ") );
		return E_FAIL;
	}

	g_bVoiceSessionOpen = TRUE;	

	// If an IM session exists, ensure that we're opening a call to the same buddy
	if (g_bIMSessionOpen == TRUE && wcscmp(pPart->get_Addr(), g_bstrCurrentlyConnectedURI) != 0) {
	
		LeaveCriticalSection( g_pcsSessionDataLock );
		
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() cannot place a call to a different person than we're already talking to.\r\n") );
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: (more info) URI attempted: %s,  URI currently connected: %s\r\n", pPart->get_Addr(), g_bstrCurrentlyConnectedURI) );
		hr = E_FAIL;
		goto Cleanup;
	}

	// Set the connected URI
	if (g_bstrCurrentlyConnectedURI == NULL)
	{
		if(!NewStrCopy(pPart->get_Addr(), g_bstrCurrentlyConnectedURI)) {
		
			LeaveCriticalSection( g_pcsSessionDataLock );
			
			hr = E_FAIL;
			goto Cleanup;
		}
		bSetURI = TRUE;
	}

	LeaveCriticalSection( g_pcsSessionDataLock );

	// ensure session not already in use
	if (m_Valid == TRUE || m_pSess != NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() this session already open, can't open a new one!\r\n ") );
		hr = E_FAIL;
		goto Cleanup;	
	}

	// store participant info in session
	if (m_sPartInfo.Copy(pPart) == FALSE) {
		// memory allocation error
		hr = E_FAIL; 
		goto Cleanup;
	}

	// do some checking for the selected type of action
	switch(m_enRST)
	{
	case RTCST_PHONE_TO_PHONE:
#ifdef NO_PHONE_TO_PHONE
		DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Phone to Phone calls presently unsupported, failing\r\n") );
		hr = E_FAIL;
		goto Cleanup;
#endif
		// ensure we have a local phone number to call 
		if (!m_bstrLocalPhoneURI) {
			DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Phone to phone call attempted without local phone number!") );
			hr = E_FAIL;
			goto Cleanup;
		}

		// fall thru to check buddy for phone buddy

	case RTCST_PC_TO_PHONE:
		if (pPart->btBuddyType != BT_PHONE) {
			DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Attempting phone call to non-phone buddy!") );			
			hr = E_FAIL;
			goto Cleanup;
		}
		break;

	case RTCST_PC_TO_PC:
		if (pPart->btBuddyType != BT_COMPUTER) {
			DEBUGMSG( ZONE_ERROR, (L"Voipdemo CSession::OpenVoiceSession() Attempting phone call to non-computer buddy!") );
			hr = E_FAIL;
			goto Cleanup;
		}
		break;

	default: // check for invalid type?
		break;
	}

	// set URI for m_NewSession
	NewStrCopy( pPart->get_Addr(), m_bstrRemoteURI );
	
	if (m_bstrRemoteURI == NULL) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo CSession::OpenVoiceSession() Error allocating memory for a new string!\r\n ") );
		hr = E_FAIL;
		goto Cleanup;
	}
	
	hr = m_NewSession(hSession);

Cleanup:
	if (FAILED(hr)) {

		EnterCriticalSection( g_pcsSessionDataLock );
		
		g_bVoiceSessionOpen = FALSE;

		if (bSetURI) {
			SysFreeString(g_bstrCurrentlyConnectedURI);
			g_bstrCurrentlyConnectedURI = NULL;
		}
		
		LeaveCriticalSection( g_pcsSessionDataLock );
	}

	return hr;
} // end OpenVoiceSession()

/************************************************************************************************
 
	m_NewSession()
 
 		Uses m_bstrRemoteURI as input parameter, assumed to be set by the caller.
 
 		Perform all generic tasks for a standard peer-to-peer session.  Assume that the caller
 		has ensured that it's okay to create this session. 
 
		Some potential issues:
	 		Creating more than one voice session.
 			The IRTCSession in this CSession is already active.
 			Provisioning / Presence info?
 	
	 	m_NewSession will clean up session information after itself.

 *************************************************************************************************/

HRESULT
CSession::m_NewSession(HANDLE& hSess)
{
	HRESULT hr;
	hSess = NULL;
		
	ASSERT (m_Valid == FALSE);

	// Create the RTC Session object to add participants to.
	hr = g_pRTCClient->CreateSession(m_enRST, m_bstrLocalPhoneURI, m_pProfile, m_lSessionFlags, &m_pSess);	

	if (FAILED(hr)) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::m_NewSession() CreateSession failed 0x%lx\r\n ", hr) );
		return E_FAIL;
	}
	
	// store the session with its handle in the container
	HANDLE hRetVal = g_pSessionContainer->Add( m_pSess, this );

	if (hRetVal != m_pSess) {
		DEBUGMSG( ZONE_ERROR, (L"Voipdemo:SessionTo - Error adding CSession object to the container!\r\n") );
		// fatal error, die
		return E_FAIL;
	}

	DEBUGMSG( ZONE_STATUS | ZONE_CALL, (L"VoipDemo: Calling %s @ %s\r\n ", m_sPartInfo.get_Name(), m_bstrRemoteURI) );

	// Signal a call to the specified user.
	// This call will block, ensure any variables needed by RTCEvent are all set before this point
	hr = m_pSess->AddParticipant(m_bstrRemoteURI, m_sPartInfo.get_Name(), NULL); 	// does AddRef(m_pSess)
	
	if (FAILED(hr)) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: AddParticipant(%s) failed 0x%lx\r\n ", m_bstrRemoteURI, hr) );
		
		// Hangup requires a valid session to hangup
		// we're calling our own destructor here
		g_pSessionContainer->Remove(m_pSess);
		return E_FAIL;
	}
		
	DEBUGMSG( ZONE_STATUS | ZONE_CALL, (L"VoipDemo: AddParticipant(%s) succeeded\r\n ", m_bstrRemoteURI) );

	// validate this session object internally
	m_Valid = TRUE;
	
	hSess = m_pSess;

	return S_OK;	
} // end m_NewSession()


BOOL
CSession::SendIM( 
				 P_IM_MSG msg 
				 )
{
	HRESULT hr;
	// send an IM message to participant

	hr = m_pSess->SendMessage( NULL, msg->szMsg, 0 );

	return SUCCEEDED( hr );	
	
} // end SendIM()

/************************************************************************************************

  AddParticipantToSession()
  
	Attempt to add a participant to an existing session.  This will only work for phone2phone 
	sessions at present.  

  NOTE: Need a good way to store the current participants of the session
	
  ************************************************************************************************/

BOOL
CSession::AddParticipantToSession(
						 IN P_PARTICIPANT_INFO pPartInfo, 
						 IN FARPROC fnSWCB
						 )
{
	HRESULT hr;
	VARIANT_BOOL vbAddable = VARIANT_FALSE;

	ASSERT(pPartInfo);

	// the reason for traversing the class to get to the session is so we will get meaningful errors on a debug
	hr = m_pSess->get_CanAddParticipants(&vbAddable);
	
	if ( FAILED(hr) || m_enRST != RTCST_PHONE_TO_PHONE || vbAddable == VARIANT_FALSE) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::AddParticipant() : get_CanAddParticipants failed on session 0x%lx\r\n", m_pSess) );
		return FALSE;
	}

	// Add selected participant to current conference call.  This will initiate a dialing call to 
	// the selected user.
	// Note: blocking call, ensure everything is set up before this point
	DEBUGMSG( ZONE_STATUS | ZONE_CALL, (L"VoipDemo: Adding participant %s to current phone sesion", pPartInfo->get_Addr()) );

	hr = m_pSess->AddParticipant(pPartInfo->get_Name(), pPartInfo->get_Addr(), NULL); 	// does AddRef(m_pSess)

	if (FAILED(hr)) {
		DEBUGMSG( ZONE_ERROR, (L"VoipDemo: CSession::AddParticipant() : AddParticipant failed 0x%lx", hr) );
		return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -